2 This file is part of CanFestival, a library implementing CanOpen Stack.
4 Copyright (C): Edouard TISSERANT and Francis DUPIN
5 AVR Port: Andreas GLAUSER and Peter CHRISTEN
7 See COPYING file for copyrights details.
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.
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.
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
23 /******************************************************************************
25 Test projekt for a DS 401 slave, running on Atmel's STK500 with AT90CAN128
27 PORTA: Inputs (Keys, low active)
28 PORTB: Outputs (LEDs, low active)
29 PORTC: Node ID (1 BCD switch)
31 ******************************************************************************/
33 #include "canfestival.h"
39 unsigned char timer_interrupt = 0; // Set if timer interrupt eclapsed
44 unsigned char digital_input[1] = {0};
45 unsigned char digital_output[1] = {0};
47 static Message m = Message_Initializer; // contain a CAN message
51 // macros to handle the schedule timer
52 #define sys_timer timer_interrupt
53 #define reset_sys_timer() timer_interrupt = 0
54 #define CYCLE_TIME 1000 // Sample Timebase [us]
58 sys_init(); // Initialize system
59 canInit(CAN_BAUDRATE); // Initialize the CANopen bus
60 initTimer(); // Start timer for the CANopen stack
61 nodeID = read_bcd(); // Read node ID first
62 setNodeId (&ObjDict_Data, nodeID);
63 setState(&ObjDict_Data, Initialisation); // Init the state
65 for(;;) // forever loop
67 if (sys_timer) // Cycle timer, invoke action on every time slice
69 reset_sys_timer(); // Reset timer
70 digital_input[0] = get_inputs();
71 digital_input_handler(&ObjDict_Data, digital_input, sizeof(digital_input));
72 digital_output_handler(&ObjDict_Data, digital_output, sizeof(digital_output));
73 set_outputs(digital_output[0]);
75 // Check if CAN address has been changed
76 if(!( nodeID == read_bcd()))
78 nodeID = read_bcd(); // Save the new CAN adress
79 setState(&ObjDict_Data, Stopped); // Stop the node, to change the node ID
80 setNodeId(&ObjDict_Data, nodeID); // Now the CAN adress is changed
81 setState(&ObjDict_Data, Pre_operational); // Set to Pre_operational, master must boot it again
85 // a message was received pass it to the CANstack
86 if (canReceive(&m)) // a message reveived
87 canDispatch(&ObjDict_Data, &m); // process it
91 #ifdef WD_SLEEP // Watchdog and Sleep
95 #endif // Watchdog and Sleep
101 /******************************************************************************
102 Initialize the relays, the main states and the modbus protocol stack.
103 INPUT LOCK_STATES *lock_states
105 ******************************************************************************/
109 PORTA = 0xFF; // Inputs (Keys, low active) with pullup
111 PORTB = 0xFF; // Outputs (LEDs, low active) all 1
113 PORTC = 0xFF; // 1 BCD switch with pullup
115 PORTD = 0x2C; // 2xCOM, unused, CAN, unused
116 DDRD = 0x2A; // All init 0 or without pullup
117 PORTE = 0x00; // Output
118 DDRE = 0x3C; // 2x not used, 2x not used
119 PORTF = 0x00; // Not used
120 DDRF = 0xFF; // All output
121 PORTG = 0x00; // Not used
122 DDRG = 0x1F; // Output for debug (only 5 pins)
124 // Set timer 0 for main schedule time
125 TCCR0A |= 1 << WGM01 | 1 << CS01 | 1 << CS00;// Timer 0 CTC , Timer 0 mit CK/64 starten
126 TIMSK0 = 1 << OCIE0A; // Timer Interrupts: Timer 0 Compare
127 OCR0A = (unsigned char)(F_CPU / 64 * CYCLE_TIME/1000000 - 1); // Reloadvalue for timer 0
128 #ifdef WD_SLEEP // Watchdog and Sleep
130 wdt_enable(WDTO_15MS); // Watchdogtimer start with 16 ms timeout
131 #endif // Watchdog and Sleep
132 sei(); // Enable Interrupts
136 #ifdef __IAR_SYSTEMS_ICC__
137 #pragma type_attribute = __interrupt
138 #pragma vector=TIMER0_COMP_vect
139 void TIMER0_COMP_interrupt(void)
141 ISR(TIMER0_COMP_vect)
143 /******************************************************************************
144 Interruptserviceroutine Timer 2 Compare A for the main cycle
145 ******************************************************************************/
148 timer_interrupt = 1; // Set flag