etisserant@0: /* etisserant@0: This file is part of CanFestival, a library implementing CanOpen Stack. etisserant@0: etisserant@0: Copyright (C): Edouard TISSERANT and Francis DUPIN etisserant@0: etisserant@0: See COPYING file for copyrights details. etisserant@0: etisserant@0: This library is free software; you can redistribute it and/or etisserant@0: modify it under the terms of the GNU Lesser General Public etisserant@0: License as published by the Free Software Foundation; either etisserant@0: version 2.1 of the License, or (at your option) any later version. etisserant@0: etisserant@0: This library is distributed in the hope that it will be useful, etisserant@0: but WITHOUT ANY WARRANTY; without even the implied warranty of etisserant@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU etisserant@0: Lesser General Public License for more details. etisserant@0: etisserant@0: You should have received a copy of the GNU Lesser General Public etisserant@0: License along with this library; if not, write to the Free Software etisserant@0: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA etisserant@0: */ etisserant@0: etisserant@0: etisserant@0: #define DEBUG_WAR_CONSOLE_ON etisserant@0: #define DEBUG_ERR_CONSOLE_ON etisserant@0: etisserant@0: #include /* for NULL */ etisserant@0: etisserant@0: #include etisserant@0: #include etisserant@0: #include etisserant@0: #include etisserant@0: etisserant@0: #include etisserant@0: etisserant@0: etisserant@0: etisserant@0: #include <../include/hcs12/candriver.h> etisserant@0: etisserant@0: #include "../include/def.h" etisserant@0: #include "../include/can.h" etisserant@0: #include "../include/objdictdef.h" etisserant@0: #include "../include/objacces.h" etisserant@0: #include "../include/sdo.h" etisserant@0: #include "../include/pdo.h" etisserant@0: #include "../include/timer.h" etisserant@0: #include "../include/lifegrd.h" etisserant@0: #include "../include/sync.h" etisserant@0: etisserant@0: etisserant@0: #include "../include/nmtSlave.h" etisserant@0: #include "objdict.h" etisserant@0: etisserant@0: etisserant@0: // HCS12 configuration etisserant@0: // ----------------------------------------------------- etisserant@0: etisserant@0: enum E_CanBaudrate etisserant@0: { etisserant@0: CAN_BAUDRATE_250K, etisserant@0: CAN_BAUDRATE_500K, etisserant@0: CAN_BAUDRATE_1M, etisserant@0: }; etisserant@0: etisserant@0: etisserant@0: const canBusTime CAN_Baudrates[] = etisserant@0: { etisserant@0: { etisserant@0: 1, /* clksrc: Use the bus clock : 16 MHz, the freq. of the quartz's board */ etisserant@0: 3, /* brp : chose btw 0 and 63 (6 bits). freq time quantum = 16MHz / (brp + 1) */ etisserant@0: 0, /* sjw : chose btw 0 and 3 (2 bits). Sync on (sjw + 1 ) time quantum */ etisserant@0: 0, /* samp : chose btw 0 and 3 (2 bits) (samp + 1 ) samples per bit */ etisserant@0: 1, /* tseg2 : chose btw 0 and 7 (3 bits) Segment 2 width = (tseg2 + 1) tq */ etisserant@0: 12, /* tseg1 : chose btw 0 and 15 (4 bits) Segment 1 width = (tseg1 + 1) tq */ etisserant@0: etisserant@0: /* etisserant@0: With these values, etisserant@0: - The width of the bit time is 16 time quantum : etisserant@0: - 1 tq for the SYNC segment (could not be modified) etisserant@0: - 13 tq for the TIME 1 segment (tseg1 = 12) etisserant@0: - 2 tq for the TIME 2 segment (tseg2 = 1) etisserant@0: - Because the bus clock of the MSCAN is 16 MHZ, and the etisserant@0: freq of the time quantum is 4 MHZ (brp = 3+1), and there are 16 tq in the bit time, etisserant@0: so the freq of the bit time is 250 kHz. etisserant@0: */ etisserant@0: }, etisserant@0: etisserant@0: { etisserant@0: 1, /* clksrc: Use the bus clock : 16 MHz, the freq. of the quartz's board */ etisserant@0: 1, /* brp : chose btw 0 and 63 (6 bits). freq time quantum = 16MHz / (brp + 1) */ etisserant@0: 0, /* sjw : chose btw 0 and 3 (2 bits). Sync on (sjw + 1 ) time quantum */ etisserant@0: 0, /* samp : chose btw 0 and 3 (2 bits) (samp + 1 ) samples per bit */ etisserant@0: 1, /* tseg2 : chose btw 0 and 7 (3 bits) Segment 2 width = (tseg2 + 1) tq */ etisserant@0: 12, /* tseg1 : chose btw 0 and 15 (4 bits) Segment 1 width = (tseg1 + 1) tq */ etisserant@0: etisserant@0: /* etisserant@0: With these values, etisserant@0: - The width of the bit time is 16 time quantum : etisserant@0: - 1 tq for the SYNC segment (could not be modified) etisserant@0: - 13 tq for the TIME 1 segment (tseg1 = 12) etisserant@0: - 2 tq for the TIME 2 segment (tseg2 = 1) etisserant@0: - Because the bus clock of the MSCAN is 16 MHZ, and the etisserant@0: freq of the time quantum is 8 MHZ (brp = 1+1), and there are 16 tq in the bit time, etisserant@0: so the freq of the bit time is 500 kHz. etisserant@0: */ etisserant@0: }, etisserant@0: etisserant@0: { etisserant@0: 1, /* clksrc: Use the bus clock : 16 MHz, the freq. of the quartz's board */ etisserant@0: 1, /* brp : chose btw 0 and 63 (6 bits). freq time quantum = 16MHz / (brp + 1) */ etisserant@0: 0, /* sjw : chose btw 0 and 3 (2 bits). Sync on (sjw + 1 ) time quantum */ etisserant@0: 0, /* samp : chose btw 0 and 3 (2 bits) (samp +MSG_WAR(0x3F33, "Je suis le noeud ", getNodeId()); 1 ) samples per bit */ etisserant@0: 1, /* tseg2 : chose btw 0 and 7 (3 bits) Segment 2 width = (tseg2 + 1) tq */ etisserant@0: 4, /* tseg1 : chose btw 0 and 15 (4 bits) Segment 1 width = (tseg1 + 1) tq */ etisserant@0: etisserant@0: /* etisserant@0: With these values, etisserant@0: - The width of the bit time is 16 time quantum : etisserant@0: - 1 tq for the SYNC segment (could not be modified) etisserant@0: - 5 tq for the TIME 1 segment (tseg1 = 4) etisserant@0: - 2 tq for the TIME 2 segment (tseg2 = 1) etisserant@0: - Because the bus clock of the MSCAN is 16 MHZ, and the etisserant@0: freq of the time quantum is 8 MHZ (brp = 1+1), and there are 8 tq in the bit time, etisserant@0: so the freq of the bit time is 1 MHz. etisserant@0: */ etisserant@0: } etisserant@0: }; etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: /**************************prototypes*****************************************/ etisserant@0: etisserant@0: //fonction d'initialisation du bus can et la couche CANOPEN pour le capteur etisserant@0: void initCanopencapteur (void); etisserant@0: // les fonctions d'initialisation du capteur: timer, compteurs logiciel etisserant@0: void initSensor(void); etisserant@0: void initPortB(void); etisserant@0: etisserant@0: //------------------------------------------------------------------------------ etisserant@0: //Initialisation of the port B for the leds. etisserant@0: void initPortB(void) etisserant@0: { etisserant@0: // Port B is output etisserant@0: IO_PORTS_8(DDRB)= 0XFF; etisserant@0: // RAZ etisserant@0: IO_PORTS_8(PORTB) = 0xFF; etisserant@0: } etisserant@0: etisserant@0: etisserant@0: etisserant@0: //------------------------------------------------------------------------------ etisserant@0: void initSensor(void) etisserant@0: { etisserant@0: UNS8 baudrate = 0; etisserant@0: MSG_WAR(0x3F33, "I am the node : ", getNodeId(&gene_SYNC_Data)); etisserant@0: // Init led control etisserant@0: initPortB(); etisserant@0: IO_PORTS_8(PORTB) &= ~ 0x01; //One led ON etisserant@0: // Init port to choose se CAN baudrate by switch etisserant@0: IO_PORTS_8(ATD0DIEN) = 0x03; etisserant@0: etisserant@0: canBusInit bi0 = { etisserant@0: 0, /* no low power */ etisserant@0: 0, /* no time stamp */ etisserant@0: 1, /* enable MSCAN */ etisserant@0: 0, /* clock source : oscillator (In fact, it is not used) */ etisserant@0: 0, /* no loop back */ etisserant@0: 0, /* no listen only */ etisserant@0: 0, /* no low pass filter for wk up */ etisserant@0: CAN_Baudrates[CAN_BAUDRATE_250K], etisserant@0: { etisserant@0: 0x00, /* Filter on 16 bits. See Motorola Block Guide V02.14 fig 4-3 */ etisserant@0: 0x00, 0xFF, /* filter 0 hight accept all msg */ etisserant@0: 0x00, 0xFF, /* filter 0 low accept all msg */ etisserant@0: 0x00, 0xFF, /* filter 1 hight filter all of msg */ etisserant@0: 0x00, 0xFF, /* filter 1 low filter all of msg */ etisserant@0: 0x00, 0xFF, /* filter 2 hight filter most of msg */ etisserant@0: 0x00, 0xFF, /* filter 2 low filter most of msg */ etisserant@0: 0x00, 0xFF, /* filter 3 hight filter most of msg */ etisserant@0: 0x00, 0xFF, /* filter 3 low filter most of msg */ etisserant@0: } etisserant@0: }; etisserant@0: etisserant@0: //Init the HCS12 microcontroler for CanOpen etisserant@0: initHCS12(); etisserant@0: etisserant@0: // Chose the CAN rate etisserant@0: baudrate = IO_PORTS_8(PORTAD0) & 0x03; etisserant@0: switch (baudrate) { etisserant@0: case 1: etisserant@0: bi0.clk = CAN_Baudrates[CAN_BAUDRATE_250K]; etisserant@0: MSG_WAR(0x3F30, "CAN 250 kbps ", 0); etisserant@0: break; etisserant@0: case 2: etisserant@0: bi0.clk = CAN_Baudrates[CAN_BAUDRATE_500K]; etisserant@0: MSG_WAR(0x3F31, "CAN 500 kbps ", 0); etisserant@0: break; etisserant@0: case 3: etisserant@0: bi0.clk = CAN_Baudrates[CAN_BAUDRATE_1M]; etisserant@0: MSG_WAR(0x3F31, "CAN 1000 kbps ", 0); etisserant@0: break; etisserant@0: default: etisserant@0: MSG_WAR(0x2F32, "CAN BAUD RATE NOT DEFINED ", 0); etisserant@0: } etisserant@0: etisserant@0: MSG_WAR(0x3F33, "SYNC signal generator", 0); etisserant@0: etisserant@0: canInit(CANOPEN_LINE_NUMBER_USED, bi0); //initialize filters... etisserant@0: initTimer(); // Init hcs12 timer used by CanFestival. (see timerhw.c) etisserant@0: unlock(); // Allow interruptions etisserant@0: } etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: etisserant@0: //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ etisserant@0: // FUNCTIONS WHICH ARE PART OF CANFESTIVAL and *must* be implemented here. etisserant@0: etisserant@0: //------------------------------------------------------------------------------ etisserant@0: void gene_SYNC_heartbeatError( UNS8 heartbeatID ) etisserant@0: { etisserant@0: etisserant@0: MSG_ERR(0x1F00, "HeartBeat not received from node : ", heartbeatID); etisserant@0: } etisserant@0: etisserant@0: //------------------------------------------------------------------------------ etisserant@0: void gene_SYNC_SDOtimeoutError (UNS8 line) etisserant@0: { etisserant@0: MSG_ERR(0x1F01, "SDO timeout for line : ", line); etisserant@0: } etisserant@0: etisserant@0: //------------------------------------------------------------------------------ etisserant@0: UNS8 gene_SYNC_canSend(Message *m) etisserant@0: { etisserant@0: // HCS12 driver function to send the CAN msg etisserant@0: canMsgTransmit(CAN0, *m); etisserant@0: return 0; etisserant@0: } etisserant@0: etisserant@0: //------------------------------------------------------------------------------ etisserant@0: void gene_SYNC_initialisation() etisserant@0: { etisserant@0: MSG_WAR (0x3F00, "Entering in INIT ", 0); etisserant@0: initSensor(); etisserant@0: IO_PORTS_8(PORTB) &= ~ 0x01; // led 0 : ON etisserant@0: IO_PORTS_8(PORTB) |= 0x0E; // leds 1, 2, 3 : OFF etisserant@0: } etisserant@0: etisserant@0: etisserant@0: //------------------------------------------------------------------------------ etisserant@0: void gene_SYNC_preOperational() etisserant@0: { etisserant@0: MSG_WAR (0x3F01, "Entering in PRE-OPERATIONAL ", 0); etisserant@0: IO_PORTS_8(PORTB) &= ~ 0x03; // leds 0, 1 : ON etisserant@0: IO_PORTS_8(PORTB) |= 0x0C; // leds 2, 3 : OFF etisserant@0: } etisserant@0: etisserant@0: etisserant@0: //------------------------------------------------------------------------------ etisserant@0: void gene_SYNC_operational() etisserant@0: { etisserant@0: MSG_WAR (0x3F02, "Entering in OPERATIONAL ", 0); etisserant@0: IO_PORTS_8(PORTB) &= ~ 0x07; // leds 0, 1, 2 : ON etisserant@0: IO_PORTS_8(PORTB) |= 0x08; // leds 3 : OFF etisserant@0: } etisserant@0: etisserant@0: //------------------------------------------------------------------------------ etisserant@0: void gene_SYNC_stopped() etisserant@0: { etisserant@0: MSG_WAR (0x3F02, "Entering in STOPPED ", 0); etisserant@0: } etisserant@0: etisserant@0: //------------------------------------------------------------------------------ etisserant@0: void gene_SYNC_post_sync() etisserant@0: { etisserant@0: } etisserant@0: etisserant@0: //------------------------------------------------------------------------------ etisserant@0: void gene_SYNC_post_TPDO() etisserant@0: { etisserant@0: } etisserant@0: etisserant@0: // End functions which are part of Canfestival etisserant@0: //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ etisserant@0: etisserant@0: etisserant@0: /******************************************************************************/ etisserant@0: /********************************* MAIN ***************************************/ etisserant@0: /******************************************************************************/ etisserant@0: etisserant@0: etisserant@0: UNS8 main (void) etisserant@0: { etisserant@0: etisserant@0: MSG_WAR(0x3F34, "Entering in the main", 0); etisserant@0: //----------------------------- INITIALISATION -------------------------------- etisserant@0: /* Defining the node Id */ etisserant@0: setNodeId(&gene_SYNC_Data, 0x03); etisserant@0: etisserant@0: /* Put the node in Initialisation mode */ etisserant@0: MSG_WAR(0x3F35, "va passer en init", 0); etisserant@0: setState(&gene_SYNC_Data, Initialisation); etisserant@0: etisserant@0: //----------------------------- START ----------------------------------------- etisserant@0: /* Put the node in pre-operational mode */ etisserant@0: //MSG_WAR(0x3F36, "va passer en pre-op", 0); etisserant@0: //setState(&gene_SYNC_Data, Pre_operational); etisserant@0: etisserant@0: while (1) { etisserant@0: { etisserant@0: Message m; etisserant@0: if (f_can_receive(0, &m)) { etisserant@0: MSG_WAR(0x3F36, "Msg received", m.cob_id.w); etisserant@0: canDispatch(&gene_SYNC_Data, &m); etisserant@0: } etisserant@0: etisserant@0: etisserant@0: } etisserant@0: etisserant@0: } etisserant@0: etisserant@0: return (0); etisserant@0: } etisserant@0: etisserant@0: etisserant@0: