amiro-blt / Target / Source / ARMCM3_STM32 / can.c @ 72294488
History | View | Annotate | Download (17.943 KB)
| 1 | 
      /************************************************************************************//**  | 
  
|---|---|
| 2 | 
      * \file         Source\ARMCM3_STM32\can.c
     | 
  
| 3 | 
      * \brief        Bootloader CAN communication interface source file.
     | 
  
| 4 | 
      * \ingroup      Target_ARMCM3_STM32
     | 
  
| 5 | 
      * \internal
     | 
  
| 6 | 
      *----------------------------------------------------------------------------------------
     | 
  
| 7 | 
      *                          C O P Y R I G H T
     | 
  
| 8 | 
      *----------------------------------------------------------------------------------------
     | 
  
| 9 | 
      *   Copyright (c) 2011  by Feaser    http://www.feaser.com    All rights reserved
     | 
  
| 10 | 
      *
     | 
  
| 11 | 
      *----------------------------------------------------------------------------------------
     | 
  
| 12 | 
      *                            L I C E N S E
     | 
  
| 13 | 
      *----------------------------------------------------------------------------------------
     | 
  
| 14 | 
      * This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
     | 
  
| 15 | 
      * modify it under the terms of the GNU General Public License as published by the Free
     | 
  
| 16 | 
      * Software Foundation, either version 3 of the License, or (at your option) any later
     | 
  
| 17 | 
      * version.
     | 
  
| 18 | 
      *
     | 
  
| 19 | 
      * OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
     | 
  
| 20 | 
      * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     | 
  
| 21 | 
      * PURPOSE. See the GNU General Public License for more details.
     | 
  
| 22 | 
      *
     | 
  
| 23 | 
      * You should have received a copy of the GNU General Public License along with OpenBLT.
     | 
  
| 24 | 
      * If not, see <http://www.gnu.org/licenses/>.
     | 
  
| 25 | 
      *
     | 
  
| 26 | 
      * A special exception to the GPL is included to allow you to distribute a combined work 
     | 
  
| 27 | 
      * that includes OpenBLT without being obliged to provide the source code for any 
     | 
  
| 28 | 
      * proprietary components. The exception text is included at the bottom of the license
     | 
  
| 29 | 
      * file <license.html>.
     | 
  
| 30 | 
      * 
     | 
  
| 31 | 
      * \endinternal
     | 
  
| 32 | 
      ****************************************************************************************/
     | 
  
| 33 | 
       | 
  
| 34 | 
       | 
  
| 35 | 
      /****************************************************************************************
     | 
  
| 36 | 
      * Include files
     | 
  
| 37 | 
      ****************************************************************************************/
     | 
  
| 38 | 
      #include "boot.h" /* bootloader generic header */  | 
  
| 39 | 
       | 
  
| 40 | 
       | 
  
| 41 | 
      #if (BOOT_COM_CAN_ENABLE > 0 || BOOT_GATE_CAN_ENABLE > 0)  | 
  
| 42 | 
      /****************************************************************************************
     | 
  
| 43 | 
      * Type definitions
     | 
  
| 44 | 
      ****************************************************************************************/
     | 
  
| 45 | 
      /** \brief CAN transmission mailbox layout. */
     | 
  
| 46 | 
      typedef struct  | 
  
| 47 | 
      {
     | 
  
| 48 | 
        volatile blt_int32u TIR;
     | 
  
| 49 | 
        volatile blt_int32u TDTR;
     | 
  
| 50 | 
        volatile blt_int32u TDLR;
     | 
  
| 51 | 
        volatile blt_int32u TDHR;
     | 
  
| 52 | 
      } tCanTxMailBox;  | 
  
| 53 | 
       | 
  
| 54 | 
      /** \brief CAN reception FIFO mailbox layout. */
     | 
  
| 55 | 
      typedef struct  | 
  
| 56 | 
      {
     | 
  
| 57 | 
        volatile blt_int32u RIR;
     | 
  
| 58 | 
        volatile blt_int32u RDTR;
     | 
  
| 59 | 
        volatile blt_int32u RDLR;
     | 
  
| 60 | 
        volatile blt_int32u RDHR;
     | 
  
| 61 | 
      } tCanRxFIFOMailBox;  | 
  
| 62 | 
       | 
  
| 63 | 
      /** \brief CAN filter register layout. */
     | 
  
| 64 | 
      typedef struct  | 
  
| 65 | 
      {
     | 
  
| 66 | 
        volatile blt_int32u FR1;
     | 
  
| 67 | 
        volatile blt_int32u FR2;
     | 
  
| 68 | 
      } tCanFilter;  | 
  
| 69 | 
       | 
  
| 70 | 
      /** \brief CAN controller register layout. */
     | 
  
| 71 | 
      typedef struct  | 
  
| 72 | 
      {
     | 
  
| 73 | 
        volatile blt_int32u MCR;
     | 
  
| 74 | 
        volatile blt_int32u MSR;
     | 
  
| 75 | 
        volatile blt_int32u TSR;
     | 
  
| 76 | 
        volatile blt_int32u RF0R;
     | 
  
| 77 | 
        volatile blt_int32u RF1R;
     | 
  
| 78 | 
        volatile blt_int32u IER;
     | 
  
| 79 | 
        volatile blt_int32u ESR;
     | 
  
| 80 | 
        volatile blt_int32u BTR;
     | 
  
| 81 | 
        blt_int32u          RESERVED0[88];
     | 
  
| 82 | 
        tCanTxMailBox       sTxMailBox[3];
     | 
  
| 83 | 
        tCanRxFIFOMailBox   sFIFOMailBox[2];
     | 
  
| 84 | 
        blt_int32u          RESERVED1[12];
     | 
  
| 85 | 
        volatile blt_int32u FMR;
     | 
  
| 86 | 
        volatile blt_int32u FM1R;
     | 
  
| 87 | 
      blt_int32u RESERVED2;  | 
  
| 88 | 
        volatile blt_int32u FS1R;
     | 
  
| 89 | 
      blt_int32u RESERVED3;  | 
  
| 90 | 
        volatile blt_int32u FFA1R;
     | 
  
| 91 | 
      blt_int32u RESERVED4;  | 
  
| 92 | 
        volatile blt_int32u FA1R;
     | 
  
| 93 | 
        blt_int32u          RESERVED5[8];
     | 
  
| 94 | 
        tCanFilter          sFilterRegister[14];
     | 
  
| 95 | 
      } tCanRegs;  | 
  
| 96 | 
       | 
  
| 97 | 
       | 
  
| 98 | 
      /****************************************************************************************
     | 
  
| 99 | 
      * Macro definitions
     | 
  
| 100 | 
      ****************************************************************************************/
     | 
  
| 101 | 
      /** \brief Reset request bit. */
     | 
  
| 102 | 
      #define CAN_BIT_RESET ((blt_int32u)0x00008000)  | 
  
| 103 | 
      /** \brief Initialization request bit. */
     | 
  
| 104 | 
      #define CAN_BIT_INRQ ((blt_int32u)0x00000001)  | 
  
| 105 | 
      /** \brief Initialization acknowledge bit. */
     | 
  
| 106 | 
      #define CAN_BIT_INAK ((blt_int32u)0x00000001)  | 
  
| 107 | 
      /** \brief Sleep mode request bit. */
     | 
  
| 108 | 
      #define CAN_BIT_SLEEP ((blt_int32u)0x00000002)  | 
  
| 109 | 
      /** \brief Filter 0 selection bit. */
     | 
  
| 110 | 
      #define CAN_BIT_FILTER0 ((blt_int32u)0x00000001)  | 
  
| 111 | 
      /** \brief Filter init mode bit. */
     | 
  
| 112 | 
      #define CAN_BIT_FINIT ((blt_int32u)0x00000001)  | 
  
| 113 | 
      /** \brief Transmit mailbox 0 empty bit. */
     | 
  
| 114 | 
      #define CAN_BIT_TME0 ((blt_int32u)0x04000000)  | 
  
| 115 | 
      /** \brief Transmit mailbox request bit. */
     | 
  
| 116 | 
      #define CAN_BIT_TXRQ ((blt_int32u)0x00000001)  | 
  
| 117 | 
      /** \brief Release FIFO 0 mailbox bit. */
     | 
  
| 118 | 
      #define CAN_BIT_RFOM0 ((blt_int32u)0x00000020)  | 
  
| 119 | 
       | 
  
| 120 | 
      #if (BOOT_GATE_CAN_ENABLE > 0)  | 
  
| 121 | 
      blt_bool commandSend;  | 
  
| 122 | 
      #endif /* BOOT_GATE_CAN_ENABLE > 0 */  | 
  
| 123 | 
       | 
  
| 124 | 
       | 
  
| 125 | 
      /****************************************************************************************
     | 
  
| 126 | 
      * Register definitions
     | 
  
| 127 | 
      ****************************************************************************************/
     | 
  
| 128 | 
      /** \brief Macro for accessing CAN controller registers. */
     | 
  
| 129 | 
      #define CANx ((tCanRegs *) (blt_int32u)0x40006400)  | 
  
| 130 | 
       | 
  
| 131 | 
       | 
  
| 132 | 
      /****************************************************************************************
     | 
  
| 133 | 
      * Type definitions
     | 
  
| 134 | 
      ****************************************************************************************/
     | 
  
| 135 | 
      /** \brief Structure type for grouping CAN bus timing related information. */
     | 
  
| 136 | 
      typedef struct t_can_bus_timing  | 
  
| 137 | 
      {
     | 
  
| 138 | 
        blt_int8u tseg1;                                    /**< CAN time segment 1          */
     | 
  
| 139 | 
        blt_int8u tseg2;                                    /**< CAN time segment 2          */
     | 
  
| 140 | 
      } tCanBusTiming;  | 
  
| 141 | 
       | 
  
| 142 | 
       | 
  
| 143 | 
      /****************************************************************************************
     | 
  
| 144 | 
      * Local constant declarations
     | 
  
| 145 | 
      ****************************************************************************************/
     | 
  
| 146 | 
      /** \brief CAN bittiming table for dynamically calculating the bittiming settings.
     | 
  
| 147 | 
       *  \details According to the CAN protocol 1 bit-time can be made up of between 8..25 
     | 
  
| 148 | 
       *           time quanta (TQ). The total TQ in a bit is SYNC + TSEG1 + TSEG2 with SYNC 
     | 
  
| 149 | 
       *           always being 1. The sample point is (SYNC + TSEG1) / (SYNC + TSEG1 + SEG2) * 
     | 
  
| 150 | 
       *           100%. This array contains possible and valid time quanta configurations with
     | 
  
| 151 | 
       *           a sample point between 68..78%.
     | 
  
| 152 | 
       */
     | 
  
| 153 | 
      static const tCanBusTiming canTiming[] =  | 
  
| 154 | 
      {                       /*  TQ | TSEG1 | TSEG2 | SP  */
     | 
  
| 155 | 
                              /* ------------------------- */
     | 
  
| 156 | 
          {  5, 2 },          /*   8 |   5   |   2   | 75% */
     | 
  
| 157 | 
          {  6, 2 },          /*   9 |   6   |   2   | 78% */
     | 
  
| 158 | 
          {  6, 3 },          /*  10 |   6   |   3   | 70% */
     | 
  
| 159 | 
          {  7, 3 },          /*  11 |   7   |   3   | 73% */
     | 
  
| 160 | 
          {  8, 3 },          /*  12 |   8   |   3   | 75% */
     | 
  
| 161 | 
          {  9, 3 },          /*  13 |   9   |   3   | 77% */
     | 
  
| 162 | 
          {  9, 4 },          /*  14 |   9   |   4   | 71% */
     | 
  
| 163 | 
          { 10, 4 },          /*  15 |  10   |   4   | 73% */
     | 
  
| 164 | 
          { 11, 4 },          /*  16 |  11   |   4   | 75% */
     | 
  
| 165 | 
          { 12, 4 },          /*  17 |  12   |   4   | 76% */
     | 
  
| 166 | 
          { 12, 5 },          /*  18 |  12   |   5   | 72% */
     | 
  
| 167 | 
          { 13, 5 },          /*  19 |  13   |   5   | 74% */
     | 
  
| 168 | 
          { 14, 5 },          /*  20 |  14   |   5   | 75% */
     | 
  
| 169 | 
          { 15, 5 },          /*  21 |  15   |   5   | 76% */
     | 
  
| 170 | 
          { 15, 6 },          /*  22 |  15   |   6   | 73% */
     | 
  
| 171 | 
          { 16, 6 },          /*  23 |  16   |   6   | 74% */
     | 
  
| 172 | 
          { 16, 7 },          /*  24 |  16   |   7   | 71% */
     | 
  
| 173 | 
          { 16, 8 }           /*  25 |  16   |   8   | 68% */
     | 
  
| 174 | 
      };  | 
  
| 175 | 
       | 
  
| 176 | 
       | 
  
| 177 | 
      /************************************************************************************//**  | 
  
| 178 | 
      ** \brief     Search algorithm to match the desired baudrate to a possible bus 
     | 
  
| 179 | 
      **            timing configuration.
     | 
  
| 180 | 
      ** \param     baud The desired baudrate in kbps. Valid values are 10..1000.
     | 
  
| 181 | 
      ** \param     prescaler Pointer to where the value for the prescaler will be stored.
     | 
  
| 182 | 
      ** \param     tseg1 Pointer to where the value for TSEG2 will be stored.
     | 
  
| 183 | 
      ** \param     tseg2 Pointer to where the value for TSEG2 will be stored.
     | 
  
| 184 | 
      ** \return    BLT_TRUE if the CAN bustiming register values were found, BLT_FALSE 
     | 
  
| 185 | 
      **            otherwise.
     | 
  
| 186 | 
      **
     | 
  
| 187 | 
      ****************************************************************************************/
     | 
  
| 188 | 
      static blt_bool CanGetSpeedConfig(blt_int16u baud, blt_int16u *prescaler, 
     | 
  
| 189 | 
      blt_int8u *tseg1, blt_int8u *tseg2)  | 
  
| 190 | 
      {
     | 
  
| 191 | 
      blt_int8u cnt;  | 
  
| 192 | 
       | 
  
| 193 | 
        /* loop through all possible time quanta configurations to find a match */
     | 
  
| 194 | 
      for (cnt=0; cnt < sizeof(canTiming)/sizeof(canTiming[0]); cnt++)  | 
  
| 195 | 
        {
     | 
  
| 196 | 
      if (((BOOT_CPU_SYSTEM_SPEED_KHZ/2) % (baud*(canTiming[cnt].tseg1+canTiming[cnt].tseg2+1))) == 0)  | 
  
| 197 | 
          {
     | 
  
| 198 | 
            /* compute the prescaler that goes with this TQ configuration */
     | 
  
| 199 | 
      *prescaler = (BOOT_CPU_SYSTEM_SPEED_KHZ/2)/(baud*(canTiming[cnt].tseg1+canTiming[cnt].tseg2+1));  | 
  
| 200 | 
       | 
  
| 201 | 
            /* make sure the prescaler is valid */
     | 
  
| 202 | 
      if ( (*prescaler > 0) && (*prescaler <= 1024) )  | 
  
| 203 | 
            {
     | 
  
| 204 | 
              /* store the bustiming configuration */
     | 
  
| 205 | 
      *tseg1 = canTiming[cnt].tseg1;  | 
  
| 206 | 
      *tseg2 = canTiming[cnt].tseg2;  | 
  
| 207 | 
              /* found a good bus timing configuration */
     | 
  
| 208 | 
              return BLT_TRUE;
     | 
  
| 209 | 
      }  | 
  
| 210 | 
      }  | 
  
| 211 | 
      }  | 
  
| 212 | 
        /* could not find a good bus timing configuration */
     | 
  
| 213 | 
        return BLT_FALSE;
     | 
  
| 214 | 
      } /*** end of CanGetSpeedConfig ***/
     | 
  
| 215 | 
       | 
  
| 216 | 
       | 
  
| 217 | 
      /************************************************************************************//**  | 
  
| 218 | 
      ** \brief     Initializes the CAN controller and synchronizes it to the CAN bus.
     | 
  
| 219 | 
      ** \return    none.
     | 
  
| 220 | 
      **
     | 
  
| 221 | 
      ****************************************************************************************/
     | 
  
| 222 | 
      void CanInit(void)  | 
  
| 223 | 
      {
     | 
  
| 224 | 
      blt_int16u prescaler;  | 
  
| 225 | 
      blt_int8u tseg1, tseg2;  | 
  
| 226 | 
      blt_bool result;  | 
  
| 227 | 
       | 
  
| 228 | 
      #if (BOOT_GATE_CAN_ENABLE > 0)  | 
  
| 229 | 
      commandSend = BLT_FALSE;  | 
  
| 230 | 
      #endif /* BOOT_GATE_CAN_ENABLE > 0 */  | 
  
| 231 | 
       | 
  
| 232 | 
        /* the current implementation supports CAN1. throw an assertion error in case a 
     | 
  
| 233 | 
         * different CAN channel is configured.  
     | 
  
| 234 | 
         */
     | 
  
| 235 | 
        ASSERT_CT(BOOT_COM_CAN_CHANNEL_INDEX == 0); 
     | 
  
| 236 | 
        /* obtain bittiming configuration information */
     | 
  
| 237 | 
        result = CanGetSpeedConfig(BOOT_COM_CAN_BAUDRATE/1000, &prescaler, &tseg1, &tseg2);
     | 
  
| 238 | 
      ASSERT_RT(result == BLT_TRUE);  | 
  
| 239 | 
        /* disable all can interrupt. this driver works in polling mode */
     | 
  
| 240 | 
        CANx->IER = (blt_int32u)0;
     | 
  
| 241 | 
        /* set request to reset the can controller */
     | 
  
| 242 | 
      CANx->MCR |= CAN_BIT_RESET ;  | 
  
| 243 | 
        /* wait for acknowledge that the can controller was reset */
     | 
  
| 244 | 
      while ((CANx->MCR & CAN_BIT_RESET) != 0)  | 
  
| 245 | 
        {
     | 
  
| 246 | 
          /* keep the watchdog happy */
     | 
  
| 247 | 
      CopService();  | 
  
| 248 | 
      }  | 
  
| 249 | 
        /* exit from sleep mode, which is the default mode after reset */
     | 
  
| 250 | 
      CANx->MCR &= ~CAN_BIT_SLEEP;  | 
  
| 251 | 
        /* set request to enter initialisation mode */
     | 
  
| 252 | 
      CANx->MCR |= CAN_BIT_INRQ ;  | 
  
| 253 | 
        /* wait for acknowledge that initialization mode was entered */
     | 
  
| 254 | 
      while ((CANx->MSR & CAN_BIT_INAK) == 0)  | 
  
| 255 | 
        {
     | 
  
| 256 | 
          /* keep the watchdog happy */
     | 
  
| 257 | 
      CopService();  | 
  
| 258 | 
      }  | 
  
| 259 | 
        /* configure the bittming */
     | 
  
| 260 | 
      CANx->BTR = (blt_int32u)((blt_int32u)(tseg1 - 1) << 16) | \  | 
  
| 261 | 
      (blt_int32u)((blt_int32u)(tseg2 - 1) << 20) | \  | 
  
| 262 | 
                    (blt_int32u)(prescaler - 1);
     | 
  
| 263 | 
        /* set request to leave initialisation mode */
     | 
  
| 264 | 
      CANx->MCR &= ~CAN_BIT_INRQ;  | 
  
| 265 | 
        /* wait for acknowledge that initialization mode was exited */
     | 
  
| 266 | 
      while ((CANx->MSR & CAN_BIT_INAK) != 0)  | 
  
| 267 | 
        {
     | 
  
| 268 | 
          /* keep the watchdog happy */
     | 
  
| 269 | 
      CopService();  | 
  
| 270 | 
      }  | 
  
| 271 | 
        /* enter initialisation mode for the acceptance filter */
     | 
  
| 272 | 
      CANx->FMR |= CAN_BIT_FINIT;  | 
  
| 273 | 
        /* deactivate filter 0 */
     | 
  
| 274 | 
      CANx->FA1R &= ~CAN_BIT_FILTER0;  | 
  
| 275 | 
        /* 32-bit scale for the filter */
     | 
  
| 276 | 
      CANx->FS1R |= CAN_BIT_FILTER0;  | 
  
| 277 | 
        /* open up the acceptance filter to receive all messages */
     | 
  
| 278 | 
      CANx->sFilterRegister[0].FR1 = 0;  | 
  
| 279 | 
      CANx->sFilterRegister[0].FR2 = 0;  | 
  
| 280 | 
        /* select id/mask mode for the filter */
     | 
  
| 281 | 
      CANx->FM1R &= ~CAN_BIT_FILTER0;  | 
  
| 282 | 
        /* FIFO 0 assignation for the filter */
     | 
  
| 283 | 
      CANx->FFA1R &= ~CAN_BIT_FILTER0;  | 
  
| 284 | 
        /* filter activation */
     | 
  
| 285 | 
      CANx->FA1R |= CAN_BIT_FILTER0;  | 
  
| 286 | 
        /* leave initialisation mode for the acceptance filter */
     | 
  
| 287 | 
      CANx->FMR &= ~CAN_BIT_FINIT;  | 
  
| 288 | 
      } /*** end of CanInit ***/
     | 
  
