📄 hcandrv.c51
字号:
#pragma large
#pragma debug
#pragma registerbank(3)
#pragma pagelength(80) pagewidth(110)
/***********************************************************************
************************************************************************
* *
* C A N D R I V E R *
* *
************************************************************************
************************************************************************
* *
* Funktion: *
* *
* Diese Modul enth刲t den eigentlichen CAN-Task. Der CAN-Task *
* 乥ernimmt die gesammte Steuerung der CAN-Treiber Software. *
* Er reagiert auf Befehle von der Applikation (Signal und Daten *
* vom Modul CANAPIF) und auf Interrupts vom CAN-Controller. *
* Gestartet wird der CAN-Task vom Modul CANAPIF. *
* *
* *
* Filename : HCANDRV.C51 *
* *
* Modulename : HCANDRV *
* *
* Zielsystem : Jedes 8051 System mit einem Siemens *
* 81C91 CAN-Controller *
* *
* Entwicklungssystem : Keil C-51 *
* *
************************************************************************
* Versionen: *
* *
* 0.1 26.10.1990 Th. Fischler : Erste Version *
* 1.0 7.12.1990 Th. Fischler : Bus-off Handling eingebaut *
* 21.1.1991 Th. Fischler : Send-Error Verhalten eingebaut *
* 14.1.1991 Th. Fischler : Full-CAN eingebaut *
* 20.8.1991 Th. Fischler : Beim Basic-CAN wird der Error-INT *
* nicht mehr benutzt *
* 2.0 10.10.1991 Th. Fischler : Version f乺 RTX-51 V4.0 *
* 2.1 24.8.1992 Th. Fischler : Workaround f乺 Signal Mehrfach- *
* verwendungsproblem *
* 2.2 21.03.1996 K. Birsen : nur f乺 81C91 implementiert. *
* *
* *
************************************************************************
* Copyright 1991 .. 2001 METTLER & FUCHS AG, CH-8953 Dietikon *
************************************************************************/
/*---------------------------------------------------------------------*
* D E F I N I T I O N E N *
*---------------------------------------------------------------------*/
#include "abbrev.h"
#include "candefs.h"
/* Befehle von der Applikation */
#define CAN_HW_INIT_ORDER 1
#define CAN_DEF_OBJ_ORDER 2
#define CAN_STOP_ORDER 3
#define CAN_START_ORDER 4
#define CAN_SEND_ORDER 5
#define CAN_REQUEST_ORDER 6
#define CAN_BIND_OBJ_ORDER 7
#define CAN_UNBIND_OBJ_ORDER 8
#define CAN_WRITE_ORDER 9
#define CAN_READ_W_IND_ORDER 10
#define CAN_READ_W_TID_ORDER 11
#define CAN_READ_ORDER 12
#define CAN_GET_STATUS_ORDER 13
#define CAN_ACTIVATE_WAIT 14 /* Spezial-Funktion zum Anzeigen, */
/* das ein Task auf ein Objekt wartet */
/* Function-Prototypes */
static void c_handle_receive_int (void);
static void c_handle_can_int (void);
static void c_get_back (byte ret_val);
static void c_handle_appli_signal (void);
/*---------------------------------------------------------------------*
* I M P O R T S *
*---------------------------------------------------------------------*/
/* Verwendeter CAN-Interrupt (definiert in XCANCONF.A51) */
extern const unsigned char code CAN_INT_NBR;
/* RTX-51 Function-Calls */
#include <rtx51.h>
#include "hcanobja.h"
#include "hcancont.h"
/*---------------------------------------------------------------------*
* M O D U L G L O B A L E V A R I A B L E N *
*---------------------------------------------------------------------*/
/* Die Applikation erteilt dem CAN-Task 乥er den gemeinsamen */
/* Speicherbereich C_ORDER_BUF Befehle. Ueber diesen gemeinsamen */
/* Speicherbereich gibt der CAN-Driver ebenfalls Status-Meldungen */
/* an die Applikation zur乧k. */
/* Der C_ORDER_BUF ist im Modul CANAPIF.A51 definiert. */
/* Die hier definierte Struktur wird an die selbe Speicherstelle */
/* gelegt. */
/* ACHTUNG !! : Diese Struktur darf nicht einfach abge刵dert werden */
/* sie muss mit der Definition im Modul CANAPIF.A51 乥ereinstimmen */
/* K. Birsen um c_define_obj_ext zu realisieren */
/* c_order_buf.param hier und CANAPIF.A51 vom 5 auf 6 erh攈t */
extern xdata struct {
byte order;
byte task_id;
byte param[6];
} c_order_buf;
/* Ist TRUE falls der CAN-Task gestoppt ist (keine Objekte senden */
/* oder empfangen kann) und FALSE falls der CAN-Task l剈ft. */
static byte can_stopped;
/* Workaround Signal-Problem */
/* Enth刲t die identifikation aller Tasks an die ein Objekt */
/* gebunden ist und an die tats刢hlich mit CAN_WAIT auf das Objekt */
/* warten */
static struct {
byte task_id;
byte task_waits;
} signal_ok[MAX_BIND_OBJ];
#pragma eject
/*---------------------------------------------------------------------*
* L O K A L E P R O Z E D U R E N *
*---------------------------------------------------------------------*/
/*---------------------------------------------------------------------*
* C _ H A N D L E _ R E C E I V E _ I N T
*---------------------------------------------------------------------*
* Funktion:
*
* Steuert den Empfang eines Objektes nach einem Receive-Interrupt
*
*---------------------------------------------------------------------*
* Parameter:
*
* --
*
*---------------------------------------------------------------------*/
static void c_handle_receive_int (void)
{
unsigned int stat;
byte index, bind, i;
stat = c_receive_obj ();
if (stat <= 255) {
/* Applikation muss benachrichtigt werden */
index = stat;
/* testen ob das empfangene Objekt an einen Task gebunden ist */
bind = c_get_bind (index);
if (bind != NO_BIND) {
/* Objekt ist an einen Task gebunden */
/* Testen ob Task bereit ist */
for (i=0; i<=MAX_BIND_OBJ-1; i++) {
if ((signal_ok[i].task_id == bind)
&& (signal_ok[i].task_waits == TRUE)) {
os_send_signal (bind);
return;
}
}
}
else {
/* Objekt an keinen Task gebunden, an Mailbox senden */
/* Die Applikation liest danach mit dem Index die Objektdaten */
if (os_send_message (7,index,0) == -1) {
/* Objekt kann von der Applikation nicht empfangen werden */
c_set_read (index);
}
}
}
else {
;
/* Ein Objekt wurde empfangen, die Applikation muss aber nicht */
/* benachrichtigt werden. */
/* Dieser Fall wurde nur f乺 interne Testzwecke eingef乬t */
}
}
/*---------------------------------------------------------------------*
* C _ H A N D L E _ C A N _ I N T
*---------------------------------------------------------------------*
* Funktion:
*
* Abhandlung der Aktionen die beim Auftreten eines CAN-Interrupts
* ausgef乭rt werden m乻sen.
*
*---------------------------------------------------------------------*
* Parameter:
*
* --
*
*---------------------------------------------------------------------*/
static void c_handle_can_int (void)
{
/* Die Informationsdarstellung ist beim Basic- und Full-CAN */
/* Controller nach einem Interrupt sehr unterschiedlich. */
/* Daher wird die Auswertung der Interrupt-Informationen f乺 */
/* die beiden Controller getrennt implementiert */
enum interrupt_t int_t; /* 81C91 Interrupt Typen */
int_t = c_get_int_typ();
if (int_t == obj_int) {
c_handle_receive_int();
/* Der Interrupt wird von der Empfangsroutine zur乧kgesetzt */
}
else if (int_t == error_int) {
/* Das Status-Register muss ausgewertet werden */
/* Es k攏nen mehrere Fehler gleichzeitig auftreten */
if (c_get_status() == bus_off) {
/* Applikation mit Index 0 benachrichtigen */
os_send_message (7,0,0);
}
/* Error-Interrupt zur乧ksetzen */
c_receipt_error_int();
}
else if (int_t == no_int) {
/* Der Controller zeigt keinen Interrupt an */
/* Sollte eigentlich nicht vorkommen */
/* Wird jedoch aus Sicherheitsgr乶den abgefangen */
c_receipt_error_int(); /* Interrupt zur乧ksetzen */
}
}
#pragma eject
/*---------------------------------------------------------------------*
* C _ G E T _ B A C K
*---------------------------------------------------------------------*
* Funktion:
*
* R乧kgabe des Statuswert RET_VAL an die Applikation, starten
* der Applikation mit einem Signal
*
*---------------------------------------------------------------------*
* Parameter:
*
* ret_val : Wert der an die Applikation zur乧kgegeben werden soll
*
*---------------------------------------------------------------------*/
static void c_get_back (byte ret_val)
{
c_order_buf.param[0] = ret_val;
os_send_signal (c_order_buf.task_id);
}
/*---------------------------------------------------------------------*
* C _ H A N D L E _ A P P L I _ S I G N A L
*---------------------------------------------------------------------*
* Funktion:
* Ausf乭rung aller Applikationsbefehle
*
*---------------------------------------------------------------------*
* Parameter:
*
* --
*
*---------------------------------------------------------------------*/
static void c_handle_appli_signal (void)
{
byte temp, temp2;
byte done, i;
/* Hilfsvariable zum separaten ansprechen von Bytes */
/* in einem Word oder doubel Word */
union {
unsigned int tw;
byte tb[2];
} qq;
/* Union um den den Pointer als einzelne Bytes ansprechen zu k攏nen */
union {
struct
{ byte offs[2];
} short_ptr;
unsigned int xdata *i_ptr;
byte xdata *c_ptr;
} po;
unsigned int w_temp;
switch (c_order_buf.order) {
case CAN_HW_INIT_ORDER:
c_stop ();
can_stopped = TRUE;
done = c_hw_init ( c_order_buf.param[0], /* bit_length_1_reg */
c_order_buf.param[1], /* bit_length_2_reg */
c_order_buf.param[2], /* output_control_reg */
c_order_buf.param[3]); /* sleep_and_br_prescale */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -