etisserant@400: /*
etisserant@400: Copyright (C): Giuseppe Massimo BERTANI
etisserant@400: gmbertani@users.sourceforge.net
etisserant@400: 
etisserant@400: 
etisserant@400: See COPYING file for copyrights details.
etisserant@400: 
etisserant@400: This library is free software; you can redistribute it and/or
etisserant@400: modify it under the terms of the GNU Lesser General Public
etisserant@400: License as published by the Free Software Foundation; either
etisserant@400: version 2.1 of the License, or (at your option) any later version.
etisserant@400: 
etisserant@400: This library is distributed in the hope that it will be useful,
etisserant@400: but WITHOUT ANY WARRANTY; without even the implied warranty of
etisserant@400: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
etisserant@400: Lesser General Public License for more details.
etisserant@400: 
etisserant@400: You should have received a copy of the GNU Lesser General Public
etisserant@400: License along with this library; if not, write to the Free Software
etisserant@400: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
etisserant@400: */
etisserant@400: 
etisserant@400: /**
etisserant@400:  * @file slave.c
etisserant@400:  * @author GMB
etisserant@400:  * @date 17/1/08
etisserant@400:  *
etisserant@400:  * This file is part of SillySlave demo for CANfestival
etisserant@400:  * open source CANopen stack.
etisserant@400:  */ 
etisserant@400: 
etisserant@400: #include "SillySlave.h"
etisserant@400: #include "slave.h"
etisserant@400: #include "main.h"
etisserant@400: 
etisserant@400: 
etisserant@400: static UNS8 slaveNode = 0;  
etisserant@400: 
etisserant@400: void InitNode(CO_Data* d, UNS32 id)
etisserant@400: {
etisserant@400:     /* Defining the node Id */
etisserant@400:     setNodeId(&SillySlave_Data, slaveNode);
etisserant@400:     /* CAN init */
etisserant@400:     setState(&SillySlave_Data, Initialisation);
etisserant@400: }
etisserant@400: 
greg@454: void Exit(CO_Data* d, UNS32 id)
greg@454: {
greg@454: 	/* Stop slave */
greg@454:     setState(&SillySlave_Data, Stopped);
greg@454: }
greg@454: 
etisserant@400: INTEGER8 InitCANdevice( UNS8 bus, UNS32 baudrate, UNS8 node )
etisserant@400: { 
etisserant@400: char busName[2];
etisserant@400: char baudRate[7];
etisserant@400: s_BOARD board;
etisserant@400: 
etisserant@400:     sprintf(busName, "%u", bus);
Christian@642:     sprintf(baudRate, "%uK", baudrate);
etisserant@400:     board.busname = busName;
etisserant@400:     board.baudrate = baudRate;
etisserant@400: 
etisserant@400:     slaveNode = node;
etisserant@400: 
etisserant@400:     SillySlave_Data.heartbeatError = SillySlave_heartbeatError;
etisserant@400:     SillySlave_Data.initialisation = SillySlave_initialisation;
etisserant@400:     SillySlave_Data.preOperational = SillySlave_preOperational;
etisserant@400:     SillySlave_Data.operational = SillySlave_operational;
etisserant@400:     SillySlave_Data.stopped = SillySlave_stopped;
etisserant@400:     SillySlave_Data.post_sync = SillySlave_post_sync;
etisserant@400:     SillySlave_Data.post_TPDO = SillySlave_post_TPDO;
etisserant@400:     SillySlave_Data.storeODSubIndex = SillySlave_storeODSubIndex;
etisserant@400:     SillySlave_Data.post_emcy = SillySlave_post_emcy;
etisserant@400:     
Christian@642: 	TimerInit();
Christian@642: 
etisserant@400:     if(!canOpen(&board, &SillySlave_Data))
etisserant@400:     {
etisserant@400:         printf("\n\aInitCANdevice() CAN bus %s opening error, baudrate=%s\n",board.busname, board.baudrate);
etisserant@400:         return -1;
etisserant@400:     }
etisserant@400: 
etisserant@400: 
etisserant@400:     printf("\nInitCANdevice(), canOpen() OK, starting timer loop...\n");
etisserant@400: 
Christian@642: 	/* Start timer thread */
etisserant@400:     StartTimerLoop(&InitNode); 
etisserant@400:     
etisserant@400: 	/* wait Ctrl-C */
etisserant@400: 	pause();
etisserant@400: 	printf("\nFinishing.\n");
etisserant@400: 	
etisserant@400: 	/* Stop timer thread */
greg@454: 	StopTimerLoop(&Exit);
etisserant@400:     return 0;
etisserant@400: }
etisserant@400: 
etisserant@400: void SillySlave_heartbeatError(CO_Data* d, UNS8 heartbeatID)
etisserant@400: {
etisserant@400:     printf("SillySlave_heartbeatError %d\n", heartbeatID);
etisserant@400: }
etisserant@400: 
etisserant@400: void SillySlave_initialisation(CO_Data* d )
etisserant@400: {
etisserant@400:     UNS32 PDO1_COBID = 0x0180 + NODE_MASTER; 
etisserant@400:     UNS8 size = sizeof(PDO1_COBID); 
etisserant@400:     
etisserant@400:     printf("SillySlave_initialisation\n");
etisserant@400: 
etisserant@400:     /* sets TXPDO1 COB-ID to match master node ID */
etisserant@400:     writeLocalDict( 
etisserant@400:             &SillySlave_Data,       /*CO_Data* d*/
etisserant@400:             0x1800,                 /*UNS16 index*/
etisserant@400:             0x01,                   /*UNS8 subind*/ 
etisserant@400:             &PDO1_COBID,            /*void * pSourceData,*/ 
etisserant@400:             &size,                  /* UNS8 * pExpectedSize*/
etisserant@400:             RW);                    /* UNS8 checkAccess */
etisserant@400:             
etisserant@400:     /* value sent to master at each SYNC received */
etisserant@400:     LifeSignal = 0;
etisserant@400: }
etisserant@400: 
etisserant@400: void SillySlave_preOperational(CO_Data* d)
etisserant@400: {
etisserant@400:     printf("SillySlave_preOperational\n");
etisserant@400: }
etisserant@400: 
etisserant@400: void SillySlave_operational(CO_Data* d)
etisserant@400: {
etisserant@400:     printf("SillySlave_operational\n");
etisserant@400: }
etisserant@400: 
etisserant@400: void SillySlave_stopped(CO_Data* d)
etisserant@400: {
etisserant@400:     printf("SillySlave_stopped\n");
etisserant@400: }
etisserant@400: 
etisserant@400: void SillySlave_post_sync(CO_Data* d)
etisserant@400: {
etisserant@400:     printf("SillySlave_post_sync: \n");
etisserant@400:     LifeSignal++;
etisserant@400: }
etisserant@400: 
etisserant@400: void SillySlave_post_TPDO(CO_Data* d)
etisserant@400: {
etisserant@400:     printf("SillySlave_post_TPDO: \n");
etisserant@400:     printf("LifeSignal = %u\n", LifeSignal);    
etisserant@400: }
etisserant@400: 
etisserant@400: void SillySlave_storeODSubIndex(CO_Data* d, UNS16 wIndex, UNS8 bSubindex)
etisserant@400: {
etisserant@400:     /*TODO : 
etisserant@400:      * - call getODEntry for index and subindex, 
etisserant@400:      * - save content to file, database, flash, nvram, ...
etisserant@400:      * 
etisserant@400:      * To ease flash organisation, index of variable to store
etisserant@400:      * can be established by scanning d->objdict[d->ObjdictSize]
etisserant@400:      * for variables to store.
etisserant@400:      * 
etisserant@400:      * */
etisserant@400:     printf("SillySlave_storeODSubIndex : %4.4x %2.2xh\n", wIndex,  bSubindex);
etisserant@400: }
etisserant@400: 
etisserant@400: void SillySlave_post_emcy(CO_Data* d, UNS8 nodeID, UNS16 errCode, UNS8 errReg)
etisserant@400: {
etisserant@400:     printf("Slave received EMCY message. Node: %2.2xh  ErrorCode: %4.4x  ErrorRegister: %2.2xh\n", nodeID, errCode, errReg);
etisserant@400: }
etisserant@400: