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
198
199
200
201
202
203
|
/*
SNAP.h - RepRap SNAP Communications library for Arduino
This library implements easy SNAP based communication with the RepRap host software
with easy commands to enable receiving, sending, and passing along SNAP messages.
History:
* (0.1) Ported from PIC library by Zach Smith.
* (0.2) Updated and fixed by the guys from Metalab in Austra (kintel and wizard23)
* (0.3) Rewrote and refactored all code. Added separate buffers and variables for Rx/Tx by Zach Smith.
License: GPL v2.0
*/
#ifndef SNAP_h
#define SNAP_h
// include types & constants of Wiring core API
#include "WProgram.h" // Fix for Arduino-0012 compile error (see http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1232533589)
#include "WConstants.h"
#include "HardwareSerial.h"
//how many devices we have on this meta device
#define MAX_DEVICE_COUNT 5 // size of our array to store virtual addresses
#define TX_BUFFER_SIZE 16 // Transmit buffer size.
#define RX_BUFFER_SIZE 16 // Receive buffer size.
#define HOST_ADDRESS 0 // address of the host.
//our sync packet value.
#define SNAP_SYNC 0x54
//The defines below are for error checking and such.
//Bit0 is for serialError-flag for checking if an serial error has occured,
// if set, we will reset the communication
//Bit1 is set if we are currently transmitting a message, that means bytes of
// a message have been put in the transmitBuffer, but the message is not
// finished.
//Bit2 is set if we are currently building a send-message
//Bit3 is set if we are busy with the last command and have to abort the message
//Bit4 is set when we have a wrong uartState
//Bit5 is set when we receive a wrong byte
//Bit6 is set if we have to acknowledge a received message
//Bit7 is set if we have received a message for local processing
#define serialErrorBit B00000001
#define inTransmitMsgBit B00000010
#define inSendQueueMsgBit B00000100
#define msgAbortedBit B00001000
#define wrongStateErrorBit B00010000
#define wrongByteErrorBit B00100000
#define ackRequestedBit B01000000
#define processingLockBit B10000000
//these are the states for processing a packet.
enum SNAP_states
{
SNAP_idle = 0x30,
SNAP_haveSync,
SNAP_haveHDB2,
SNAP_haveHDB1,
SNAP_haveDAB,
SNAP_readingData,
SNAP_dataComplete,
// The *Pass states below represent states where
// we should just be passing the data on to the next node.
// This is either because we bailed out, or because the
// packet wasn't destined for us.
SNAP_haveHDB2Pass,
SNAP_haveHDB1Pass,
SNAP_haveDABPass,
SNAP_readingDataPass
};
class SNAP
{
public:
SNAP();
void begin(long baud);
void addDevice(byte b);
void receivePacket();
void receiveByte(byte b);
bool packetReady();
byte getDestination();
byte getByte(byte index);
int getInt(byte index); // get 16 bits
void startMessage(byte to, byte from);
void sendDataByte(byte c);
void sendDataInt(int data);
void sendDataLong(long data);
void sendMessage();
void debug();
void releaseLock();
private:
void receiveError();
bool hasDevice(byte b);
void transmit(byte c);
//our crc functions.
byte computeCRC(byte b, byte crc);
byte computeRxCRC(byte c);
byte computeTxCRC(byte c);
//these are variables for the packet we're currently receiving.
byte rxState; // Current SNAP packet state
byte rxFlags; // flags for checking status of the serial-communication
byte rxHDB1; // 1st header byte
byte rxHDB2; // 2nd header byte
byte rxLength; // Length of packet being received
byte rxDestAddress; // Destination of packet being received (us)
byte rxSourceAddress; // Source of packet being received
byte rxCRC; // Incrementally calculated CRC value
byte rxBufferIndex; // Current receive buffer index
byte rxBuffer[RX_BUFFER_SIZE]; // Receive buffer
//these are the variables for the packet we're currently transmitting.
byte txHDB2; // 2nd header byte (1st header byte doesnt change!)
byte txLength; // transmit packet length
byte txDestAddress; // transmit packet destination
byte txSourceAddress; // transmit packet source (us)
byte txCRC; // incrementally calculated CRC value
byte txBuffer[TX_BUFFER_SIZE]; // Last packet data, for auto resending on a NAK
// the address of our internal device sending message
byte deviceAddresses[MAX_DEVICE_COUNT];
byte deviceCount;
};
inline void SNAP::begin(long baud)
{
Serial.begin(baud);
}
inline void SNAP::sendDataInt(int i)
{
this->sendDataByte(i & 0xff);
this->sendDataByte(i >> 8);
}
inline void SNAP::sendDataLong(long i)
{
this->sendDataByte(i & 0xff);
this->sendDataByte(i >> 8);
this->sendDataByte(i >> 16);
this->sendDataByte(i >> 24);
}
inline bool SNAP::packetReady()
{
return (this->rxFlags & processingLockBit);
}
inline void SNAP::debug()
{
Serial.print('d');
}
inline void SNAP::transmit(byte c)
{
Serial.print(c, BYTE);
}
inline byte SNAP::computeRxCRC(byte b)
{
this->rxCRC = this->computeCRC(b, this->rxCRC);
return b;
}
inline byte SNAP::computeTxCRC(byte b)
{
this->txCRC = this->computeCRC(b, this->txCRC);
return b;
}
inline byte SNAP::getDestination()
{
return this->rxDestAddress;
}
inline byte SNAP::getByte(byte index)
{
return this->rxBuffer[index];
}
inline int SNAP::getInt(byte index)
{
return (this->rxBuffer[index+1] << 8) + this->rxBuffer[index];
}
//global variable declaration.
extern SNAP snap;
#endif
|