1 /* |
|
2 This file is part of CanFestival, a library implementing CanOpen Stack. |
|
3 |
|
4 Copyright (C): Edouard TISSERANT and Francis DUPIN |
|
5 AVR Port: Andreas GLAUSER and Peter CHRISTEN |
|
6 |
|
7 See COPYING file for copyrights details. |
|
8 |
|
9 This library is free software; you can redistribute it and/or |
|
10 modify it under the terms of the GNU Lesser General Public |
|
11 License as published by the Free Software Foundation; either |
|
12 version 2.1 of the License, or (at your option) any later version. |
|
13 |
|
14 This library is distributed in the hope that it will be useful, |
|
15 but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
17 Lesser General Public License for more details. |
|
18 |
|
19 You should have received a copy of the GNU Lesser General Public |
|
20 License along with this library; if not, write to the Free Software |
|
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
22 */ |
|
23 /****************************************************************************** |
|
24 Project description: |
|
25 Test projekt for a DS 401 slave, running on Atmel's STK500 with AT90CAN128 |
|
26 Short description: |
|
27 PORTA: Inputs (Keys, low active) |
|
28 PORTB: Outputs (LEDs, low active) |
|
29 PORTC: Node ID (1 BCD switch) |
|
30 |
|
31 ******************************************************************************/ |
|
32 #include "hardware.h" |
|
33 #include "canfestival.h" |
|
34 #include "can_AVR.h" |
|
35 #include "objdict.h" |
|
36 |
|
37 unsigned char timer_interrupt = 0; // Set if timer interrupt eclapsed |
|
38 unsigned char inputs; |
|
39 |
|
40 // CAN |
|
41 unsigned char nodeID; |
|
42 static Message m = Message_Initializer; // contain a CAN message |
|
43 |
|
44 static unsigned char old_input_value; // Inputs, to check if a input has changed |
|
45 |
|
46 void sys_init(); |
|
47 |
|
48 // macros to handle the schedule timer |
|
49 #define sys_timer timer_interrupt |
|
50 #define reset_sys_timer() timer_interrupt = 0 |
|
51 #define CYCLE_TIME 1000 // Sample Timebase [us] |
|
52 |
|
53 int main(void) |
|
54 { |
|
55 sys_init(); // Initialize system |
|
56 canInit(CAN_BAUDRATE); // Initialize the CANopen bus |
|
57 initTimer(); // Start timer for the CANopen stack |
|
58 nodeID = read_bcd(); // Read node ID first |
|
59 setNodeId (&ObjDict_Data, nodeID); |
|
60 setState(&ObjDict_Data, Initialisation); // Init the state |
|
61 PDOInit(&ObjDict_Data); |
|
62 |
|
63 // Examples for callbacks |
|
64 // RegisterSetODentryCallBack(d, 0x1005, 0, &OnCOB_ID_SyncUpdate); |
|
65 // errorCode = setODentry(d, d->transfers[line].index, d->transfers[line].subIndex, |
|
66 // (void *) d->transfers[line].data, &size, 1); |
|
67 |
|
68 for(;;) // forever loop |
|
69 { |
|
70 if (sys_timer) // Cycle timer, invoke action on every time slice |
|
71 { |
|
72 reset_sys_timer(); // Reset timer |
|
73 |
|
74 // Read the input states from the ports |
|
75 Read_Inputs_8_Bit[0] = get_inputs(); |
|
76 // Send the new input state if there was a change |
|
77 if (old_input_value != Read_Inputs_8_Bit[0]) |
|
78 { |
|
79 old_input_value = Read_Inputs_8_Bit[0]; |
|
80 if (getState(&ObjDict_Data) == Operational) |
|
81 sendPDOevent(&ObjDict_Data); |
|
82 } |
|
83 set_outputs(Write_Outputs_8_Bit[0]); |
|
84 |
|
85 // Check if CAN address has been changed |
|
86 if(!( nodeID == read_bcd())) |
|
87 { |
|
88 nodeID = read_bcd(); // Save the new CAN adress |
|
89 setState(&ObjDict_Data, Stopped); // Stop the node, to change the node ID |
|
90 setNodeId(&ObjDict_Data, nodeID); // Now the CAN adress is changed |
|
91 setState(&ObjDict_Data, Pre_operational); // Set to Pre_operational, master must boot it again |
|
92 } |
|
93 } |
|
94 // Handle all MOB's at once, if a message was received pass it to the CANstack |
|
95 if (canReceive(&m)) // a message reveived |
|
96 canDispatch(&ObjDict_Data, &m); // process it |
|
97 else |
|
98 { |
|
99 // Enter sleep mode |
|
100 #ifdef WD_SLEEP // Watchdog and Sleep |
|
101 wdt_reset(); |
|
102 sleep_enable(); |
|
103 sleep_cpu(); |
|
104 #endif // Watchdog and Sleep |
|
105 } |
|
106 } |
|
107 } |
|
108 |
|
109 void sys_init() |
|
110 /****************************************************************************** |
|
111 Initialize the relays, the main states and the modbus protocol stack. |
|
112 INPUT LOCK_STATES *lock_states |
|
113 OUTPUT void |
|
114 ******************************************************************************/ |
|
115 { |
|
116 OSCCAL = 0x43; |
|
117 |
|
118 PORTA = 0xFF; // Inputs (Keys, low active) with pullup |
|
119 DDRA = 0x00; // |
|
120 PORTB = 0xFF; // Outputs (LEDs, low active) all 1 |
|
121 DDRB = 0xFF; // |
|
122 PORTC = 0xFF; // 1 BCD switch with pullup |
|
123 DDRC = 0x00; // |
|
124 PORTD = 0x2C; // 2xCOM, unused, CAN, unused |
|
125 DDRD = 0x2A; // All init 0 or without pullup |
|
126 PORTE = 0x00; // Output |
|
127 DDRE = 0x3C; // 2x not used, 2x not used |
|
128 PORTF = 0x00; // Not used |
|
129 DDRF = 0xFF; // All output |
|
130 PORTG = 0x00; // Not used |
|
131 DDRG = 0x1F; // Output for debug (only 5 pins) |
|
132 |
|
133 // Set timer 0 for main schedule time |
|
134 TCCR0A |= 1 << WGM01 | 1 << CS01 | 1 << CS00;// Timer 0 CTC , Timer 0 mit CK/64 starten |
|
135 TIMSK0 = 1 << OCIE0A; // Timer Interrupts: Timer 0 Compare |
|
136 OCR0A = (unsigned char)(F_CPU / 64 * CYCLE_TIME/1000000 - 1); // Reloadvalue for timer 0 |
|
137 #ifdef WD_SLEEP // Watchdog and Sleep |
|
138 wdt_reset(); |
|
139 wdt_enable(WDTO_15MS); // Watchdogtimer start with 16 ms timeout |
|
140 #endif // Watchdog and Sleep |
|
141 sei(); // Enable Interrupts |
|
142 } |
|
143 |
|
144 |
|
145 #ifdef __IAR_SYSTEMS_ICC__ |
|
146 #pragma type_attribute = __interrupt |
|
147 #pragma vector=TIMER0_COMP_vect |
|
148 void TIMER0_COMP_interrupt(void) |
|
149 #else // GCC |
|
150 ISR(TIMER0_COMP_vect) |
|
151 #endif // GCC |
|
152 /****************************************************************************** |
|
153 Interruptserviceroutine Timer 2 Compare A for the main cycle |
|
154 ******************************************************************************/ |
|
155 |
|
156 { |
|
157 timer_interrupt = 1; // Set flag |
|
158 } |
|