📄 fcancont.c51
字号:
* Funktion:
* Beim Starten des 82526 nach Power-Down ergeben sich manchmal
* kleinere Probleme den Chip sauber zu initialisieren.
* Diese Routine l攕t dieses Problem, indem der 82526 zweimal
* geresetet wird. Diese Routine sollte vor der ersten
* initialisierung des Controllers aufgerufen werden.
*
*---------------------------------------------------------------------*
* Parameter:
* --
*---------------------------------------------------------------------*/
void c_first_init (void)
{
fcan_reg.r.control = 0x01; /* Reset */
fcan_reg.r.control = 0x00; /* Reset aufheben */
fcan_reg.r.control = 0x01; /* Reset */
/* Interrupt-Pointer zur乧ksetzen */
fcan_reg.r.intr = 0xff;
}
/*---------------------------------------------------------------------*
* C _ H W _ I N I T
*---------------------------------------------------------------------*
* Funktion:
* Grundinitialisierung des 82526 CAN-Controllers.
* Der CAN-Controller wird f乺 diese Operation angehalten.
* Er muss danach mit C_START wieder neu gestartet werden.
*
*---------------------------------------------------------------------*
* Parameter:
*
* bus_t0_reg : Bus-Timing Register 0 des 82526
* bus_t1_reg : Bus-Timing Register 1 des 82526
* out_c_reg : Output-Control Register des 82526
*
* Returnwert : TRUE -> OK
* FALSE -> Fehler beim Init
*---------------------------------------------------------------------*/
byte c_hw_init (byte bus_t0_reg,
byte bus_t1_reg,
byte out_c_reg)
{
/* Plausibilit則skontrolle der Parameter noch weggelassen */
can_reset_request();
/* Operation-Bit auf low setzen */
fcan_reg.r.control = (fcan_reg.r.control & 0x7f);
fcan_reg.r.bus_tim_0 = bus_t0_reg;
fcan_reg.r.bus_tim_1 = bus_t1_reg;
fcan_reg.r.out_contr = out_c_reg;
fcan_reg.r.intr = 0xff;
return TRUE;
}
/*---------------------------------------------------------------------*
* C _ I N I T _ C O N T _ R E G
*---------------------------------------------------------------------*
* Funktion:
* Initialisierung des CONTROL-REGISTERS des 82526
* (Festlegung der Interrupts und des Synch-Modes).
* Der CAN-Controller wird f乺 diese Operation angehalten, er muss
* danach mit C_START wieder neu gestartet werden.
*
*---------------------------------------------------------------------*
* Parameter:
*
* cont_reg : Inhalt des 82526 Control-Registers
*
*---------------------------------------------------------------------*/
void c_init_cont_reg (byte cont_reg)
{
/* Reset-Request einschalten */
can_reset_request();
/* Sicherstellen dass Halt-/Reset-Request und Operation nicht */
/* ge刵dert wird */
fcan_reg.r.control = (cont_reg | 0x03) & 0x7F;
}
/*---------------------------------------------------------------------*
* C _ I N I T _ O B J
*---------------------------------------------------------------------*
* Funktion:
* Definiert an der internen CAN-Controller Adresse BUF_ADR ein
* neues CAN-Objekt. Der CAN-Controller wird f乺 diese Operation
* angehalten, er muss danach mit C_START wieder neu gestartet
* werden.
*
*---------------------------------------------------------------------*
* Parameter:
*
* ident : Identifier des zu definierenden Objektes
* (0 .. 7EFH)
* data_len : Anzahl Datenbytes des Objektes (0 .. 8)
* obj_typ : Genaue Beschreibung der Objektart :
* D_REC (0) : Objekt kann nur empfangen werden
* D_SEND (1) : Objekt kann nur gesendet werden
* D_REC_R_SEND (2) : Objekt kann empfangen werden
* und es kann ein entsprechendes
* Remote-Frame ausgesendet werden
* D_SEND_R_REC (3) : Objekt kann gesendet werden und
* es kann ein entsprechendes
* Remote-Frame empfangen und
* beantwortet werden
* obj_adr : Interne Start-Adresse des Objektes im CAN-Controller,
* das erste Byte des CAN-Controllers ist
* dabei 0 (=Control Register), das erste Objekt beginnt
* beim 82526 bei der Adresse 6H.
* (Diese Art der Objekt-Adressierung dr刵gt sich durch
* die interne Struktur des 82526 Controllers auf,
* so wird zum Beispiel bei einem Empfangsinterrupt
* vom 82526 die Objektadresse des empfangenen Objektes
* in einem Register zur Verf乬ung gestellt.
* Das 乥ergeordnete Modul muss bei dieser Art der
* Objektverwaltung eine Liste der einzelnen Objekte
* und ihre Zuordnung zu den internen Adressen f乭ren.)
*
*---------------------------------------------------------------------*/
void c_init_obj (unsigned int ident,
byte data_len,
byte obj_typ,
byte obj_adr)
{
/* Definition der einzelnen Bits in den Objekt-Descriptoren. */
/* Es werden nur die Bits definiert die sinnvollerweise einzeln */
/* angesprochen werden. */
/* Im nachfolgenden Code wird auf die hier nicht definierten */
/* Bits direkt zugegriffen */
/* Diese Definition erleichtert die korrekte Initialisierung */
/* der Descriptoren */
union {
struct {
byte cpu_access : 1;
byte remote_tx_req : 1;
byte data_direction : 1;
byte remote_direction : 1;
byte : 4;
} d2_bits;
byte d2_byte;
} desc2;
union {
struct {
byte : 5;
byte transfer_int_ena : 1;
byte transfer_status : 1;
byte transmission_req : 1;
} d3_bits;
byte d3_byte;
} desc3;
/* Hilfsvariable zum separaten ansprechen von High- und Low-Byte */
/* in einem Word */
register union {
unsigned int tw;
byte tb[2];
} temp;
/* Halt-Request aktivieren */
can_halt_request();
/* Descriptor Byte 1 des Objektes initialisieren */
temp.tw = ident << 4;
/* obere 7-Bit des Identifiers, IMP-Access freigeben */
fcan_reg.mem[obj_adr] = (temp.tb[0]);
can_set_imp (obj_adr);
/* Descriptor Byte 2 */
desc2.d2_bits.cpu_access = 1;
desc2.d2_bits.remote_tx_req = 0;
/* Remote- und Data-Direction anhand des Objekt-Typs setzen */
if (obj_typ == D_REC) {
desc2.d2_bits.data_direction = 0;
desc2.d2_bits.remote_direction = 1;
}
else if (obj_typ == D_SEND) {
desc2.d2_bits.data_direction = 1;
desc2.d2_bits.remote_direction = 0;
}
else if (obj_typ == D_REC_R_SEND) {
desc2.d2_bits.data_direction = 0;
desc2.d2_bits.remote_direction = 1;
}
else if (obj_typ == D_SEND_R_REC) {
desc2.d2_bits.data_direction = 1;
desc2.d2_bits.remote_direction = 0;
}
/* Descriptor 2 schreiben */
fcan_reg.mem[obj_adr+1] = ((desc2.d2_byte & 0x0f) | (temp.tb[1] & 0xf0));
/* Descriptor Byte 3 */
/* Wenn Empfangsobjekt, Interrupt freigeben */
if ((obj_typ == D_REC) || (obj_typ == D_REC_R_SEND)) {
desc3.d3_bits.transfer_int_ena = 1;
}
else {
desc3.d3_bits.transfer_int_ena = 0;
}
/* Transfer-Status und Transmission Request auf Null setzen */
desc3.d3_bits.transfer_status = 0;
desc3.d3_bits.transmission_req = 0;
/* Descriptor 3 schreiben */
fcan_reg.mem[obj_adr+2] = ((desc3.d3_byte & 0xe0) | (data_len & 0x0f));
}
/*---------------------------------------------------------------------*
* C _ S T A R T
*---------------------------------------------------------------------*
* Funktion:
* Starten des CAN-Controllers nach Init oder nach C_STOP.
* Nach C_START k攏nen Objekte empfangen und gesendet werden.
* Falls n攖ig wird der Controller bei C_START nochmals kurz
* zur乧kgesetzt (reset) um einen eventuellen Bus-Off Zustand
* zu l攕chen.
*
*---------------------------------------------------------------------*
* Parameter:
*
* --
*
*---------------------------------------------------------------------*/
void c_start (void)
{
/* Status Register testen ob Controller Bus-Off ist */
if (fcan_reg.r.status & 0x20) {
/* Controller ist Bus-Off, nochmals reseten */
can_reset_request();
}
/* Eventuellen Halt-und Reset Zustand l攕chen */
fcan_reg.r.control = fcan_reg.r.control & 0xfc;
/* Nach einem Bus-Off bleibt der Reset f乺 128*11 Bits erhalten */
/* Warten bis Reset wirklich aufgehoben */
while (fcan_reg.r.status & 0x01);
}
/*---------------------------------------------------------------------*
* C _ S T O P
*---------------------------------------------------------------------*
* Funktion:
* Tempor剅es Anhalten des CAN-Controllers. Es kann mit C_START
* weitergefahren werden. Solange C_STOP aktiv ist, k攏nen keine
* Objekte empfangen oder gesendet werden.
*
*---------------------------------------------------------------------*
* Parameter:
*
* --
*
*---------------------------------------------------------------------*/
void c_stop (void)
{
can_halt_request();
}
/*---------------------------------------------------------------------*
* C _ R E A D _ O B J
*---------------------------------------------------------------------*
* Funktion:
* Lesen der Daten eines Objektes. Die Daten werden
* in den XDATA-Bereich, dessen Anfang mit dem Parameter BUF_PTR
* bezeichnet ist, kopiert. Es werden soviele Bytes kopiert wie bei
* C_INIT_OBJ definiert.
*
*---------------------------------------------------------------------*
* Parameter:
*
* obj_adr : Interne Start-Adresse des zu lesenden Objektes
* (siehe C_INIT_OBJ)
*
* arr : Array im XDATA-Bereiche in den die
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -