#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 aufeinanderfolgenden Registerwerten * 0-1 * * WRITE 6 Nein Schreibanforderung * 0-3 * 4 Typ von * 5 Reserviert 0 * * REPLY 5 Nein Mitteilung über aktuellen Registerwert * 0-3 * 4 Typ von * * Kommunikationsbeschreibung * -------------------------- * * Wert lesen: * 1. READ * 2. REPLY * * Wert schreiben: * 1. WRITE * 2. REPLY * * Wertegruppe lesen: * 1. READ EXT. * 2. x REPLY * * * * **/ #include #include #include #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; };