📄 can_ifc.lst
字号:
C166 COMPILER V3.10b, CAN_IFC 27/11/97 13:35:46 PAGE 1
DOS C166 COMPILER V3.10b, COMPILATION OF MODULE CAN_IFC
OBJECT MODULE PLACED IN CAN_IFC.OBJ
COMPILER INVOKED BY: C:\C166EVAL\BIN\C166.EXE CAN_IFC.C CD DB M167 WL(3)
stmt level source
1 /******************************************************************************
2 C167CR CAN Ap. Note project
3 Low-level CAN functions
4
5 Copyright (c) 1997 Keil Software
6 ******************************************************************************/
7 #include <intrins.h>
8 #include "can_ifc.h"
9
10 /******************************************************************************
11 Start of CAN initialization
12
13 This function begins the process of initializing the CAN module.
14
15 It establishes the bit timing and marks all the message objects invalid.
16
17 The mask registers, and any message objects that will actually be used, must
18 be set up separately, and then end_can_init() should be called.
19
20 Returns: nothing.
21 -----------------------------------------------------------------------------*/
22 void
23 begin_can_init(void)
24 {
25 1 int object_number;
26 1
27 1 CAN_CTL_STAT = CAN_INIT_ | CAN_CCE_;
28 1
29 1 CAN_BIT_TIMING = BIT_TIMING;
30 1
31 1 /* Mark all CAN objects invalid */
32 1 for (object_number = 1; object_number <= 15; object_number++) {
33 2 CAN_MSGOBJ[object_number].msg_ctl = MSGVAL_CLR;
34 2 }
35 1 }
36
37
38 /******************************************************************************
39 End of CAN initialization
40
41 The CAN module has only a single interrupt request line and vector, for many
42 possible causes of interrupts. For each possible type of CAN interrupt, there
43 is an interrupt enable bit (EIE and SIE bits in the control/status register,
44 and TXIE and RXIE bits in the message control registers for the CAN message
45 objects). There is also an overall CAN interrupt enable (IE bit in the
46 control/status register) which must be set for the CAN module to generate any
47 interrupts.
48
49 The bit-mapped interrupt_enable_flags argument to this function controls
50 the IE, SIE, and EIE bits in the CAN control/status register.
51 The CAN_IE_, CAN_SIE_, and CAN_EIE_ macros define the relevant bits and may be
52 combined with addition ('+') or bitwise-or ('|') operators to form the argument
53 value. The TXIE and RXIE bits in the message control registers must be set
54 separately.
55
56 Returns: nothing.
57 -----------------------------------------------------------------------------*/
58 void
59 end_can_init(
C166 COMPILER V3.10b, CAN_IFC 27/11/97 13:35:46 PAGE 2
60 unsigned interrupt_enable_flags)
61 {
62 1 CAN_CTL_STAT = interrupt_enable_flags;
63 1 }
64
65
66 /******************************************************************************
67 Copy a message from a CAN object to a buffer.
68
69 This function ensures that the copied data come from a single version of the
70 message. If a new version of the message is received while the copy is in
71 progress, the function will start over, copying the new version.
72
73 The object_number argument specifies which of the 15 CAN objects (1...15) will
74 be read.
75
76 The buf argument is a pointer to the buffer the message is to be copied into.
77 Only the first n bytes of the buffer will be altered, where n is the number of
78 bytes in the data portion of the CAN message, as specified by the data length
79 code in the message configuration register (0 <= n <= 8). If you are certain
80 what the data length of the message will be, you may allocate only that many
81 bytes for the buffer. An 8-byte buffer is always adequate.
82
83 Returns: length of message data
84 -----------------------------------------------------------------------------*/
85 int
86 copy_received_can_message(
87 int object_number,
88 void *buf)
89 {
90 1 volatile struct can_obj *cano;
91 1 int length;
92 1
93 1 cano = &CAN_MSGOBJ[object_number];
94 1
95 1 /* The CAN controller can update the message while the CPU is trying to
96 1 process it. This could cause the CPU to use data that come partly
97 1 from the older message and partly from the newer message.
98 1 That could be very, very bad.
99 1 To prevent this, follow these steps:
100 1 (1) clear NEWDAT
101 1 (2) process the message (actually, just copy it to another location
102 1 for more thorough processing later)
103 1 (3) Check NEWDAT: if NEWDAT is set, it means the CAN controller has
104 1 updated the message (i.e., received a new message).
105 1 The copied message may be corrupt, so go back to step 1.
106 1 */
107 1 do {
108 2 /* Clear NEWDAT */
109 2 cano->msg_ctl = NEWDAT_CLR;
110 2
111 2 /* Copy the message.
112 2 The Data Length Code for the message is in bits 7...4 of the
113 2 message configuration register.
114 2 */
115 2 length = cano->msg_cfg >> 4;
116 2 /* If CAN_MSGOBJ[object_number] hasn't been properly initialized, the
117 2 data length code could be greater than the maximum valid value
118 2 of 8. This function shouldn't be called for an uninitialized
119 2 CAN object, but mistakes sometimes occur during development.
120 2 This inexpensive check contains the error in an easily identifiable
121 2 form, rather than allowing the excess data to overwrite whatever
122 2 follows the buffer in memory.
123 2 */
124 2 if (length > 8) {
125 3 length = 0; /* If this statement ever gets executed, you have a problem. */
C166 COMPILER V3.10b, CAN_IFC 27/11/97 13:35:46 PAGE 3
126 3 }
127 2 {
128 3 unsigned char *src;
129 3 unsigned char *dest;
130 3 unsigned char *stop;
131 3
132 3 src = cano->msg;
133 3 dest = (unsigned char *)buf;
134 3 for (stop = dest + length; dest != stop; ) {
135 4 *dest++ = *src++;
136 4 }
137 3 }
138 2 } while (cano->msg_ctl & NEWDAT_); /* Check NEWDAT */
139 1
140 1 return (length);
141 1 }
142
143
144 /******************************************************************************
145 Update a CAN transmit object with new data from a buffer.
146
147 This function ensures that a partially updated form of the message will
148 not be transmitted.
149
150 The object_number argument specifies which of the 15 CAN objects (1...15) will
151 be updated.
152
153 The buf argument is a pointer to the buffer the message is to be copied from.
154
155 The number of bytes of data to copy is specified by the length argument.
156 If length >= 0, the DLC (data length code) of the message object is changed
157 to length, and length bytes are copied.
158 If length < 0, the number of bytes to copy is read from the DLC of the message
159 object.
160 If length > 8, or length < 0 and the DLC of the message object is not correctly
161 set up, then incorrect results will occur.
162
163 Returns: length of message data
164 -----------------------------------------------------------------------------*/
165 int
166 update_can_transmit_message(
167 int object_number,
168 void *buf,
169 int length)
170 {
171 1 volatile struct can_obj *cano;
172 1
173 1 cano = &CAN_MSGOBJ[object_number];
174 1
175 1 cano->msg_ctl = NEWDAT_SET & CPUUPD_SET;
176 1
177 1 /* The Data Length Code of the message object and the variable 'length'
178 1 must match. Change one to equal the other.
179 1 The Data Length Code for the message is in bits 7...4 of the
180 1 message configuration register.
181 1 */
182 1 if (length < 0) {
183 2 /* Get length from the message object */
184 2 length = cano->msg_cfg >> 4;
185 2 }
186 1 else {
187 2 /* Set data length code in message object */
188 2 cano->msg_cfg = cano->msg_cfg & 0xf | length << 4;
189 2 }
190 1
191 1 /* Copy the data */
C166 COMPILER V3.10b, CAN_IFC 27/11/97 13:35:46 PAGE 4
192 1 {
193 2 unsigned char *src;
194 2 unsigned char *dest;
195 2 unsigned char *stop;
196 2
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -