1 /*
2 * CANopen main program file.
3 *
4 * This file is a template for other microcontrollers.
5 *
6 * @file main_generic.c
7 * @author Janez Paternoster
8 * @copyright 2004 - 2020 Janez Paternoster
9 *
10 * This file is part of CANopenNode, an opensource CANopen Stack.
11 * Project home page is <https://github.com/CANopenNode/CANopenNode>.
12 * For more information on CANopen see <http://www.can-cia.org/>.
13 *
14 * Licensed under the Apache License, Version 2.0 (the "License");
15 * you may not use this file except in compliance with the License.
16 * You may obtain a copy of the License at
17 *
18 * http://www.apache.org/licenses/LICENSE-2.0
19 *
20 * Unless required by applicable law or agreed to in writing, software
21 * distributed under the License is distributed on an "AS IS" BASIS,
22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23 * See the License for the specific language governing permissions and
24 * limitations under the License.
25 */
26
27
28 #include "CANopen.h"
29
30
31 #define TMR_TASK_INTERVAL (1000) /* Interval of tmrTask thread in microseconds */
32 #define INCREMENT_1MS(var) (var++) /* Increment 1ms variable in tmrTask */
33
34 /**
35 * User-defined CAN base structure, passed as argument to CO_init.
36 */
37 struct CANbase {
38 uintptr_t baseAddress; /**< Base address of the CAN module */
39 };
40
41 /* Global variables and objects */
42 volatile uint16_t CO_timer1ms = 0U; /* variable increments each millisecond */
43
44
45 /* main ***********************************************************************/
main(void)46 int main (void){
47 CO_NMT_reset_cmd_t reset = CO_RESET_NOT;
48
49 /* Configure microcontroller. */
50
51
52 /* initialize EEPROM */
53
54
55 /* increase variable each startup. Variable is stored in EEPROM. */
56 OD_powerOnCounter++;
57
58
59 while(reset != CO_RESET_APP){
60 /* CANopen communication reset - initialize CANopen objects *******************/
61 CO_ReturnError_t err;
62 uint16_t timer1msPrevious;
63
64 /* disable CAN and CAN interrupts */
65 struct CANbase canBase = {
66 .baseAddress = 0u, /* CAN module address */
67 };
68
69 /* initialize CANopen */
70 err = CO_init(&canBase, 10/* NodeID */, 125 /* bit rate */);
71 if(err != CO_ERROR_NO){
72 while(1);
73 /* CO_errorReport(CO->em, CO_EM_MEMORY_ALLOCATION_ERROR, CO_EMC_SOFTWARE_INTERNAL, err); */
74 }
75
76
77 /* Configure Timer interrupt function for execution every 1 millisecond */
78
79
80 /* Configure CAN transmit and receive interrupt */
81
82
83 /* start CAN */
84 CO_CANsetNormalMode(CO->CANmodule[0]);
85
86 reset = CO_RESET_NOT;
87 timer1msPrevious = CO_timer1ms;
88
89 while(reset == CO_RESET_NOT){
90 /* loop for normal program execution ******************************************/
91 uint16_t timer1msCopy, timer1msDiff;
92
93 timer1msCopy = CO_timer1ms;
94 timer1msDiff = timer1msCopy - timer1msPrevious;
95 timer1msPrevious = timer1msCopy;
96
97
98 /* CANopen process */
99 reset = CO_process(CO, timer1msDiff, NULL);
100
101 /* Nonblocking application code may go here. */
102
103 /* Process EEPROM */
104 }
105 }
106
107
108 /* program exit ***************************************************************/
109 /* stop threads */
110
111
112 /* delete objects from memory */
113 CO_delete((void*) 0/* CAN module address */);
114
115
116 /* reset */
117 return 0;
118 }
119
120
121 /* timer thread executes in constant intervals ********************************/
tmrTask_thread(void)122 static void tmrTask_thread(void){
123
124 for(;;) {
125
126 /* sleep for interval */
127
128 INCREMENT_1MS(CO_timer1ms);
129
130 if(CO->CANmodule[0]->CANnormal) {
131 bool_t syncWas;
132
133 /* Process Sync */
134 syncWas = CO_process_SYNC(CO, TMR_TASK_INTERVAL);
135
136 /* Read inputs */
137 CO_process_RPDO(CO, syncWas);
138
139 /* Further I/O or nonblocking application code may go here. */
140
141 /* Write outputs */
142 CO_process_TPDO(CO, syncWas, TMR_TASK_INTERVAL);
143
144 /* verify timer overflow */
145 if(0) {
146 CO_errorReport(CO->em, CO_EM_ISR_TIMER_OVERFLOW, CO_EMC_SOFTWARE_INTERNAL, 0U);
147 }
148 }
149 }
150 }
151
152
153 /* CAN interrupt function *****************************************************/
CO_CAN1InterruptHandler(void)154 void /* interrupt */ CO_CAN1InterruptHandler(void){
155 CO_CANinterrupt(CO->CANmodule[0]);
156
157
158 /* clear interrupt flag */
159 }
160