| 289 | 
       | 
  
| 290 | 
       | 
  
| 291 | 
      /************************************************************************************//**  | 
  
| 292 | 
      ** \brief     Transmits a packet formatted for the communication interface.
     | 
  
| 293 | 
      ** \param     data     Pointer to byte array with data that it to be transmitted.
     | 
  
| 294 | 
      ** \param     len      Number of bytes that are to be transmitted.
     | 
  
| 295 | 
      ** \param     deviceID ID of the device the data has to be sent to.
     | 
  
| 296 | 
      ** \return    none.
     | 
  
| 297 | 
      **
     | 
  
| 298 | 
      ****************************************************************************************/
     | 
  
| 299 | 
      void CanTransmitPacket(blt_int8u *data, blt_int8u len, blt_int8u deviceID)
     | 
  
| 300 | 
      {
     | 
  
| 301 | 
        /* make sure that transmit mailbox 0 is available */
     | 
  
| 302 | 
      ASSERT_RT((CANx->TSR&CAN_BIT_TME0) == CAN_BIT_TME0);  | 
  
| 303 | 
        /* build the message identifier */
     | 
  
| 304 | 
        CANx->sTxMailBox[0].TIR &= CAN_BIT_TXRQ;
     | 
  
| 305 | 
       | 
  
| 306 | 
      blt_int32u address;  | 
  
| 307 | 
      #if (BOOT_GATE_CAN_ENABLE > 0)  | 
  
| 308 | 
      if (deviceID == 0) {  | 
  
| 309 | 
      #endif /* BOOT_GATE_CAN_ENABLE > 0 */  | 
  
| 310 | 
      address = (blt_int32u)BOOT_COM_CAN_TX_MSG_ID;  | 
  
| 311 | 
      #if (BOOT_GATE_CAN_ENABLE > 0)  | 
  
| 312 | 
      commandSend = BLT_FALSE;  | 
  
| 313 | 
        } else {
     | 
  
| 314 | 
      address = ((blt_int32u)BOOT_COM_CAN_RX_MSG_ID | (blt_int32u)deviceID);  | 
  
| 315 | 
      commandSend = BLT_TRUE;  | 
  
| 316 | 
      }  | 
  
| 317 | 
      #endif /* BOOT_GATE_CAN_ENABLE > 0 */  | 
  
| 318 | 
       | 
  
| 319 | 
        /* init variables */
     | 
  
| 320 | 
        blt_int8u canData[8];
     | 
  
| 321 | 
      blt_int8u restLen = len;  | 
  
| 322 | 
        blt_int8u canIdx = 0;
     | 
  
| 323 | 
       | 
  
| 324 | 
        /* send the given package in 8 byte packages */
     | 
  
| 325 | 
      while (restLen > 0) {  | 
  
| 326 | 
       | 
  
| 327 | 
      CANx->sTxMailBox[0].TIR |= (address << 21);  | 
  
| 328 | 
          /* store the message date length code (DLC) */
     | 
  
| 329 | 
      if (restLen > 7) {  | 
  
| 330 | 
      CANx->sTxMailBox[0].TDTR = 8;  | 
  
| 331 | 
          } else {
     | 
  
| 332 | 
      CANx->sTxMailBox[0].TDTR = restLen+1;  | 
  
| 333 | 
      }  | 
  
| 334 | 
          /* Load max 8 bytes into message data bytes */
     | 
  
| 335 | 
          canData[0] = restLen;
     | 
  
| 336 | 
          canIdx = 1;
     | 
  
| 337 | 
      while (restLen > 0 && canIdx < 8) {  | 
  
| 338 | 
      canData[canIdx] = data[len-restLen];  | 
  
| 339 | 
      canIdx++;  | 
  
| 340 | 
      restLen--;  | 
  
| 341 | 
      }  | 
  
| 342 | 
          /* fill rest with nulls */
     | 
  
| 343 | 
      while (canIdx < 8) {  | 
  
| 344 | 
            canData[canIdx] = 0;
     | 
  
| 345 | 
      canIdx++;  | 
  
| 346 | 
      }  | 
  
| 347 | 
          /* store the message data bytes */
     | 
  
| 348 | 
      CANx->sTxMailBox[0].TDLR = (((blt_int32u)canData[3] << 24) | \  | 
  
| 349 | 
      ((blt_int32u)canData[2] << 16) | \  | 
  
| 350 | 
      ((blt_int32u)canData[1] << 8) | \  | 
  
| 351 | 
                                      ((blt_int32u)canData[0]));
     | 
  
| 352 | 
      CANx->sTxMailBox[0].TDHR = (((blt_int32u)canData[7] << 24) | \  | 
  
| 353 | 
      ((blt_int32u)canData[6] << 16) | \  | 
  
| 354 | 
      ((blt_int32u)canData[5] << 8) | \  | 
  
| 355 | 
                                      ((blt_int32u)canData[4]));
     | 
  
| 356 | 
          /* request the start of message transmission */
     | 
  
| 357 | 
          CANx->sTxMailBox[0].TIR |= CAN_BIT_TXRQ;
     | 
  
| 358 | 
          /* wait for transmit completion */
     | 
  
| 359 | 
      while ((CANx->TSR&CAN_BIT_TME0) == 0)  | 
  
| 360 | 
          {
     | 
  
| 361 | 
            /* keep the watchdog happy */
     | 
  
| 362 | 
      CopService();  | 
  
| 363 | 
      }  | 
  
| 364 | 
       | 
  
| 365 | 
      }  | 
  
| 366 | 
      } /*** end of CanTransmitPacket ***/
     | 
  
| 367 | 
       | 
  
| 368 | 
       | 
  
| 369 | 
      /************************************************************************************//**  | 
  
| 370 | 
      ** \brief     Receives a communication interface packet if one is present.
     | 
  
| 371 | 
      ** \param     data Pointer to byte array where the data is to be stored.
     | 
  
| 372 | 
      ** \return    Length of message (if the message is invalid, the length will be 0).
     | 
  
| 373 | 
      **
     | 
  
| 374 | 
      ****************************************************************************************/
     | 
  
| 375 | 
      blt_int8u CanReceivePacket(blt_int8u *data)  | 
  
| 376 | 
      {
     | 
  
| 377 | 
      blt_int32u rxMsgId;  | 
  
| 378 | 
      blt_bool result = BLT_FALSE;  | 
  
| 379 | 
        blt_int8u  length = 0;
     | 
  
| 380 | 
       | 
  
| 381 | 
        static blt_int8u readData[BOOT_COM_RX_MAX_DATA];
     | 
  
| 382 | 
      static blt_int8u receivedLen = 0;  | 
  
| 383 | 
      static blt_int8u lastLen = 0;  | 
  
| 384 | 
      static blt_int8u toReceive = 0;  | 
  
| 385 | 
        blt_int8u canData[8];
     | 
  
| 386 | 
      blt_int8u restLen;  | 
  
| 387 | 
      blt_int8u canLength;  | 
  
| 388 | 
       | 
  
| 389 | 
        /* check if a new message was received */
     | 
  
| 390 | 
      if ((CANx->RF0R&(blt_int32u)0x00000003) > 0)  | 
  
| 391 | 
        {
     | 
  
| 392 | 
          /* read out the message identifier */
     | 
  
| 393 | 
      rxMsgId = (blt_int32u)0x000007FF & (CANx->sFIFOMailBox[0].RIR >> 21);  | 
  
| 394 | 
          /* is this the packet identifier */
     | 
  
| 395 | 
       | 
  
| 396 | 
      blt_int32u compID;  | 
  
| 397 | 
      #if (BOOT_GATE_CAN_ENABLE > 0)  | 
  
| 398 | 
          if (commandSend == BLT_TRUE) {
     | 
  
| 399 | 
      compID = (blt_int32u)BOOT_COM_CAN_TX_MSG_ID;  | 
  
| 400 | 
          } else {
     | 
  
| 401 | 
      #endif /* BOOT_GATE_CAN_ENABLE > 0 */  | 
  
| 402 | 
      compID = (blt_int32u)BOOT_COM_CAN_RX_MSG_ID | (blt_int32u)BOOT_COM_DEVICE_ID;  | 
  
| 403 | 
      #if (BOOT_GATE_CAN_ENABLE > 0)  | 
  
| 404 | 
      }  | 
  
| 405 | 
      #endif /* BOOT_GATE_CAN_ENABLE > 0 */  | 
  
| 406 | 
       | 
  
| 407 | 
          if (rxMsgId == compID)
     | 
  
| 408 | 
          {
     | 
  
| 409 | 
      #if (BOOT_GATE_CAN_ENABLE > 0)  | 
  
| 410 | 
      commandSend = BLT_FALSE;  | 
  
| 411 | 
      #endif /* BOOT_GATE_CAN_ENABLE > 0 */  | 
  
| 412 | 
      result = BLT_TRUE;  | 
  
| 413 | 
       | 
  
| 414 | 
            /* save length */
     | 
  
| 415 | 
      canLength = (blt_int8u)0x0F & CANx->sFIFOMailBox[0].RDTR;  | 
  
| 416 | 
            /* store the received packet data */
     | 
  
| 417 | 
      canData[0] = (blt_int8u)0xFF & CANx->sFIFOMailBox[0].RDLR;  | 
  
| 418 | 
      canData[1] = (blt_int8u)0xFF & (CANx->sFIFOMailBox[0].RDLR >> 8);  | 
  
| 419 | 
      canData[2] = (blt_int8u)0xFF & (CANx->sFIFOMailBox[0].RDLR >> 16);  | 
  
| 420 | 
      canData[3] = (blt_int8u)0xFF & (CANx->sFIFOMailBox[0].RDLR >> 24);  | 
  
| 421 | 
      canData[4] = (blt_int8u)0xFF & CANx->sFIFOMailBox[0].RDHR;  | 
  
| 422 | 
      canData[5] = (blt_int8u)0xFF & (CANx->sFIFOMailBox[0].RDHR >> 8);  | 
  
| 423 | 
      canData[6] = (blt_int8u)0xFF & (CANx->sFIFOMailBox[0].RDHR >> 16);  | 
  
| 424 | 
      canData[7] = (blt_int8u)0xFF & (CANx->sFIFOMailBox[0].RDHR >> 24);  | 
  
| 425 | 
       | 
  
| 426 | 
            /* Store rest length of package and check if possible */
     | 
  
| 427 | 
      if (receivedLen == 0) {  | 
  
| 428 | 
              toReceive = canData[0];
     | 
  
| 429 | 
              lastLen = canData[0];
     | 
  
| 430 | 
            } else {
     | 
  
| 431 | 
              restLen = canData[0];
     | 
  
| 432 | 
      if (lastLen-restLen != 7) {  | 
  
| 433 | 
                // package has been lost - but nothing happens
     | 
  
| 434 | 
      }  | 
  
| 435 | 
      lastLen = restLen;  | 
  
| 436 | 
      }  | 
  
| 437 | 
       | 
  
| 438 | 
            /* store data in data package */
     | 
  
| 439 | 
      blt_int8u idx;  | 
  
| 440 | 
      for (idx=1; idx < canLength; idx++) {  | 
  
| 441 | 
      readData[receivedLen] = canData[idx];  | 
  
| 442 | 
      receivedLen++;  | 
  
| 443 | 
      }  | 
  
| 444 | 
       | 
  
| 445 | 
            /* check if full package has been received */
     | 
  
| 446 | 
            if (receivedLen >= toReceive) {
     | 
  
| 447 | 
              receivedLen = 0;
     | 
  
| 448 | 
      for (idx = 0; idx < toReceive; idx++) {  | 
  
| 449 | 
      data[idx] = readData[idx];  | 
  
| 450 | 
      }  | 
  
| 451 | 
      length = toReceive;  | 
  
| 452 | 
            } else {
     | 
  
| 453 | 
              length = 0;
     | 
  
| 454 | 
      }  | 
  
| 455 | 
      }  | 
  
| 456 | 
          /* release FIFO0 */
     | 
  
| 457 | 
      CANx->RF0R |= CAN_BIT_RFOM0;  | 
  
| 458 | 
      }  | 
  
| 459 | 
        return length;
     | 
  
| 460 | 
      } /*** end of CanReceivePacket ***/
     | 
  
| 461 | 
      #endif /* BOOT_COM_CAN_ENABLE > 0 || BOOT_GATE_CAN_ENABLE > 0 */  | 
  
| 462 | 
       | 
  
| 463 | 
       | 
  
| 464 | 
      /*********************************** end of can.c **************************************/
     |