avr-fw-modules/can/include/can/cannode.h

145 lines
3.2 KiB
C
Executable File

#pragma once
/**
*
* can/cannode.h Register Based CAN Communication
*
* (c) 2016 Harald Christian Joachim Wolff
*
* Beschreibung:
*
* Ein CAN-Knoten erhält eine Identität (0-15).
* Es können Werte der Typen Int32/Float gelesen und geschrieben werden, hierfür wird auf dem Knoten das RB2 System genutzt.
* Es findet auf der Knotenseite kein Routing statt!
*
* Es wird nicht durch einen RB2_LINK kommuniziert, dadurch entsteht die Möglichkeit eine Achseninsel zu errichten in welcher z.B. ein weiterer Motor via HF3/RB2 angeschlossen ist.
*
* TOP
* |
* +---MOTOR
* |
* +--[CANNODE]--LUB2400
* | |
* | +---MOTOR
* |
* +--[CANNOD]--LUB2400
* | |
* | +---MOTOR
* +---FRONTPANEL
*
* CAN-Knoten senden grundsätzlich nur nach Aufforderung. Es findet keine selbstständige Sendung statt!
*
*
* Die CANID (Object-Identifier: OID) wird nach folgendem Schema erstellt:
*
* Bit Inhalt
* --------------------------------------
* 0..15 Field / Register No
* 16..19 Reserved 0
* 20..23 Ax identity
* 24..28 0
*
* Beschreibung der Nachrichtentypen:
*
* Bezeichnung Länge RTR Beschreibung
* Payload
* --------------------------------------------------------
*
* READ 0 Ja Anfordern eines Registerwertes
*
* READ EXT. 2 Nein Anfordern von <N> aufeinanderfolgenden Registerwerten
* 0-1 <N>
*
* WRITE 6 Nein Schreibanforderung
* 0-3 <Wert>
* 4 Typ von <Wert>
* 5 Reserviert 0
*
* REPLY 5 Nein Mitteilung über aktuellen Registerwert
* 0-3 <Wert>
* 4 Typ von <Wert>
*
* Kommunikationsbeschreibung
* --------------------------
*
* Wert lesen:
* 1. READ
* 2. REPLY
*
* Wert schreiben:
* 1. WRITE
* 2. REPLY
*
* Wertegruppe lesen:
* 1. READ EXT.
* 2. <N> x REPLY
*
*
*
*
**/
#include <can/can.h>
#include <rb2/regbus.h>
#include <sys/assert.h>
#define CNT_INT32 RDT_INT32
#define CNT_FLOAT RDT_FLOAT
typedef struct {
int identity;
register_node_proc
node_proc;
canfilter_t
rxfilter;
} cannode_t;
/**
* @brief Erstellt ein cannode_t objekt.
* @param identity Die Identität des CAN Node (0..15)
* @return 0 bei Erfolg, sonst -E...
*/
cannode_t* can_node_create(int identity,register_node_proc node_proc);
/**
* @brief Behandelt empfangene Nachrichten für einen CAN Node
* @param cn cannode_t objekt
* @return 0 bei Erfolg, sonst -E...
*/
int can_node_handler(cannode_t *cn);
int can_node_read (int node,unsigned int reg,uint8_t *type,void *buffer);
int can_node_write (int node,unsigned int reg,uint8_t type,void *buffer);
static inline int can_node_write_int32(int node,unsigned int reg,int32_t value){
return can_node_write( node, reg, CNT_INT32, &value );
};
static inline int can_node_write_float(int node,unsigned int reg,float value){
return can_node_write( node, reg, CNT_FLOAT, &value );
};
static inline int can_node_read_int32(int node,unsigned int reg,int32_t *value){
uint8_t t = CNT_INT32;
assert( can_node_read( node, reg, &t, value ) );
if (t != CNT_INT32){
*value = (int32_t)*(float*)value;
};
return ESUCCESS;
};
static inline int can_node_read_float(int node,unsigned int reg,float *value){
uint8_t t = CNT_FLOAT;
assert( can_node_read( node, reg, &t, value ) );
if (t != CNT_FLOAT){
*value = (float)*(int32_t*)value;
};
return ESUCCESS;
};