leonid@255: /* leonid@255: This file is part of CanFestival, a library implementing CanOpen Stack. leonid@255: leonid@255: CanFestival Copyright (C): Edouard TISSERANT and Francis DUPIN leonid@255: CanFestival Win32 port Copyright (C) 2007 Leonid Tochinski, ChattenAssociates, Inc. leonid@255: leonid@255: See COPYING file for copyrights details. leonid@255: leonid@255: This library is free software; you can redistribute it and/or leonid@255: modify it under the terms of the GNU Lesser General Public leonid@255: License as published by the Free Software Foundation; either leonid@255: version 2.1 of the License, or (at your option) any later version. leonid@255: leonid@255: This library is distributed in the hope that it will be useful, leonid@255: but WITHOUT ANY WARRANTY; without even the implied warranty of leonid@255: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU leonid@255: Lesser General Public License for more details. leonid@255: leonid@255: You should have received a copy of the GNU Lesser General Public leonid@255: License along with this library; if not, write to the Free Software leonid@255: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA leonid@255: */ leonid@255: etisserant@145: /************************************************************************** etisserant@145: CanFestival3 win32 port example etisserant@145: etisserant@145: This sample demonstrates CanFestival usage with Win32 etisserant@145: etisserant@145: Program implements master node. It starts CANOpen slave node, modifies OD, etisserant@145: performs SDO reads and prints some slave node information. etisserant@145: etisserant@145: Usage: etisserant@145: leonid@256: win32test [can driver dll filename [baud rate]] leonid@256: leonid@256: where node_id is node_id in decimal format leonid@256: leonid@256: If driver is not specified, CAN-uVCCM.dll will be used by default. leonid@256: If baudrate is not specified, 125K will be used by default. leonid@256: You should have CanFestival-3.dll can driver dll in the search path to run this sample. etisserant@145: etisserant@145: Sample can work on other platdorms as well. etisserant@145: ***************************************************************************/ etisserant@145: etisserant@145: #include etisserant@145: #include etisserant@145: #include "win32test.h" etisserant@145: #include "canfestival.h" etisserant@145: etisserant@145: #ifdef WIN32 etisserant@145: #define sleep_proc(ms) Sleep(ms) etisserant@145: #define uptime_ms_proc() GetTickCount() etisserant@145: #else etisserant@145: #include etisserant@145: #define sleep_proc(ms) etisserant@145: #define uptime_ms_proc (1000*(time()%86400)) // TOD etisserant@145: #endif etisserant@145: etisserant@145: UNS8 GetChangeStateResults(UNS8 node_id, UNS8 expected_state, unsigned long timeout_ms) etisserant@145: { etisserant@145: unsigned long start_time = 0; etisserant@145: etisserant@145: // reset nodes state etisserant@145: win32test_Data.NMTable[node_id] = Unknown_state; etisserant@145: etisserant@145: // request node state etisserant@145: masterRequestNodeState(&win32test_Data, node_id); etisserant@145: etisserant@145: start_time = uptime_ms_proc(); etisserant@145: while(uptime_ms_proc() - start_time < timeout_ms) etisserant@145: { etisserant@145: if (getNodeState(&win32test_Data, node_id) == expected_state) etisserant@145: return 0; etisserant@145: sleep_proc(1); etisserant@145: } etisserant@145: return 0xFF; etisserant@145: } etisserant@145: hacking@701: UNS8 ReadSDO(UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 dataType, void* data, UNS32* size) etisserant@145: { etisserant@145: UNS32 abortCode = 0; etisserant@145: UNS8 res = SDO_UPLOAD_IN_PROGRESS; etisserant@145: // Read SDO hacking@701: UNS8 err = readNetworkDict (&win32test_Data, nodeId, index, subIndex, dataType, 0); etisserant@145: if (err) etisserant@145: return 0xFF; etisserant@145: for(;;) etisserant@145: { etisserant@145: res = getReadResultNetworkDict (&win32test_Data, nodeId, data, size, &abortCode); etisserant@145: if (res != SDO_UPLOAD_IN_PROGRESS) etisserant@145: break; etisserant@145: sleep_proc(1); etisserant@145: continue; etisserant@145: } etisserant@145: closeSDOtransfer(&win32test_Data, nodeId, SDO_CLIENT); etisserant@145: if (res == SDO_FINISHED) etisserant@145: return 0; etisserant@145: return 0xFF; etisserant@145: } etisserant@145: etisserant@145: int main(int argc, char *argv[]) etisserant@145: { etisserant@145: UNS8 node_id = 0; etisserant@145: s_BOARD MasterBoard = {"1", "125K"}; etisserant@145: char* dll_file_name; etisserant@145: etisserant@145: /* process command line arguments */ etisserant@145: if (argc < 2) etisserant@145: { hacking@727: printf("USAGE: win32test [can driver dll filename [baud rate[bus name]]]\n"); etisserant@145: return 1; etisserant@145: } etisserant@145: etisserant@145: node_id = atoi(argv[1]); etisserant@145: if (node_id < 2 || node_id > 127) etisserant@145: { etisserant@145: printf("ERROR: node_id shoule be >=2 and <= 127\n"); etisserant@145: return 1; etisserant@145: } etisserant@145: leonid@256: if (argc > 2) leonid@256: dll_file_name = argv[2]; leonid@256: else leonid@256: dll_file_name = "can_uvccm_win32.dll"; leonid@256: leonid@256: if (argc > 3) leonid@256: MasterBoard.baudrate = argv[3]; etisserant@145: hacking@727: if (argc > 4) hacking@727: MasterBoard.busname = argv[4]; hacking@727: etisserant@145: // load can driver etisserant@145: if (!LoadCanDriver(dll_file_name)) etisserant@145: { etisserant@145: printf("ERROR: could not load diver %s\n", dll_file_name); etisserant@145: return 1; etisserant@145: } etisserant@145: Christian@653: TimerInit(); Christian@653: etisserant@149: if (canOpen(&MasterBoard,&win32test_Data)) etisserant@145: { etisserant@145: /* Defining the node Id */ etisserant@145: setNodeId(&win32test_Data, 0x01); etisserant@145: etisserant@145: /* init */ etisserant@145: setState(&win32test_Data, Initialisation); etisserant@145: etisserant@145: /****************************** START *******************************/ etisserant@145: /* Put the master in operational mode */ etisserant@145: setState(&win32test_Data, Operational); etisserant@145: etisserant@145: /* Ask slave node to go in operational mode */ etisserant@145: masterSendNMTstateChange (&win32test_Data, 0, NMT_Start_Node); etisserant@145: etisserant@145: printf("\nStarting node %d (%xh) ...\n",(int)node_id,(int)node_id); etisserant@145: etisserant@145: /* wait untill mode will switch to operational state*/ etisserant@145: if (GetChangeStateResults(node_id, Operational, 3000) != 0xFF) etisserant@145: { etisserant@145: /* modify Client SDO 1 Parameter */ etisserant@145: UNS32 COB_ID_Client_to_Server_Transmit_SDO = 0x600 + node_id; etisserant@145: UNS32 COB_ID_Server_to_Client_Receive_SDO = 0x580 + node_id; hacking@733: UNS8 Node_ID_of_the_SDO_Server = node_id; hacking@733: UNS32 ExpectedSize = sizeof(UNS32); hacking@733: UNS32 ExpectedSizeNodeId = sizeof (UNS8); etisserant@145: etisserant@175: if (OD_SUCCESSFUL == writeLocalDict(&win32test_Data, 0x1280, 1, &COB_ID_Client_to_Server_Transmit_SDO, &ExpectedSize, RW) etisserant@175: && OD_SUCCESSFUL == writeLocalDict(&win32test_Data, 0x1280, 2, &COB_ID_Server_to_Client_Receive_SDO, &ExpectedSize, RW) hacking@733: && OD_SUCCESSFUL == writeLocalDict(&win32test_Data, 0x1280, 3, &Node_ID_of_the_SDO_Server, &ExpectedSizeNodeId, RW)) etisserant@145: { etisserant@145: UNS32 dev_type = 0; etisserant@145: char device_name[64]=""; etisserant@145: char hw_ver[64]=""; etisserant@145: char sw_ver[64]=""; etisserant@145: UNS32 vendor_id = 0; etisserant@145: UNS32 prod_code = 0; etisserant@145: UNS32 ser_num = 0; hacking@701: UNS32 size; etisserant@145: UNS8 res; etisserant@145: etisserant@145: printf("\nnode_id: %d (%xh) info\n",(int)node_id,(int)node_id); etisserant@145: printf("********************************************\n"); etisserant@145: etisserant@145: size = sizeof (dev_type); etisserant@145: res = ReadSDO(node_id, 0x1000, 0, uint32, &dev_type, &size); etisserant@145: printf("device type: %d\n",dev_type & 0xFFFF); etisserant@145: etisserant@145: size = sizeof (device_name); etisserant@145: res = ReadSDO(node_id, 0x1008, 0, visible_string, device_name, &size); etisserant@145: printf("device name: %s\n",device_name); etisserant@145: etisserant@145: size = sizeof (hw_ver); etisserant@145: res = ReadSDO(node_id, 0x1009, 0, visible_string, hw_ver, &size); etisserant@145: printf("HW version: %s\n",hw_ver); etisserant@145: etisserant@145: size = sizeof (sw_ver); etisserant@145: res = ReadSDO(node_id, 0x100A, 0, visible_string, sw_ver, &size); etisserant@145: printf("SW version: %s\n",sw_ver); etisserant@145: etisserant@145: size = sizeof (vendor_id); etisserant@145: res = ReadSDO(node_id, 0x1018, 1, uint32, &vendor_id, &size); etisserant@145: printf("vendor id: %d\n",vendor_id); etisserant@145: etisserant@145: size = sizeof (prod_code); etisserant@145: res = ReadSDO(node_id, 0x1018, 2, uint32, &prod_code, &size); etisserant@145: printf("product code: %d\n",prod_code); etisserant@145: etisserant@145: size = sizeof (ser_num); etisserant@145: res = ReadSDO(node_id, 0x1018, 4, uint32, &ser_num, &size); etisserant@145: printf("serial number: %d\n",ser_num); etisserant@145: etisserant@145: printf("********************************************\n"); etisserant@145: } etisserant@145: else etisserant@145: { etisserant@145: printf("ERROR: Object dictionary access failed\n"); etisserant@145: } etisserant@145: } etisserant@145: else etisserant@145: { etisserant@145: printf("ERROR: node_id %d (%xh) is not responding\n",(int)node_id,(int)node_id); etisserant@145: } etisserant@145: etisserant@145: masterSendNMTstateChange (&win32test_Data, 0x02, NMT_Stop_Node); etisserant@145: etisserant@145: setState(&win32test_Data, Stopped); etisserant@145: etisserant@149: canClose(&win32test_Data); etisserant@145: } etisserant@145: return 0; etisserant@145: } etisserant@145: etisserant@145: