Statistics
| Branch: | Tag: | Revision:

amiro-blt / Target / Source / ARMCM3_STM32 / can.c @ 7737db33

History | View | Annotate | Download (24.263 KB)

1 69661903 Thomas Schöpping
/************************************************************************************//**
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 d54d2f07 Thomas Schöpping
* 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 69661903 Thomas Schöpping
* proprietary components. The exception text is included at the bottom of the license
29
* file <license.html>.
30 d54d2f07 Thomas Schöpping
*
31 69661903 Thomas Schöpping
* \endinternal
32
****************************************************************************************/
33
34 d54d2f07 Thomas Schöpping
#define CAN_DEBUG       (0)
35 69661903 Thomas Schöpping
36
/****************************************************************************************
37
* Include files
38
****************************************************************************************/
39
#include "boot.h"                                /* bootloader generic header          */
40
41 d54d2f07 Thomas Schöpping
#if (CAN_DEBUG > 0)
42
#include <helper.h>
43
#endif
44
45 69661903 Thomas Schöpping
46
#if (BOOT_COM_CAN_ENABLE > 0 || BOOT_GATE_CAN_ENABLE > 0)
47
/****************************************************************************************
48
* Type definitions
49
****************************************************************************************/
50
/** \brief CAN transmission mailbox layout. */
51
typedef struct
52
{
53
  volatile blt_int32u TIR;
54
  volatile blt_int32u TDTR;
55
  volatile blt_int32u TDLR;
56
  volatile blt_int32u TDHR;
57
} tCanTxMailBox;
58
59
/** \brief CAN reception FIFO mailbox layout. */
60
typedef struct
61
{
62
  volatile blt_int32u RIR;
63
  volatile blt_int32u RDTR;
64
  volatile blt_int32u RDLR;
65
  volatile blt_int32u RDHR;
66 d54d2f07 Thomas Schöpping
} tCanRxFIFOMailBox;
67 69661903 Thomas Schöpping
68
/** \brief CAN filter register layout. */
69
typedef struct
70
{
71
  volatile blt_int32u FR1;
72
  volatile blt_int32u FR2;
73
} tCanFilter;
74
75
/** \brief CAN controller register layout. */
76
typedef struct
77
{
78
  volatile blt_int32u MCR;
79
  volatile blt_int32u MSR;
80
  volatile blt_int32u TSR;
81
  volatile blt_int32u RF0R;
82
  volatile blt_int32u RF1R;
83
  volatile blt_int32u IER;
84
  volatile blt_int32u ESR;
85
  volatile blt_int32u BTR;
86
  blt_int32u          RESERVED0[88];
87
  tCanTxMailBox       sTxMailBox[3];
88
  tCanRxFIFOMailBox   sFIFOMailBox[2];
89
  blt_int32u          RESERVED1[12];
90
  volatile blt_int32u FMR;
91
  volatile blt_int32u FM1R;
92
  blt_int32u          RESERVED2;
93
  volatile blt_int32u FS1R;
94
  blt_int32u          RESERVED3;
95
  volatile blt_int32u FFA1R;
96
  blt_int32u          RESERVED4;
97
  volatile blt_int32u FA1R;
98
  blt_int32u          RESERVED5[8];
99
  tCanFilter          sFilterRegister[14];
100 d54d2f07 Thomas Schöpping
} tCanRegs;
101 69661903 Thomas Schöpping
102
103
/****************************************************************************************
104
* Macro definitions
105
****************************************************************************************/
106
/** \brief Reset request bit. */
107
#define CAN_BIT_RESET    ((blt_int32u)0x00008000)
108
/** \brief Initialization request bit. */
109
#define CAN_BIT_INRQ     ((blt_int32u)0x00000001)
110
/** \brief Initialization acknowledge bit. */
111
#define CAN_BIT_INAK     ((blt_int32u)0x00000001)
112
/** \brief Sleep mode request bit. */
113
#define CAN_BIT_SLEEP    ((blt_int32u)0x00000002)
114
/** \brief Filter 0 selection bit. */
115
#define CAN_BIT_FILTER0  ((blt_int32u)0x00000001)
116
/** \brief Filter init mode bit. */
117
#define CAN_BIT_FINIT    ((blt_int32u)0x00000001)
118
/** \brief Transmit mailbox 0 empty bit. */
119
#define CAN_BIT_TME0     ((blt_int32u)0x04000000)
120
/** \brief Transmit mailbox request bit. */
121
#define CAN_BIT_TXRQ     ((blt_int32u)0x00000001)
122
/** \brief Release FIFO 0 mailbox bit. */
123
#define CAN_BIT_RFOM0    ((blt_int32u)0x00000020)
124
125
#if (BOOT_GATE_CAN_ENABLE > 0)
126
blt_bool commandSend;
127
#endif /* BOOT_GATE_CAN_ENABLE > 0 */
128
129
130
/****************************************************************************************
131
* Register definitions
132
****************************************************************************************/
133
/** \brief Macro for accessing CAN controller registers. */
134
#define CANx             ((tCanRegs *) (blt_int32u)0x40006400)
135
136
137
/****************************************************************************************
138
* Type definitions
139
****************************************************************************************/
140
/** \brief Structure type for grouping CAN bus timing related information. */
141
typedef struct t_can_bus_timing
142
{
143
  blt_int8u tseg1;                                    /**< CAN time segment 1          */
144
  blt_int8u tseg2;                                    /**< CAN time segment 2          */
145
} tCanBusTiming;
146
147
148
/****************************************************************************************
149
* Local constant declarations
150
****************************************************************************************/
151
/** \brief CAN bittiming table for dynamically calculating the bittiming settings.
152 d54d2f07 Thomas Schöpping
 *  \details According to the CAN protocol 1 bit-time can be made up of between 8..25
153
 *           time quanta (TQ). The total TQ in a bit is SYNC + TSEG1 + TSEG2 with SYNC
154
 *           always being 1. The sample point is (SYNC + TSEG1) / (SYNC + TSEG1 + SEG2) *
155 69661903 Thomas Schöpping
 *           100%. This array contains possible and valid time quanta configurations with
156
 *           a sample point between 68..78%.
157
 */
158
static const tCanBusTiming canTiming[] =
159
{                       /*  TQ | TSEG1 | TSEG2 | SP  */
160
                        /* ------------------------- */
161
    {  5, 2 },          /*   8 |   5   |   2   | 75% */
162
    {  6, 2 },          /*   9 |   6   |   2   | 78% */
163
    {  6, 3 },          /*  10 |   6   |   3   | 70% */
164
    {  7, 3 },          /*  11 |   7   |   3   | 73% */
165
    {  8, 3 },          /*  12 |   8   |   3   | 75% */
166
    {  9, 3 },          /*  13 |   9   |   3   | 77% */
167
    {  9, 4 },          /*  14 |   9   |   4   | 71% */
168
    { 10, 4 },          /*  15 |  10   |   4   | 73% */
169
    { 11, 4 },          /*  16 |  11   |   4   | 75% */
170
    { 12, 4 },          /*  17 |  12   |   4   | 76% */
171
    { 12, 5 },          /*  18 |  12   |   5   | 72% */
172
    { 13, 5 },          /*  19 |  13   |   5   | 74% */
173
    { 14, 5 },          /*  20 |  14   |   5   | 75% */
174
    { 15, 5 },          /*  21 |  15   |   5   | 76% */
175
    { 15, 6 },          /*  22 |  15   |   6   | 73% */
176
    { 16, 6 },          /*  23 |  16   |   6   | 74% */
177
    { 16, 7 },          /*  24 |  16   |   7   | 71% */
178
    { 16, 8 }           /*  25 |  16   |   8   | 68% */
179
};
180
181
182
/************************************************************************************//**
183 d54d2f07 Thomas Schöpping
** \brief     Search algorithm to match the desired baudrate to a possible bus
184 69661903 Thomas Schöpping
**            timing configuration.
185
** \param     baud The desired baudrate in kbps. Valid values are 10..1000.
186
** \param     prescaler Pointer to where the value for the prescaler will be stored.
187
** \param     tseg1 Pointer to where the value for TSEG2 will be stored.
188
** \param     tseg2 Pointer to where the value for TSEG2 will be stored.
189 d54d2f07 Thomas Schöpping
** \return    BLT_TRUE if the CAN bustiming register values were found, BLT_FALSE
190 69661903 Thomas Schöpping
**            otherwise.
191
**
192
****************************************************************************************/
193 d54d2f07 Thomas Schöpping
static blt_bool CanGetSpeedConfig(blt_int16u baud, blt_int16u *prescaler,
194 69661903 Thomas Schöpping
                                  blt_int8u *tseg1, blt_int8u *tseg2)
195
{
196
  blt_int8u  cnt;
197
198
  /* loop through all possible time quanta configurations to find a match */
199
  for (cnt=0; cnt < sizeof(canTiming)/sizeof(canTiming[0]); cnt++)
200
  {
201
    if (((BOOT_CPU_SYSTEM_SPEED_KHZ/2) % (baud*(canTiming[cnt].tseg1+canTiming[cnt].tseg2+1))) == 0)
202
    {
203
      /* compute the prescaler that goes with this TQ configuration */
204
      *prescaler = (BOOT_CPU_SYSTEM_SPEED_KHZ/2)/(baud*(canTiming[cnt].tseg1+canTiming[cnt].tseg2+1));
205
206
      /* make sure the prescaler is valid */
207
      if ( (*prescaler > 0) && (*prescaler <= 1024) )
208
      {
209
        /* store the bustiming configuration */
210
        *tseg1 = canTiming[cnt].tseg1;
211
        *tseg2 = canTiming[cnt].tseg2;
212
        /* found a good bus timing configuration */
213
        return BLT_TRUE;
214
      }
215
    }
216
  }
217
  /* could not find a good bus timing configuration */
218
  return BLT_FALSE;
219
} /*** end of CanGetSpeedConfig ***/
220
221
222
/************************************************************************************//**
223
** \brief     Initializes the CAN controller and synchronizes it to the CAN bus.
224
** \return    none.
225
**
226
****************************************************************************************/
227
void CanInit(void)
228