-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathOLCB_CAN_Link.h
197 lines (162 loc) · 5.93 KB
/
OLCB_CAN_Link.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#ifndef __OLCB_CAN_LINK_H__
#define __OLCB_CAN_LINK_H__
#include <stdint.h>
#include "can.h"
#include "Arduino.h"
#include "OLCB_Link.h"
#include "OLCB_CAN_Buffer.h"
#include "OLCB_NodeID.h"
#include "OLCB_Event.h"
#include "OLCB_Datagram.h"
#include "OLCB_Stream.h"
#include "OLCB_Alias_Cache.h"
#include "float16.h"
// state machine definitions NOT USED apparently!?
#define STATE_INITIAL 0
#define STATE_WAIT_CONFIRM 10
#define STATE_ALIAS_ASSIGNED 20
#define STATE_INITIALIZED 30
#define NODE_ID_STATE_INACTIVE 0
#define NODE_ID_STATE_CID1 1
#define NODE_ID_STATE_CID2 2
#define NODE_ID_STATE_CID3 3
#define NODE_ID_STATE_CID4 4
#define NODE_ID_STATE_RID 5
/**********************/
//YOU MUST SET THIS TO EQUAL THE NUMBER OF NIDS YOU WISH TO USE!
//This definition is pretty bad, but universally useable
#if defined(__AVR_ATMEGA328__) || defined(__AVR_ATMEGA168__)
#define CAN_ALIAS_BUFFER_SIZE 5
#else
#define CAN_ALIAS_BUFFER_SIZE 10
#endif
#define RID_TIME_WAIT 500 //ms. Up for debate how long this should be!
class OLCB_CAN_Link;
#define ALIAS_EMPTY_STATE 0 //idle, doing nothing, no alias
#define ALIAS_HOLDING_STATE 1 //alias allocated, not assigned to a NodeID
#define ALIAS_CID1_STATE 2
#define ALIAS_CID2_STATE 3
#define ALIAS_CID3_STATE 4
#define ALIAS_CID4_STATE 5
#define ALIAS_RID_STATE 6
#define ALIAS_AMD_STATE 7
#define ALIAS_INIT_COMPLETE_STATE 8
#define ALIAS_RELEASING_STATE 15
#define ALIAS_RESENDRID_STATE 20
#define ALIAS_SENDVERIFIEDNID_STATE 25
#define ALIAS_READY_STATE 30 //assigned to a NodeID
struct private_nodeID_t
{
OLCB_NodeID *node;
uint8_t state;
uint16_t alias; //yes, an alias.
uint32_t time_stamp;
uint32_t lfsr1, lfsr2;
};
/* This class is a helper class that manages the state machine for allocating CAN aliases to local virtual nodes */
class OLCB_CAN_Alias_Helper
{
public:
OLCB_CAN_Alias_Helper() : index(0)
{
for(uint8_t i = 0; i < CAN_ALIAS_BUFFER_SIZE; ++i)
{
_nodes[i].alias = 0;
_nodes[i].node = 0;
_nodes[i].state = ALIAS_EMPTY_STATE;
}
}
void initialize(OLCB_CAN_Link *link);
void checkMessage(OLCB_CAN_Buffer *msg);
void update(void);
void preAllocateAliases(void);
void allocateAlias(OLCB_NodeID* nodeID);
void reAllocateAlias(private_nodeID_t* nodeID);
bool releaseAlias(OLCB_NodeID* nodeID);
void idleAlias(OLCB_NodeID* nodeID);
void verifyNID(OLCB_CAN_Buffer *buf);
void sendAMD(OLCB_NodeID* nodeID);
private:
//methods
//fields
uint8_t index;
OLCB_CAN_Link *_link;
uint32_t _helper_value; //for constructing aliases with a NID to seed the LSFR.
private_nodeID_t _nodes[CAN_ALIAS_BUFFER_SIZE];
};
/**********************/
/******************
OLCB_CAN_Link is our gateway to the outside world. We require one instance for each
CAN interface we wish to use.
Manages each virtual node, and transparently handles all CAN aliasing requirements (which are manifold).
******************/
class OLCB_CAN_Link : public OLCB_Link
{
public:
OLCB_CAN_Link() : internalMessage(false)
{
return;
}
bool initialize(void);
// bool negotiateAlias(OLCB_NodeID *nid);
void negotiateAliasesInQueue(void);
bool handleTransportLevel(void);
virtual void update(void);
uint8_t sendDatagramFragment(OLCB_Datagram *datagram, uint8_t start);
bool ackDatagram(OLCB_NodeID *source, OLCB_NodeID *dest);
bool nakDatagram(OLCB_NodeID *source, OLCB_NodeID *dest, int reason);
//TODO This one needs implementation!
bool sendStream(OLCB_NodeID* source, OLCB_Stream *stream) {return false;}
//Not sure that this is how streams should work at all!
//TODO does this need to be modified!?
bool sendVerifiedNID(OLCB_NodeID *nid);
bool sendVerifyNID(OLCB_NodeID *src);
bool sendVerifyNID(OLCB_NodeID *src, OLCB_NodeID *request);
bool sendIdent(OLCB_NodeID* source);
bool sendPCER(OLCB_NodeID* source, OLCB_Event *event);
bool sendConsumerIdentified(OLCB_NodeID* source, OLCB_Event *event);
bool sendLearnEvent(OLCB_NodeID* source, OLCB_Event *event);
bool sendProducerIdentified(OLCB_NodeID* source, OLCB_Event *event, uint8_t active=EVENT_STATE_UNKNOWN);
bool sendTractionControlSpeed(OLCB_NodeID* source, OLCB_NodeID* dest, _float16_shape_type speed);
bool sendTractionControlFX(OLCB_NodeID* source, OLCB_NodeID* dest, uint32_t address, uint16_t value);
bool sendMessage(OLCB_Buffer *msg); //send an arbitrary message
void addVNode(OLCB_Virtual_Node *vnode);
void removeVNode(OLCB_Virtual_Node *vnode);
bool wasActiveSet();
void resetWasActive();
//friend class OLCB_CAN_Alias_Helper;
//protected:
//private:
//This method would not only send the current txbuffer over CAN, but would distribute the message locally among vnodes as well.
bool sendMessage(void);
void deliverMessage(void);
OLCB_CAN_Buffer txBuffer, rxBuffer;
OLCB_CAN_Alias_Helper _aliasHelper;
OLCB_Alias_Cache _translationCache;
//stuffs for VerifyNodeID/VerifiedNodeID; TODO!
OLCB_NodeID _nodeIDToBeVerified;
uint32_t _aliasCacheTimer;
/**
* Send the next CID message. Return true it you can/did,
* false if you didn't.
*/
bool sendCID(OLCB_NodeID* nodeID, uint8_t i);
/**
* Send an RIM message. Return true it you can/did,
* false if you didn't.
*/
bool sendRID(OLCB_NodeID* nodeID);
/**
* Send the InitializationComplete when everything is OK.
* Return true it you can/did,
* false if you didn't.
*/
bool sendInitializationComplete(OLCB_NodeID* nodeID);
bool sendRejectOptionalInteraction(OLCB_NodeID* source, OLCB_NodeID* dest, uint16_t MTI);
bool sendAMR(OLCB_NodeID *nid);
bool sendAMD(OLCB_NodeID *nid);
bool sendAME(OLCB_NodeID *nid);
bool internalMessage;
bool wasActive;
};
#endif //__OLCB_LINK_H__