00001 /* 00002 This file is part of CanFestival, a library implementing CanOpen Stack. 00003 00004 Copyright (C): Edouard TISSERANT and Francis DUPIN 00005 00006 See COPYING file for copyrights details. 00007 00008 This library is free software; you can redistribute it and/or 00009 modify it under the terms of the GNU Lesser General Public 00010 License as published by the Free Software Foundation; either 00011 version 2.1 of the License, or (at your option) any later version. 00012 00013 This library is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 Lesser General Public License for more details. 00017 00018 You should have received a copy of the GNU Lesser General Public 00019 License along with this library; if not, write to the Free Software 00020 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00021 */ 00022 00023 // Uncomment if you don't need console informations. 00024 #define DEBUG_WAR_CONSOLE_ON 00025 #define DEBUG_ERR_CONSOLE_ON 00026 00027 #include <stddef.h> /* for NULL */ 00028 00029 #include <asm-m68hc12/portsaccess.h> 00030 #include <asm-m68hc12/ports_def.h> 00031 #include <asm-m68hc12/ports.h> 00032 #include <interrupt.h> 00033 00034 #include "../include/data.h" 00035 #include <applicfg.h> 00036 00037 00038 00039 #include "../include/hcs12/candriver.h" 00040 #include "../include/hcs12/canOpenDriver.h" 00041 #include "../include/def.h" 00042 #include "../include/can.h" 00043 #include "../include/objdictdef.h" 00044 #include "../include/objacces.h" 00045 #include "../include/sdo.h" 00046 #include "../include/pdo.h" 00047 #include "../include/timer.h" 00048 #include "../include/lifegrd.h" 00049 #include "../include/sync.h" 00050 00051 #include "../include/nmtSlave.h" 00052 00053 // File created by the GUI 00054 #include "objdict.h" 00055 00056 00057 00058 00059 00060 // HCS12 configuration 00061 // ----------------------------------------------------- 00062 00063 enum E_CanBaudrate 00064 { 00065 CAN_BAUDRATE_250K, 00066 CAN_BAUDRATE_500K, 00067 CAN_BAUDRATE_1M, 00068 }; 00069 00070 00071 const canBusTime CAN_Baudrates[] = 00072 { 00073 { 00074 1, /* clksrc: Use the bus clock : 16 MHz, the freq. of the quartz's board */ 00075 3, /* brp : chose btw 0 and 63 (6 bits). freq time quantum = 16MHz / (brp + 1) */ 00076 0, /* sjw : chose btw 0 and 3 (2 bits). Sync on (sjw + 1 ) time quantum */ 00077 0, /* samp : chose btw 0 and 3 (2 bits) (samp + 1 ) samples per bit */ 00078 1, /* tseg2 : chose btw 0 and 7 (3 bits) Segment 2 width = (tseg2 + 1) tq */ 00079 12, /* tseg1 : chose btw 0 and 15 (4 bits) Segment 1 width = (tseg1 + 1) tq */ 00080 00081 /* 00082 With these values, 00083 - The width of the bit time is 16 time quantum : 00084 - 1 tq for the SYNC segment (could not be modified) 00085 - 13 tq for the TIME 1 segment (tseg1 = 12) 00086 - 2 tq for the TIME 2 segment (tseg2 = 1) 00087 - Because the bus clock of the MSCAN is 16 MHZ, and the 00088 freq of the time quantum is 4 MHZ (brp = 3+1), and there are 16 tq in the bit time, 00089 so the freq of the bit time is 250 kHz. 00090 */ 00091 }, 00092 00093 { 00094 1, /* clksrc: Use the bus clock : 16 MHz, the freq. of the quartz's board */ 00095 1, /* brp : chose btw 0 and 63 (6 bits). freq time quantum = 16MHz / (brp + 1) */ 00096 0, /* sjw : chose btw 0 and 3 (2 bits). Sync on (sjw + 1 ) time quantum */ 00097 0, /* samp : chose btw 0 and 3 (2 bits) (samp + 1 ) samples per bit */ 00098 1, /* tseg2 : chose btw 0 and 7 (3 bits) Segment 2 width = (tseg2 + 1) tq */ 00099 12, /* tseg1 : chose btw 0 and 15 (4 bits) Segment 1 width = (tseg1 + 1) tq */ 00100 00101 /* 00102 With these values, 00103 - The width of the bit time is 16 time quantum : 00104 - 1 tq for the SYNC segment (could not be modified) 00105 - 13 tq for the TIME 1 segment (tseg1 = 12) 00106 - 2 tq for the TIME 2 segment (tseg2 = 1) 00107 - Because the bus clock of the MSCAN is 16 MHZ, and the 00108 freq of the time quantum is 8 MHZ (brp = 1+1), and there are 16 tq in the bit time, 00109 so the freq of the bit time is 500 kHz. 00110 */ 00111 }, 00112 00113 { 00114 1, /* clksrc: Use the bus clock : 16 MHz, the freq. of the quartz's board */ 00115 1, /* brp : chose btw 0 and 63 (6 bits). freq time quantum = 16MHz / (brp + 1) */ 00116 0, /* sjw : chose btw 0 and 3 (2 bits). Sync on (sjw + 1 ) time quantum */ 00117 0, /* samp : chose btw 0 and 3 (2 bits) (samp +MSG_WAR(0x3F33, "Je suis le noeud ", getNodeId()); 1 ) samples per bit */ 00118 1, /* tseg2 : chose btw 0 and 7 (3 bits) Segment 2 width = (tseg2 + 1) tq */ 00119 4, /* tseg1 : chose btw 0 and 15 (4 bits) Segment 1 width = (tseg1 + 1) tq */ 00120 00121 /* 00122 With these values, 00123 - The width of the bit time is 16 time quantum : 00124 - 1 tq for the SYNC segment (could not be modified) 00125 - 5 tq for the TIME 1 segment (tseg1 = 4) 00126 - 2 tq for the TIME 2 segment (tseg2 = 1) 00127 - Because the bus clock of the MSCAN is 16 MHZ, and the 00128 freq of the time quantum is 8 MHZ (brp = 1+1), and there are 8 tq in the bit time, 00129 so the freq of the bit time is 1 MHz. 00130 */ 00131 } 00132 }; 00133 00134 00135 00136 00137 /**************************prototypes*****************************************/ 00138 00139 //Init can bus and Canopen 00140 void initCanopencapteur (void); 00141 // Init the sensor 00142 void initSensor(void); 00143 void initPortB(void); 00144 void initPortH(void); 00145 00146 00147 //------------------------------------------------------------------------------ 00148 //Initialisation of the port B for the leds. 00149 void initPortB(void) 00150 { 00151 // Port B is output 00152 IO_PORTS_8(DDRB)= 0XFF; 00153 // RAZ 00154 IO_PORTS_8(PORTB) = 0xFF; 00155 } 00156 00157 //------------------------------------------------------------------------------ 00158 // Init of port H to choose the CAN rate by switch, and the nodeId 00159 void initPortH(void) 00160 { 00161 // Port H is input 00162 IO_PORTS_8(DDRH)= 0X00; 00163 // Enable pull device 00164 IO_PORTS_8(PERH) = 0XFF; 00165 // Choose the pull-up device 00166 IO_PORTS_8(PPSH) = 0X00; 00167 } 00168 00169 //------------------------------------------------------------------------------ 00170 void initSensor(void) 00171 { 00172 UNS8 baudrate = 0; 00173 UNS8 nodeId = 0; 00174 // Init led control 00175 initPortB(); 00176 IO_PORTS_8(PORTB) &= ~ 0x01; //One led ON 00177 initPortH(); 00178 00179 /* Defining the node Id */ 00180 // Uncomment to have a fixed nodeId 00181 //setNodeId(&gene_SYNC_Data, 0x03); 00182 00183 // Comment below to have a fixed nodeId 00184 nodeId = ~(IO_PORTS_8(PTH)) & 0x3F; 00185 if (nodeId == 0) { 00186 MSG_WAR(0x3F33, "Using default nodeId : ", getNodeId(&gene_SYNC_Data)); 00187 } 00188 else 00189 setNodeId(&gene_SYNC_Data, nodeId); 00190 00191 MSG_WAR(0x3F33, "My nodeId is : ", getNodeId(&gene_SYNC_Data)); 00192 00193 canBusInit bi0 = { 00194 0, /* no low power */ 00195 0, /* no time stamp */ 00196 1, /* enable MSCAN */ 00197 0, /* clock source : oscillator (In fact, it is not used) */ 00198 0, /* no loop back */ 00199 0, /* no listen only */ 00200 0, /* no low pass filter for wk up */ 00201 CAN_Baudrates[CAN_BAUDRATE_250K], 00202 { 00203 0x00, /* Filter on 16 bits. See Motorola Block Guide V02.14 fig 4-3 */ 00204 0x00, 0xFF, /* filter 0 hight accept all msg */ 00205 0x00, 0xFF, /* filter 0 low accept all msg */ 00206 0x00, 0xFF, /* filter 1 hight filter all of msg */ 00207 0x00, 0xFF, /* filter 1 low filter all of msg */ 00208 0x00, 0xFF, /* filter 2 hight filter most of msg */ 00209 0x00, 0xFF, /* filter 2 low filter most of msg */ 00210 0x00, 0xFF, /* filter 3 hight filter most of msg */ 00211 0x00, 0xFF, /* filter 3 low filter most of msg */ 00212 } 00213 }; 00214 00215 //Init the HCS12 microcontroler for CanOpen 00216 initHCS12(); 00217 00218 // Chose the CAN rate (On our board, whe have switch for all purpose) 00219 // 7 8 00220 // ON ON => 1000 kpbs 00221 // OFF ON => 500 kpbs 00222 // ON OFF => 250 kpbs 00223 00224 baudrate = ~(IO_PORTS_8(PTH)) & 0xC0; 00225 00226 // Uncomment to have a fixed baudrate of 250 kbps 00227 //baudrate = 1; 00228 00229 switch (baudrate) { 00230 case 0x40: 00231 bi0.clk = CAN_Baudrates[CAN_BAUDRATE_250K]; 00232 MSG_WAR(0x3F30, "CAN 250 kbps ", 0); 00233 break; 00234 case 0x80: 00235 bi0.clk = CAN_Baudrates[CAN_BAUDRATE_500K]; 00236 MSG_WAR(0x3F31, "CAN 500 kbps ", 0); 00237 break; 00238 case 0xC0: 00239 bi0.clk = CAN_Baudrates[CAN_BAUDRATE_1M]; 00240 MSG_WAR(0x3F31, "CAN 1000 kbps ", 0); 00241 break; 00242 default: 00243 bi0.clk = CAN_Baudrates[CAN_BAUDRATE_250K]; 00244 MSG_WAR(0x2F32, "CAN BAUD RATE NOT DEFINED => 250 kbps ", 0); 00245 } 00246 00247 00248 00249 MSG_WAR(0x3F33, "SYNC signal generator ", 0); 00250 00251 canInit(CANOPEN_LINE_NUMBER_USED, bi0); //initialize filters... 00252 initTimer(); // Init hcs12 timer used by CanFestival. (see timerhw.c) 00253 unlock(); // Allow interruptions 00254 } 00255 00256 00257 00258 00259 00260 00261 //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 00262 // FUNCTIONS WHICH ARE PART OF CANFESTIVAL and *must* be implemented here. 00263 00264 //------------------------------------------------------------------------------ 00265 void gene_SYNC_heartbeatError( UNS8 heartbeatID ) 00266 { 00267 00268 MSG_ERR(0x1F00, "HeartBeat not received from node : ", heartbeatID); 00269 } 00270 00271 //------------------------------------------------------------------------------ 00272 void gene_SYNC_initialisation() 00273 { 00274 MSG_WAR (0x3F00, "Entering in INIT ", 0); 00275 initSensor(); 00276 00277 IO_PORTS_8(PORTB) &= ~ 0x01; // led 0 : ON 00278 IO_PORTS_8(PORTB) |= 0x0E; // leds 1, 2, 3 : OFF 00279 00280 } 00281 00282 00283 //------------------------------------------------------------------------------ 00284 void gene_SYNC_preOperational() 00285 { 00286 MSG_WAR (0x3F01, "Entering in PRE-OPERATIONAL ", 0); 00287 IO_PORTS_8(PORTB) &= ~ 0x03; // leds 0, 1 : ON 00288 IO_PORTS_8(PORTB) |= 0x0C; // leds 2, 3 : OFF 00289 /* default values for the msg CAN filters */ 00290 /* Accept all */ 00291 { 00292 canBusFilterInit filterConfiguration = 00293 { 00294 0x01, /* Filter on 16 bits. See Motorola Block Guide V02.14 */ 00295 /*canidarx, canidmrx */ 00296 0x00, 0xFF, /* filter 0 */ 00297 0x00, 0xFF, /* filter 0 */ 00298 0x00, 0xFF, /* filter 1 */ 00299 0x00, 0xFF, /* filter 1 */ 00300 0x00, 0xFF, /* filter 2 */ 00301 0x00, 0xFF, /* filter 2 */ 00302 0x00, 0xFF, /* filter 3 */ 00303 0x00, 0xFF, /* filter 3 */ 00304 }; 00305 canChangeFilter(CANOPEN_LINE_NUMBER_USED, filterConfiguration); 00306 } 00307 // Reset the automatic change by SDO 00308 applyDownloadedFilters = 0; 00309 00310 } 00311 00312 00313 //------------------------------------------------------------------------------ 00314 void gene_SYNC_operational() 00315 { 00316 MSG_WAR (0x3F02, "Entering in OPERATIONAL ", 0); 00317 IO_PORTS_8(PORTB) &= ~ 0x07; // leds 0, 1, 2 : ON 00318 IO_PORTS_8(PORTB) |= 0x08; // leds 3 : OFF 00319 00320 // Filtering the CAN received msgs. 00321 // 2 ways 00322 // First :applying an automatic filter 00323 // Second : The values of the filtering registers are mapped in the object dictionary, 00324 // So that a filtering configuration can be downloaded by SDO in pre-operational mode 00325 00326 if (applyDownloadedFilters == 0) {// No downloaded configuration to apply 00327 UNS16 accept1 = 0x0000; // Accept NMT 00328 UNS16 mask1 = 0x0FFF; // Mask NMT 00329 UNS16 accept2 = 0xE000; // Accept NMT error control (heartbeat, nodeguard) 00330 UNS16 mask2 = 0x0FFF; // Mask NMT error control (heartbeat, nodeguard) 00331 00332 canBusFilterInit filterConfiguration = 00333 {// filters 3 and 4 not used, so configured like filter 1. 00334 0x01, /* Filter on 16 bits. See Motorola Block Guide V02.14 */ 00335 /*canidarx, canidmrx */ 00336 (UNS8)(accept1 >> 8), (UNS8)(mask1 >> 8), /* filter 1 id10...3*/ 00337 (UNS8)accept1 , (UNS8)mask1, /* filter 1 id2 ... */ 00338 (UNS8)(accept2 >> 8), (UNS8)(mask2 >> 8), /* filter 2 id10...3*/ 00339 (UNS8)accept2 , (UNS8)mask2, /* filter 2 id2 ... */ 00340 (UNS8)(accept1 >> 8), (UNS8)(mask1 >> 8), /* filter 3 id10...3*/ 00341 (UNS8)accept1 , (UNS8)mask1, /* filter 3 id2 ... */ 00342 (UNS8)(accept1 >> 8), (UNS8)(mask1 >> 8), /* filter 4 id10...3*/ 00343 (UNS8)accept1 , (UNS8)mask1 /* filter 4 id2 ... */ 00344 }; 00345 canChangeFilter(CANOPEN_LINE_NUMBER_USED, filterConfiguration); 00346 MSG_WAR (0x3F03, "Internal CAN Rcv filter applied ", 0); 00347 } 00348 else { // Apply filters downnloaded 00349 canBusFilterInit filterConfiguration = 00350 {// filters 3 and 4 not used, so configured like filter 1. 00351 0x01, /* Filter on 16 bits. See Motorola Block Guide V02.14 */ 00352 /*canidarx, canidmrx */ 00353 (UNS8)( acceptanceFilter1>> 8), (UNS8)(mask1 >> 8), /* filter 1 id10...3*/ 00354 (UNS8)acceptanceFilter1 , (UNS8)mask1, /* filter 1 id2 ... */ 00355 (UNS8)(acceptanceFilter2 >> 8), (UNS8)(mask2 >> 8), /* filter 2 id10...3*/ 00356 (UNS8)acceptanceFilter2 , (UNS8)mask2, /* filter 2 id2 ... */ 00357 (UNS8)(acceptanceFilter3 >> 8), (UNS8)(mask3 >> 8), /* filter 3 id10...3*/ 00358 (UNS8)acceptanceFilter3 , (UNS8)mask3, /* filter 3 id2 ... */ 00359 (UNS8)(acceptanceFilter4 >> 8), (UNS8)(mask4 >> 8), /* filter 4 id10...3*/ 00360 (UNS8)acceptanceFilter4 , (UNS8)mask4 /* filter 4 id2 ... */ 00361 }; 00362 canChangeFilter(CANOPEN_LINE_NUMBER_USED, filterConfiguration); 00363 MSG_WAR (0x3F04, "Downloaded CAN Rcv filter applied ", 0); 00364 } 00365 } 00366 00367 //------------------------------------------------------------------------------ 00368 void gene_SYNC_stopped() 00369 { 00370 MSG_WAR (0x3F02, "Entering in STOPPED ", 0); 00371 IO_PORTS_8(PORTB) |= 0x0E; // leds 1, 2, 3, 4 : OFF 00372 } 00373 00374 // End functions which are part of Canfestival 00375 //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 00376 00377 00378 /******************************************************************************/ 00379 /********************************* MAIN ***************************************/ 00380 /******************************************************************************/ 00381 00382 00383 UNS8 main (void) 00384 { 00385 00386 MSG_WAR(0x3F34, "Entering in the main ", 0); 00387 //----------------------------- INITIALISATION -------------------------------- 00388 gene_SYNC_Data.heartbeatError = gene_SYNC_heartbeatError; 00389 gene_SYNC_Data.initialisation = gene_SYNC_initialisation; 00390 gene_SYNC_Data.preOperational = gene_SYNC_preOperational; 00391 gene_SYNC_Data.preOperational = gene_SYNC_operational; 00392 gene_SYNC_Data.stopped = gene_SYNC_stopped; 00393 00394 00395 /* Put the node in Initialisation mode */ 00396 MSG_WAR(0x3F35, "Will entering in INIT ", 0); 00397 setState(&gene_SYNC_Data, Initialisation); 00398 00399 //----------------------------- START ----------------------------------------- 00400 /* Put the node in pre-operational mode */ 00401 //MSG_WAR(0x3F36, "va passer en pre-op", 0); 00402 //setState(&gene_SYNC_Data, Pre_operational); 00403 00404 // Loop of receiving messages 00405 while (1) { 00406 Message m; 00407 if (f_can_receive(0, &m)) { 00408 //MSG_WAR(0x3F36, "Msg received", m.cob_id.w); 00409 lock(); // Not to have interruptions by timer, which can corrupt the data 00410 canDispatch(&gene_SYNC_Data, &m); 00411 unlock(); 00412 } 00413 } 00414 00415 return (0); 00416 } 00417 00418 00419