-
Notifications
You must be signed in to change notification settings - Fork 8
/
MdbMaster.cpp
125 lines (103 loc) · 3 KB
/
MdbMaster.cpp
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
#include "MdbMaster.h"
unsigned long _commandSentTime;
MdbMaster::MdbMaster()
{
MdbPort.begin();
while (!MdbPort);
_commandSentTime = 0;
}
void MdbMaster::SendCommand(unsigned char address, unsigned char command)
{
unsigned char dataBytes[1];
MdbMaster::SendCommand(address, command, dataBytes, 0);
}
void MdbMaster::SendCommand(unsigned char address, unsigned char command,
unsigned char *dataBytes, unsigned int dataByteCount)
{
unsigned char sum = 0;
// Send the command along with the Bill Validator Address.
MdbPort.write(address | command, 1);
sum += address | command;
// Limit the number of data bytes that can be sent for a command
// to 34, since the total length of a message, including the
// address/command byte and the checksum byte, is limited to 36 bytes.
if (dataByteCount > 34)
{
dataByteCount = 34;
}
// Send data bytes.
for (unsigned int i = 0; i < dataByteCount; i++)
{
MdbPort.write(dataBytes[i], 0);
sum += dataBytes[i];
}
// Send checksum.
MdbPort.write(sum, 0);
_commandSentTime = millis();
}
// Try to read the response after sending a command to the validator.
// Wait for ~5ms after sending a command before returning with error
// code -1 (request retransmit). If there is some other, more fatal error,
// returns -2. If the message is recieved with no problem, 0 is the return
// value and the returned bytes will be put into the array pointed at by
// the response parameter. The number of bytes received will be stored in
// the variable referenced by the numBytes parameter. Other special
// conditions include ACK and NAK, which return 1 and 2 respectively.
//
// Return Codes:
// 0: Message returned normally in response parameter reference
// 1: ACK
// -1: NAK: Request retransmit after response timeout or NAK recieved.
// -2: Unrecoverable error, device should probably be reset after this.
int MdbMaster::GetResponse(unsigned char *response, unsigned int *numBytes)
{
int index = 0;
int lastMode = 0;
// Wait for some bytes to be available. I should probably add some
// sort of timeout here.
while (!MdbPort.available())
{
if (millis() - _commandSentTime > 5)
{
return -1;
}
}
// Loop through bytes received until there are either no bytes
// available, 36 bytes have been received (max message size),
// or a byte with the mode bit set, which signifies the end of
// the message.
while ((MdbPort.available() > 0)
&& (index <= MAX_MSG_SIZE)
&& (lastMode == 0))
{
response[index] = MdbPort.read() & 0xFF;
lastMode = (response[index] >> 8) & 0x01;
index++;
}
*numBytes = index;
return 0;
}
// Send an acknowledgement.
void MdbMaster::SendAck()
{
MdbPort.write(ACK, 0);
}
// Send a retransmit request.
void MdbMaster::SendRet()
{
MdbPort.write(RET, 0);
}
// Send a negative acknowledgement.
void MdbMaster::SendNak()
{
MdbPort.write(NAK, 0);
}
// A hard reset will trigger all connected peripherals to reset.
void MdbMaster::HardReset()
{
pinMode(1, OUTPUT);
digitalWrite(1, LOW);
delay(150);
digitalWrite(1, HIGH);
delay(150);
}