📄 can_ifc.lst
字号:
197 2 src = (unsigned char *)buf;
198 2 dest = cano->msg;
199 2 for (stop = dest + length; dest != stop; ) {
200 3 *dest++ = *src++;
201 3 }
202 2 }
203 1
204 1 cano->msg_ctl = CPUUPD_CLR;
205 1
206 1 return (length);
207 1 }
208
209
210 /******************************************************************************
211 CAN interrupt handler
212
213 There is a single interrupt vector for all interrupts generated by the on-chip
214 CAN module. The INTID field of the CAN interrupt register (CAN_INTID)
215 identifies what caused the interrupt. Several interrupt-causing conditions can
216 exist at once, but the INTID field will reveal only one of these at a time.
217 The values of INTID and their corresponding interrupt causes are:
218
219 0: no interrupt pending
220 1: status change interrupt
221 2: message 15 interrupt
222 2+N: message N (1 <= N <= 14) interrupt
223
224 When several interrupt conditions exist, the one associated with the lowest
225 value of INTID (other than 0) takes precedence, i.e., its value appears in
226 the INTID field. Once this interrupt has been cleared, the next interrupt
227 source has its value appear in INTID. You must clear all interrupt sources
228 for the CAN module (i.e., get INTID to 0) before returning from the interrupt
229 handler or no further CAN interrupts will be generated.
230
231
232 Since this example program doesn't use CAN message interrupts, this function
233 doesn't really need to have any code to deal with them. Absolute minimal
234 message interrupt handling is provided for the benefit of people who want
235 to use this program as a skeleton for more elaborate CAN programs. Of course,
236 this skeleton may be anatomically unfit for your project.
237
238 -----------------------------------------------------------------------------*/
239 void
240 can_interrupt(void) interrupt 0x40
241 {
242 1 unsigned char interrupt_id;
243 1 int message_number;
244 1
245 1 while (1) {
246 2 switch (interrupt_id = CAN_INTID) {
247 3
248 3 case 0 : /* no interrupt */
249 3 return;
250 3
251 3 case 1 : /* status change interrupt */
252 3 /* Interrupts associated with changes in the CAN status register
253 3 are handled here.
254 3
255 3 Reading the status register clears this interrupt condition.
256 3
257 3 If the SIE bit of the CAN control register is set, an interrupt is
C166 COMPILER V3.10b, CAN_IFC 27/11/97 13:35:46 PAGE 5
258 3 generated when the CAN controller updates the LEC field of the CAN
259 3 status register.
260 3
261 3 If the EIE bit of the CAN control register is set, an interrupt is
262 3 generated when the CAN controller changes the BOFF or EWRN bits in
263 3 the CAN status register.
264 3
265 3 The only one of these interrupts we are interested in for this
266 3 program is a change in the BOFF (Bus Off) bit.
267 3 */
268 3 { /* Bus Off recovery */
269 4 /* During bus off recovery, busoff_recovery_state contains the
270 4 (non-zero) value to write into the CAN control register when
271 4 recovery is complete. At all other times, it contains 0.
272 4 */
273 4 static unsigned char busoff_recovery_state;
274 4 unsigned char boff; /* reading of BOFF bit in status reg */
275 4
276 4 if ((boff = CAN_STAT & CAN_BOFF_) && busoff_recovery_state == 0) {
277 5 /* Bus off condition just occurred. */
278 5 /* When Bus Off occurrs, the CAN module sets the BOFF and INIT
279 5 bits in its control/status register. It begins the bus off
280 5 recovery sequence when the CPU clears the INIT bit.
281 5
282 5 Remember the current value in the CAN control register so we
283 5 can restore it later. (Except the INIT bit; it will always
284 5 be set at this point, and we will always want to restore it
285 5 cleared.)
286 5
287 5 Clear INIT bit to start bus off recovery, and clear SIE (if
288 5 it were set) to disable SIE-controlled status change
289 5 interrupts. They are of no interest to us while the bus off
290 5 condition exists.
291 5 */
292 5 busoff_recovery_state = CAN_CTL & ~CAN_INIT_;
293 5 CAN_CTL = CAN_EIE_ | CAN_IE_;
294 5 }
295 4 else if (busoff_recovery_state && !boff) {
296 5 /* Bus off recovery just completed */
297 5 CAN_CTL = busoff_recovery_state; /* Restore control register from before bus off */
298 5 busoff_recovery_state = 0; /* No longer in bus off recovery */
299 5 }
300 4 }
301 3 break;
302 3
303 3 case 2 : /* message 15 interrupt */
304 3 message_number = 15;
305 3 goto handle_message_interrupt;
306 3
307 3 default : /* other message interrupts */
308 3 message_number = interrupt_id - 2;
309 3 handle_message_interrupt:
310 3 /* Clear the INTPND (interrupt pending) bit in the message control
311 3 register for the message object.
312 3
313 3 For most applications, you will probably need to do more than this,
314 3 and you probably need to do different things for different
315 3 messages. But you will always need to do this.
316 3 */
317 3 CAN_MSGOBJ[message_number].msg_ctl = INTPND_CLR;
318 3 break;
319 3 }
320 2 }
321 1 }
C166 COMPILER V3.10b, CAN_IFC 27/11/97 13:35:46 PAGE 6
ASSEMBLY LISTING OF GENERATED OBJECT CODE
; FUNCTION begin_can_init (BEGIN RMASK = @0x4070)
; SOURCE LINE # 23
; SOURCE LINE # 24
; SOURCE LINE # 27
0000 E6F44100 MOV R4,#041H
0004 F6F400EF MOV 0EF00H,R4
; SOURCE LINE # 29
0008 E6F44024 MOV R4,#02440H
000C F6F404EF MOV 0EF04H,R4
; SOURCE LINE # 32
0010 E016 MOV R6,#01H
;---- Variable 'object_number' assigned to Register 'R6' ----
0012 E6F57FFF MOV R5,#0FF7FH
0016 ?C0004:
; SOURCE LINE # 33
0016 F046 MOV R4,R6
0018 5C44 SHL R4,#04H
001A C45400EF MOV [R4+#0EF00H],R5
; SOURCE LINE # 34
001E 80E6 CMPI1 R6,#0EH
0020 BDFA JMPR cc_SLE,?C0004
0022 ?C0002:
; SOURCE LINE # 35
0022 CB00 RET
; FUNCTION begin_can_init (END RMASK = @0x4070)
; FUNCTION end_can_init (BEGIN RMASK = @0x4000)
; SOURCE LINE # 59
;---- Variable 'interrupt_enable_flags' assigned to Register 'R8' ----
; SOURCE LINE # 62
0024 F6F800EF MOV 0EF00H,R8
; SOURCE LINE # 63
0028 CB00 RET
; FUNCTION end_can_init (END RMASK = @0x4000)
; FUNCTION copy_received_can_message (BEGIN RMASK = @0x4DF0)
; SOURCE LINE # 86
;---- Variable 'buf' assigned to Register 'R9' ----
;---- Variable 'object_number' assigned to Register 'R8' ----
; SOURCE LINE # 89
; SOURCE LINE # 93
002A F058 MOV R5,R8
002C 5C45 SHL R5,#04H
002E E6FA00EF MOV R10,#0EF00H
0032 00A5 ADD R10,R5
;---- Variable 'cano' assigned to Register 'R10' ----
; SOURCE LINE # 107
0034 ?C0006:
; SOURCE LINE # 109
0034 E6F5FFFD MOV R5,#0FDFFH
0038 B85A MOV [R10],R5
; SOURCE LINE # 115
003A F48A0600 MOVB RL4,[R10+#06H]
003E C084 MOVBZ R4,RL4
0040 7C44 SHR R4,#04H
0042 C088 MOVBZ R8,RL4
;---- Variable 'length' assigned to Register 'R8' ----
; SOURCE LINE # 124
0044 46F80800 CMP R8,#08H
0048 BD01 JMPR cc_SLE,?C0010
; SOURCE LINE # 125
004A E008 MOV R8,#00H
; SOURCE LINE # 126
C166 COMPILER V3.10b, CAN_IFC 27/11/97 13:35:46 PAGE 7
004C ?C0010:
; SOURCE LINE # 127
; SOURCE LINE # 132
004C F0BA MOV R11,R10
004E 08B7 ADD R11,#07H
;---- Variable 'src' assigned to Register 'R11' ----
; SOURCE LINE # 133
0050 F079 MOV R7,R9
;---- Variable 'dest' assigned to Register 'R7' ----
; SOURCE LINE # 134
0052 F049 MOV R4,R9
0054 0048 ADD R4,R8
;---- Variable 'stop' assigned to Register 'R4' ----
0056 0D04 JMPR cc_UC,?C0013
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -