/* * CANopen main program file. * * This file is a template for other microcontrollers. * * @file main_generic.c * @author Janez Paternoster * @copyright 2004 - 2020 Janez Paternoster * * This file is part of CANopenNode, an opensource CANopen Stack. * Project home page is . * For more information on CANopen see . * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "CANopen.h" #define TMR_TASK_INTERVAL (1000) /* Interval of tmrTask thread in microseconds */ #define INCREMENT_1MS(var) (var++) /* Increment 1ms variable in tmrTask */ /* Global variables and objects */ volatile uint16_t CO_timer1ms = 0U; /* variable increments each millisecond */ /* main ***********************************************************************/ int main (void){ CO_ReturnError_t err; CO_NMT_reset_cmd_t reset = CO_RESET_NOT; /* Configure microcontroller. */ /* Allocate memory */ err = CO_new(); if (err != CO_ERROR_NO) { while(1); } /* initialize EEPROM */ /* increase variable each startup. Variable is stored in EEPROM. */ OD_powerOnCounter++; while(reset != CO_RESET_APP){ /* CANopen communication reset - initialize CANopen objects *******************/ uint16_t timer1msPrevious; /* disable CAN and CAN interrupts */ /* initialize CANopen */ err = CO_CANinit(NULL /* CAN module address */, 125 /* bit rate */); if (err == CO_ERROR_NO) { err = CO_CANopenInit(10 /* NodeID */); } 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, (uint32_t)timer1msDiff*1000, 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 ********************************/ void tmrTask_thread(void){ for(;;) { /* sleep for interval */ INCREMENT_1MS(CO_timer1ms); if(CO->CANmodule[0]->CANnormal) { bool_t syncWas; /* Process Sync */ syncWas = CO_process_SYNC(CO, TMR_TASK_INTERVAL, NULL); /* Read inputs */ CO_process_RPDO(CO, syncWas); /* Further I/O or nonblocking application code may go here. */ /* Write outputs */ CO_process_TPDO(CO, syncWas, TMR_TASK_INTERVAL, NULL); /* verify timer overflow */ if(0) { CO_errorReport(CO->em, CO_EM_ISR_TIMER_OVERFLOW, CO_EMC_SOFTWARE_INTERNAL, 0U); } } } } /* CAN interrupt function executes on received CAN message ********************/ void /* interrupt */ CO_CAN1InterruptHandler(void){ /* clear interrupt flag */ }