/* * CANopen main program file. * * This file is a template for other microcontrollers. * * @file main_generic.c * @author Janez Paternoster * @copyright 2004 - 2015 Janez Paternoster * * This file is part of CANopenNode, an opensource CANopen Stack. * Project home page is . * For more information on CANopen see . * * CANopenNode is free and open source software: you can redistribute * it and/or modify it under the terms of the GNU General Public License * as published by the Free Software Foundation, either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Following clarification and special exception to the GNU General Public * License is included to the distribution terms of CANopenNode: * * Linking this library statically or dynamically with other modules is * making a combined work based on this library. Thus, the terms and * conditions of the GNU General Public License cover the whole combination. * * As a special exception, the copyright holders of this library give * you permission to link this library with independent modules to * produce an executable, regardless of the license terms of these * independent modules, and to copy and distribute the resulting * executable under terms of your choice, provided that you also meet, * for each linked independent module, the terms and conditions of the * license of that module. An independent module is a module which is * not derived from or based on this library. If you modify this * library, you may extend this exception to your version of the * library, but you are not obliged to do so. If you do not wish * to do so, delete this exception statement from your version. */ #include "CANopen.h" #define TMR_TASK_INTERVAL (1000) /* Interval of tmrTask thread in microseconds */ #define INCREMENT_1MS(var) (var++) /* Increment 1ms variable in tmrTask */ /** * User-defined CAN base structure, passed as argument to CO_init. */ struct CANbase { uintptr_t baseAddress; /**< Base address of the CAN module */ }; /* Global variables and objects */ volatile uint16_t CO_timer1ms = 0U; /* variable increments each millisecond */ /* main ***********************************************************************/ int main (void){ CO_NMT_reset_cmd_t reset = CO_RESET_NOT; /* Configure microcontroller. */ /* initialize EEPROM */ /* increase variable each startup. Variable is stored in EEPROM. */ OD_powerOnCounter++; while(reset != CO_RESET_APP){ /* CANopen communication reset - initialize CANopen objects *******************/ CO_ReturnError_t err; uint16_t timer1msPrevious; /* disable CAN and CAN interrupts */ struct CANbase canBase = { .baseAddress = 0u, /* CAN module address */ }; /* initialize CANopen */ err = CO_init(&canBase, 10/* NodeID */, 125 /* bit rate */); if(err != CO_ERROR_NO){ while(1); /* CO_errorReport(CO->em, CO_EM_MEMORY_ALLOCATION_ERROR, CO_EMC_SOFTWARE_INTERNAL, err); */ } /* Configure Timer interrupt function for execution every 1 millisecond */ /* Configure CAN transmit and receive interrupt */ /* start CAN */ CO_CANsetNormalMode(CO->CANmodule[0]); reset = CO_RESET_NOT; timer1msPrevious = CO_timer1ms; while(reset == CO_RESET_NOT){ /* loop for normal program execution ******************************************/ uint16_t timer1msCopy, timer1msDiff; timer1msCopy = CO_timer1ms; timer1msDiff = timer1msCopy - timer1msPrevious; timer1msPrevious = timer1msCopy; /* CANopen process */ reset = CO_process(CO, timer1msDiff, NULL); /* Nonblocking application code may go here. */ /* Process EEPROM */ } } /* program exit ***************************************************************/ /* stop threads */ /* delete objects from memory */ CO_delete((void*) 0/* CAN module address */); /* reset */ return 0; } /* timer thread executes in constant intervals ********************************/ static void tmrTask_thread(void){ for(;;) { /* sleep for interval */ INCREMENT_1MS(CO_timer1ms); if(CO->CANmodule[0]->CANnormal) { bool_t syncWas; /* Process Sync and read inputs */ syncWas = CO_process_SYNC_RPDO(CO, TMR_TASK_INTERVAL); /* Further I/O or nonblocking application code may go here. */ /* Write outputs */ CO_process_TPDO(CO, syncWas, TMR_TASK_INTERVAL); /* verify timer overflow */ if(0) { CO_errorReport(CO->em, CO_EM_ISR_TIMER_OVERFLOW, CO_EMC_SOFTWARE_INTERNAL, 0U); } } } } /* CAN interrupt function *****************************************************/ void /* interrupt */ CO_CAN1InterruptHandler(void){ CO_CANinterrupt(CO->CANmodule[0]); /* clear interrupt flag */ }