📄 scc_m515.lst
字号:
278 /*------------------------------------------------------------------*-
279
280 SCC_A_MASTER_Start()
281
282 Starts the scheduler, by enabling interrupts.
283
284 NOTE: Usually called after all regular tasks are added,
285 to keep the tasks synchronised.
286
287 NOTE: ONLY THE SCHEDULER INTERRUPT SHOULD BE ENABLED!!!
288
289 -*------------------------------------------------------------------*/
290 void SCC_A_MASTER_Start(void)
291 {
292 1 tByte Num_active_slaves;
293 1 tByte i;
294 1 bit Slave_replied_correctly;
295 1 tByte Slave_index, Slave_ID;
296 1
297 1 // Refresh the watchdog
298 1 SCC_A_MASTER_Watchdog_Refresh();
299 1
300 1 // Place system in 'safe state'
301 1 SCC_A_MASTER_Enter_Safe_State();
302 1
303 1 // Report error as we wait to start
304 1 Network_error_pin = NETWORK_ERROR;
305 1
306 1 Error_code_G = ERROR_SCH_WAITING_FOR_SLAVE_TO_ACK;
307 1 SCH_Report_Status(); // Sch not yet running - do this manually
308 1
309 1 // Pause here (300 ms), to time-out all the slaves
310 1 // (This is the means by which we synchronise the network)
311 1 for (i = 0; i < 10; i++)
312 1 {
313 2 Hardware_Delay_T0(30);
C51 COMPILER V6.10 SCC_M515 04/19/2001 14:10:31 PAGE 20
314 2 SCC_A_MASTER_Watchdog_Refresh();
315 2 }
316 1
317 1 // Currently disconnected from all slaves
318 1 Num_active_slaves = 0;
319 1
320 1 // After the initial (long) delay, all (operational) slaves will have timed out.
321 1 // All operational slaves will now be in the 'READY TO START' state
322 1 // Send them a 'slave id' message to get them started
323 1 Slave_index = 0;
324 1 do {
325 2 // Refresh the watchdog
326 2 SCC_A_MASTER_Watchdog_Refresh();
327 2
328 2 // Find the slave ID for this slave
329 2 Slave_ID = (tByte) Current_Slave_IDs_G[Slave_index];
330 2
331 2 Slave_replied_correctly = SCC_A_MASTER_Start_Slave(Slave_ID);
332 2
333 2 if (Slave_replied_correctly)
334 2 {
335 3 Num_active_slaves++;
336 3 Slave_index++;
337 3 }
338 2 else
339 2 {
340 3 // Slave did not reply correctly
341 3 // - try to switch to backup device (if available)
342 3 if (Current_Slave_IDs_G[Slave_index] != BACKUP_SLAVE_IDs[Slave_index])
343 3 {
344 4 // There is a backup available: switch to backup and try again
345 4 Current_Slave_IDs_G[Slave_index] = BACKUP_SLAVE_IDs[Slave_index];
346 4 }
347 3 else
348 3 {
349 4 // No backup available (or backup failed too) - have to continue
350 4 Slave_index++;
351 4 }
352 3 }
353 2 } while (Slave_index < NUMBER_OF_SLAVES);
354 1
355 1 // DEAL WITH CASE OF MISSING SLAVE(S) HERE ...
356 1 if (Num_active_slaves < NUMBER_OF_SLAVES)
357 1 {
358 2 // User-defined error handling here...
359 2 // 1 or more slaves have not replied
360 2 // NOTE: In some circumstances you may wish to abort if slaves are missing
361 2 // - or reconfigure the network.
362 2
363 2 // Simplest solution is to display an error and carry on
364 2 // (this is what we do here)
365 2 Error_code_G = ERROR_SCH_ONE_OR_MORE_SLAVES_DID_NOT_START;
366 2 Network_error_pin = NETWORK_ERROR;
367 2 }
368 1 else
369 1 {
370 2 Error_code_G = 0;
371 2 Network_error_pin = NO_NETWORK_ERROR;
372 2 }
373 1
374 1 // Start the scheduler
375 1 IRCON = 0;
C51 COMPILER V6.10 SCC_M515 04/19/2001 14:10:31 PAGE 21
376 1 EAL = 1;
377 1 }
378
379 /*------------------------------------------------------------------*-
380
381 SCC_A_MASTER_Update_T2
382
383 This is the scheduler ISR. It is called at a rate determined by
384 the timer settings in SCC_A_MASTER_Init_T2(). This version is
385 triggered by Timer 2 interrupts: timer is automatically reloaded.
386
387 -*------------------------------------------------------------------*/
388 void SCC_A_MASTER_Update_T2(void) interrupt INTERRUPT_Timer_2_Overflow
389 {
390 1 tByte Index;
391 1 tByte Previous_slave_index;
392 1 bit Slave_replied_correctly;
393 1
394 1 TF2 = 0; // Must clear this.
395 1
396 1 // Refresh the watchdog
397 1 SCC_A_MASTER_Watchdog_Refresh();
398 1
399 1 // Default
400 1 Network_error_pin = NO_NETWORK_ERROR;
401 1
402 1 // Keep track of the current slave
403 1 Previous_slave_index = Slave_index_G; // First value of prev slave is 0...
404 1
405 1 if (++Slave_index_G >= NUMBER_OF_SLAVES)
406 1 {
407 2 Slave_index_G = 0;
408 2 }
409 1
410 1 // Check that the appropriate slave responded to the previous message:
411 1 // (if it did, store the data sent by this slave)
412 1 if (SCC_A_MASTER_Process_Ack(Previous_slave_index) == RETURN_ERROR)
413 1 {
414 2 Error_code_G = ERROR_SCH_LOST_SLAVE;
415 2 Network_error_pin = NETWORK_ERROR;
416 2
417 2 // If we have lost contact with a slave, we attempt to
418 2 // switch to a backup device (if one is available)
419 2 if (Current_Slave_IDs_G[Slave_index_G] != BACKUP_SLAVE_IDs[Slave_index_G])
420 2 {
421 3 // There is a backup available: switch to backup and try again
422 3 Current_Slave_IDs_G[Slave_index_G] = BACKUP_SLAVE_IDs[Slave_index_G];
423 3 }
424 2 else
425 2 {
426 3 // There is no backup available (or we are already using it)
427 3 // Try main device.
428 3 Current_Slave_IDs_G[Slave_index_G] = MAIN_SLAVE_IDs[Slave_index_G];
429 3 }
430 2
431 2 // Try to connect to the slave
432 2 Slave_replied_correctly = SCC_A_MASTER_Start_Slave(Current_Slave_IDs_G[Slave_index_G]);
433 2
434 2 if (!Slave_replied_correctly)
435 2 {
436 3 // No backup available (or backup failed too) - we shut down
437 3 // OTHER BEHAVIOUR MAY BE MORE APPROPRIATE IN YOUR APPLICATION
C51 COMPILER V6.10 SCC_M515 04/19/2001 14:10:31 PAGE 22
438 3 SCC_A_MASTER_Shut_Down_the_Network();
439 3 }
440 2 }
441 1
442 1 // Send 'tick' message to all connected slaves
443 1 // (sends one data byte to the current slave)
444 1 SCC_A_MASTER_Send_Tick_Message(Slave_index_G);
445 1
446 1 // Check the last error codes on the CAN bus via the status register
447 1 if ((CAN_sr & 0x07) != 0)
448 1 {
449 2 Error_code_G = ERROR_SCH_CAN_BUS_ERROR;
450 2 Network_error_pin = NETWORK_ERROR;
451 2
452 2 // See Infineon c515c manual for error code details
453 2 CAN_error_pin0 = ((CAN_sr & 0x01) == 0);
454 2 CAN_error_pin1 = ((CAN_sr & 0x02) == 0);
455 2 CAN_error_pin2 = ((CAN_sr & 0x04) == 0);
456 2 }
457 1 else
458 1 {
459 2 CAN_error_pin0 = 1;
460 2 CAN_error_pin1 = 1;
461 2 CAN_error_pin2 = 1;
462 2 }
463 1
464 1 // NOTE: calculations are in *TICKS* (not milliseconds)
465 1 for (Index = 0; Index < SCH_MAX_TASKS; Index++)
466 1 {
467 2 // Check if there is a task at this location
468 2 if (SCH_tasks_G[Index].pTask)
469 2 {
470 3 if (SCH_tasks_G[Index].Delay == 0)
471 3 {
472 4 // The task is due to run
473 4 SCH_tasks_G[Index].RunMe += 1; // Incr. the 'Run Me' flag
474 4
475 4 if (SCH_tasks_G[Index].Period)
476 4 {
477 5 // Schedule rperiodic tasks to run again
478 5 SCH_tasks_G[Index].Delay = SCH_tasks_G[Index].Period;
479 5 }
480 4 }
481 3 else
482 3 {
483 4 // Not yet ready to run: just decrement the delay
484 4 SCH_tasks_G[Index].Delay -= 1;
485 4 }
486 3 }
487 2 }
488 1 }
489
490 /*------------------------------------------------------------------*-
491
492 SCC_A_MASTER_Send_Tick_Message()
493
494 This function sends a tick message, over the CAN network.
495 The receipt of this message will cause an interrupt to be generated
496 in the slave(s): this invoke the scheduler 'update' function
497 in the slave(s).
498
499 -*------------------------------------------------------------------*/
C51 COMPILER V6.10 SCC_M515 04/19/2001 14:10:31 PAGE 23
500 void SCC_A_MASTER_Send_Tick_Message(const tByte SLAVE_INDEX)
501 {
502 1 // Find the slave ID for this slave
503 1 // ALL SLAVES MUST HAVE A UNIQUE (non-zero) ID
504 1 tByte Slave_ID = (tByte) Current_Slave_IDs_G[SLAVE_INDEX];
505 1 CAN_messages[0].Data[0] = Slave_ID;
506 1
507 1 // Fill the data fields
508 1 CAN_messages[0].Data[1] = Tick_message_data_G[SLAVE_INDEX][0];
509 1 CAN_messages[0].Data[2] = Tick_message_data_G[SLAVE_INDEX][1];
510 1 CAN_messages[0].Data[3] = Tick_message_data_G[SLAVE_INDEX][2];
511 1 CAN_messages[0].Data[4] = Tick_message_data_G[SLAVE_INDEX][3];
512 1
513 1 // Send the message on the CAN bus
514 1 CAN_messages[0].MCR1 = 0xE7; // TXRQ, reset CPUUPD
515 1 }
516
517 /*------------------------------------------------------------------*-
518
519 SCC_A_MASTER_Process_Ack()
520
521 Make sure the slave (SLAVE_ID) has acknowledged the previous
522 message that was sent. If it has, extract the message data
523 from the USART hardware: if not, call the appropriate error
524 handler.
525
526 PARAMS: The index of the slave.
527
528 RETURNS: RETURN_NORMAL - Ack received (data in Ack_message_data_G)
529 RETURN_ERROR - No ack received (-> no data)
530
531 -*------------------------------------------------------------------*/
532
533 bit SCC_A_MASTER_Process_Ack(const tByte SLAVE_INDEX)
534 {
535 1 tByte Ack_ID, Slave_ID;
536 1
537 1 // First time this is called there is no ack tick to check
538 1 // - we simply return 'OK'
539 1 if (First_ack_G)
540 1 {
541 2 First_ack_G = 0;
542 2 return RETURN_NORMAL;
543 2 }
544 1
545 1 if ((CAN_messages[1].MCR1 & 0x03) == 0x02) // if NEWDAT
546 1 {
547 2 // An ack message was received
548 2 //
549 2 // Extract the data
550 2 Ack_ID = CAN_messages[1].Data[0]; // Get data byte 0
551 2
552 2 Ack_message_data_G[SLAVE_INDEX][0] = CAN_messages[1].Data[1];
553 2 Ack_message_data_G[SLAVE_INDEX][1] = CAN_messages[1].Data[2];
554 2 Ack_message_data_G[SLAVE_INDEX][2] = CAN_messages[1].Data[3];
555 2 Ack_message_data_G[SLAVE_INDEX][3] = CAN_messages[1].Data[4];
556 2
557 2 CAN_messages[1].MCR0 = 0xfd; // reset NEWDAT, INTPND
558 2 CAN_messages[1].MCR1 = 0xfd;
559 2
560 2 // Find the slave ID for this slave
561 2 Slave_ID = (tByte) Current_Slave_IDs_G[SLAVE_INDEX];
C51 COMPILER V6.10 SCC_M515
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -