📄 can_hw.lst
字号:
ARM COMPILER V2.32a, CAN_hw 15/03/07 08:58:24 PAGE 1
ARM COMPILER V2.32a, COMPILATION OF MODULE CAN_hw
OBJECT MODULE PLACED IN .\obj\CAN_hw.obj
COMPILER INVOKED BY: C:\Keil\ARM\BIN\CA.exe CAN_hw.c THUMB OPTIMIZE(7,SPEED) DEBUG CODE PRINT(.\LST\CAN_HW.LST) TABS(3)
-OBJECT(.\obj\CAN_hw.obj)
stmt level source
1 /*----------------------------------------------------------------------------
2 * A R T X - C A N D r i v e r - H a r d w a r e L a y e r
3 *----------------------------------------------------------------------------
4 * Name: CAN_Hw.c
5 * Purpose: CAN Driver, Hardware specific module for LPC2xxx
6 * Rev.: V0.20 / october-14-2005
7 *----------------------------------------------------------------------------
8 * This code is part of the ARTX-ARM kernel package of Keil Software.
9 * Copyright (c) 2004-2005 Keil Software. All rights reserved.
10 *---------------------------------------------------------------------------*/
11
12 #include <ARTX.h> /* ARTX kernel functions & defines */
13 #include <LPC21xx.h> /* LPC21xx definitions */
14 #include "ARTX_CAN.h" /* CAN Generic functions & defines */
15 #include "CAN_hw.h" /* CAN hw specific functions & defines */
16 #include "CAN_reg.h" /* LPC2xxx CAN registers */
17
18 /* Values of bit time register for different baudrates
19 NT = Nominal bit time = TSEG1 + TSEG2 + 3
20 SP = Sample point = ((TSEG2 +1) / (TSEG1 + TSEG2 + 3)) * 100%
21 SAM, SJW, TSEG1, TSEG2, NT, SP */
22 const U32 CAN_BIT_TIME[] = { 0, /* not used */
23 0, /* not used */
24 0, /* not used */
25 0, /* not used */
26 0x0001C000, /* 0+1, 3+1, 1+1, 0+1, 4, 75% */
27 0, /* not used */
28 0x0012C000, /* 0+1, 3+1, 2+1, 1+1, 6, 67% */
29 0, /* not used */
30 0x0023C000, /* 0+1, 3+1, 3+1, 2+1, 8, 63% */
31 0, /* not used */
32 0x0025C000, /* 0+1, 3+1, 5+1, 2+1, 10, 70% */
33 0, /* not used */
34 0x0036C000, /* 0+1, 3+1, 6+1, 3+1, 12, 67% */
35 0, /* not used */
36 0, /* not used */
37 0x0048C000, /* 0+1, 3+1, 8+1, 4+1, 15, 67% */
38 0x0049C000, /* 0+1, 3+1, 9+1, 4+1, 16, 69% */
39 };
40
41
42 /*----------------------------------------------------------------------------
43 * CAN ARTX Hardware Specific Driver Functions for LPC2xxx
44 *----------------------------------------------------------------------------
45 * Functions implemented in this module:
46 * CAN_ERROR CAN_hw_setup (void)
47 * static U32 CAN_calc_baudrate (U32 baudrate)
48 * CAN_ERROR CAN_hw_init (U32 ctrl, U32 baudrate)
49 * CAN_ERROR CAN_hw_start (U32 ctrl)
50 * CAN_ERROR CAN_hw_tx_empty (U32 ctrl)
51 * CAN_ERROR CAN_hw_wr (U32 ctrl, CAN_msg *msg)
52 * static void CAN_hw_rd (U32 ctrl, CAN_msg *msg)
53 * CAN_ERROR CAN_hw_set (U32 ctrl, CAN_msg *msg)
54 * CAN_ERROR CAN_hw_rx_object (U32 ctrl, U32 ch, U32 id, CAN_FORMAT format)
55 * CAN_ERROR CAN_hw_tx_object (U32 ctrl, U32 ch, CAN_FORMAT format)
56 * Interrupt fuctions
57 *---------------------------------------------------------------------------*/
58
ARM COMPILER V2.32a, CAN_hw 15/03/07 08:58:24 PAGE 2
59 /* Static functions used only in this module */
60 static U32 CAN_calc_baudrate (U32 baudrate);
61 static void CAN_hw_rd (U32 ctrl, CAN_msg *msg);
62 static void CAN_TX1_ISR (void) __irq;
63 static void CAN_RX1_ISR (void) __irq;
64 static void CAN_TX2_ISR (void) __irq;
65 static void CAN_RX2_ISR (void) __irq;
66 static void CAN_TX3_ISR (void) __irq;
67 static void CAN_RX3_ISR (void) __irq;
68 static void CAN_TX4_ISR (void) __irq;
69 static void CAN_RX4_ISR (void) __irq;
70
71
72 /*--------------------------- CAN_hw_setup ----------------------------------
73 *
74 * Setup CAN transmit and receive PINs and interrupt vectors
75 *
76 * Parameter: none
77 *
78 * Return: CAN_ERROR: Error code
79 *---------------------------------------------------------------------------*/
80
81 CAN_ERROR CAN_hw_setup (void) {
82 1 #if USE_CAN_CTRL1 == 1
83 1 PINSEL1 &= 0xFFEBFFFF; /* Reset CAN1 bits */
84 1 PINSEL1 |= 0x00040000; /* Set CAN1 bits to 01 */
85 1
86 1 /* Set interrupt vector for Tx1 */
87 1 *(&VICVectAddr0 + VIC_NUM_CTRL1_TX) = (unsigned long) CAN_TX1_ISR;
88 1 *(&VICVectCntl0 + VIC_NUM_CTRL1_TX) = 0x20 | 20;
89 1 /* Set interrupt vector for Rx1 */
90 1 *(&VICVectAddr0 + VIC_NUM_CTRL1_RX) = (unsigned long) CAN_RX1_ISR;
91 1 *(&VICVectCntl0 + VIC_NUM_CTRL1_RX) = 0x20 | 26;
92 1
93 1 VICIntEnable = 0x04100000; /* Enable CAN Tx1 and Rx1 Interrupt */
94 1 #endif
95 1 #if USE_CAN_CTRL2 == 1
96 1 PINSEL1 &= 0xFFFC3FFF; /* Reset CAN2 bits */
97 1 PINSEL1 |= 0x00014000; /* Set CAN2 bits to 11 */
98 1
99 1 /* Set interrupt vector for Tx2 */
100 1 *(&VICVectAddr0 + VIC_NUM_CTRL2_TX) = (unsigned long) CAN_TX2_ISR;
101 1 *(&VICVectCntl0 + VIC_NUM_CTRL2_TX) = 0x20 | 21;
102 1 /* Set interrupt vector for Rx2 */
103 1 *(&VICVectAddr0 + VIC_NUM_CTRL2_RX) = (unsigned long) CAN_RX2_ISR;
104 1 *(&VICVectCntl0 + VIC_NUM_CTRL2_RX) = 0x20 | 27;
105 1
106 1 VICIntEnable = 0x08200000; /* Enable CAN Tx2 and Rx2 Interrupt */
107 1 #endif
108 1 #if USE_CAN_CTRL3 == 1
PINSEL1 &= 0xFFFFC3FF; /* Reset CAN3 bits */
PINSEL1 |= 0x00001800; /* Set CAN3 bits to 11 */
/* Set interrupt vector for Tx3 */
*(&VICVectAddr0 + VIC_NUM_CTRL3_TX) = (unsigned long) CAN_TX3_ISR;
*(&VICVectCntl0 + VIC_NUM_CTRL3_TX) = 0x20 | 22;
/* Set interrupt vector for Rx3 */
*(&VICVectAddr0 + VIC_NUM_CTRL3_RX) = (unsigned long) CAN_RX3_ISR;
*(&VICVectCntl0 + VIC_NUM_CTRL3_RX) = 0x20 | 28;
VICIntEnable = 0x10400000; /* Enable CAN Tx3 and Rx3 Interrupt */
#endif
121 1 #if USE_CAN_CTRL4 == 1
PINSEL0 &= 0xF0FFFFFF; /* Reset CAN4 bits */
PINSEL0 |= 0x0F000000; /* Set CAN4 bits to 1111 */
ARM COMPILER V2.32a, CAN_hw 15/03/07 08:58:24 PAGE 3
/* Set interrupt vector for Tx4 */
*(&VICVectAddr0 + VIC_NUM_CTRL4_TX) = (unsigned long) CAN_TX4_ISR;
*(&VICVectCntl0 + VIC_NUM_CTRL4_TX) = 0x20 | 23;
/* Set interrupt vector for Rx4 */
*(&VICVectAddr0 + VIC_NUM_CTRL4_RX) = (unsigned long) CAN_RX4_ISR;
*(&VICVectCntl0 + VIC_NUM_CTRL4_RX) = 0x20 | 29;
VICIntEnable = 0x20800000; /* Enable CAN Tx4 and Rx4 Interrupt */
#endif
134 1
135 1 return CAN_OK;
136 1 }
137
138
139 /*--------------------------- CAN_calc_baudrate -----------------------------
140 *
141 * Calculate baudrate register value for requested baudrate
142 *
143 * Parameter: baudrate: Baudrate
144 *
145 * Return: U32: Bitrate register value
146 *---------------------------------------------------------------------------*/
147
148 static U32 CAN_calc_baudrate (U32 baudrate) {
149 1 U32 result = 0;
150 1 U32 nominal_time;
151 1
152 1 /* Determine which nominal time to use for PCLK and baudrate */
153 1 if (baudrate <= 500000) {
154 2 nominal_time = 12;
155 2 } else if (((PCLK / 1000000) % 15) == 0) {
156 2 nominal_time = 15;
157 2 } else if (((PCLK / 1000000) % 16) == 0) {
158 2 nominal_time = 16;
159 2 } else {
160 2 nominal_time = 10;
161 2 }
162 1
163 1 /* Prepare value appropriate for bit time register */
164 1 result = (PCLK / nominal_time) / baudrate - 1;
165 1 result &= 0x000003FF;
166 1 result |= CAN_BIT_TIME[nominal_time];
167 1
168 1 return result;
169 1 }
170
171
172 /*--------------------------- CAN_hw_init -----------------------------------
173 *
174 * Initialize the CAN hardware
175 *
176 * Parameter: ctrl: Index of the hardware CAN controller (1 .. x)
177 * baudrate: Baudrate
178 *
179 * Return: CAN_ERROR: Error code
180 *---------------------------------------------------------------------------*/
181
182 CAN_ERROR CAN_hw_init (U32 ctrl, U32 baudrate) {
183 1 U32 ctrl0 = ctrl-1; /* Controller index 0 .. x-1 */
184 1 regCAN_AF *ptrcan_af = CAN_AF_BASE;
185 1 regCAN *ptrcan = (regCAN *) CAN_BASE[ctrl0];
186 1
187 1 ptrcan_af->AFMR = 1; /* Disable acceptance filter */
188 1 ptrcan->CANMOD = 1; /* Enter reset mode */
189 1 ptrcan->CANIER = 0; /* Disable all interrupts */
190 1 ptrcan->CANGSR = 0; /* Clear status register */
ARM COMPILER V2.32a, CAN_hw 15/03/07 08:58:24 PAGE 4
191 1 ptrcan->CANBTR = CAN_calc_baudrate(baudrate); /* Set bit timing */
192 1 ptrcan->CANIER = 0x0603; /* Enable Tx and Rx interrupt */
193 1
194 1 return CAN_OK;
195 1 }
196
197
198 /*--------------------------- CAN_hw_start ----------------------------------
199 *
200 * Enable the CAN interrupts (recive or/and transmit)
201 *
202 * Parameter: ctrl: Index of the hardware CAN controller (1 .. x)
203 *
204 * Return: CAN_ERROR: Error code
205 *---------------------------------------------------------------------------*/
206
207 CAN_ERROR CAN_hw_start (U32 ctrl) {
208 1 U32 ctrl0 = ctrl-1; /* Controller index 0 .. x-1 */
209 1 regCAN *ptrcan = (regCAN *) CAN_BASE[ctrl0];
210 1
211 1 ptrcan->CANMOD = 0; /* Enter normal operating mode */
212 1
213 1 return CAN_OK;
214 1 }
215
216
217 /*--------------------------- CAN_hw_tx_empty -------------------------------
218 *
219 * Check if controller is available for transmission
220 *
221 * Parameter: ctrl: Index of the hardware CAN controller (1 .. x)
222 *
223 * Return: CAN_ERROR: Error code
224 *---------------------------------------------------------------------------*/
225
226 CAN_ERROR CAN_hw_tx_empty (U32 ctrl) {
227 1 U32 ctrl0 = ctrl-1; /* Controller index 0 .. x-1 */
228 1 regCAN *ptrcan = (regCAN *) CAN_BASE[ctrl0];
229 1
230 1 if (!(ptrcan->CANSR & 0x00000004)) /* Transmitter 1 busy */
231 1 return CAN_TX_BUSY_ERROR;
232 1
233 1 return CAN_OK;
234 1 }
235
236
237 /*--------------------------- CAN_hw_wr -------------------------------------
238 *
239 * Write CAN_msg to the hardware registers of the requested controller
240 *
241 * Parameter: ctrl: Index of the hardware CAN controller (1 .. x)
242 * msg: Pointer to CAN message to be written to hardware
243 *
244 * Return: CAN_ERROR: Error code
245 *---------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -