forked from shb/arduino-adns-5050
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAdns5050.cpp
129 lines (109 loc) · 2.84 KB
/
Adns5050.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
125
126
127
128
129
#include <SPI.h>
#include "Adns5050.h"
Adns5050::Adns5050 (const int ncsPin, const int resetPin)
{
_ncsPin = ncsPin;
_resetPin = resetPin;
#ifdef ADNS_50x0_DEBUG
Serial.print("ADNS.NCS: "); Serial.println(_ncsPin);
Serial.print("ADNS.NRESET: "); Serial.println(_resetPin);
#endif
}
bool Adns5050::begin (const unsigned long fsck)
{
// Setup SPI pins
SPI.begin();
// Setup control pins
if (_ncsPin > -1) {
pinMode(_ncsPin, OUTPUT);
}
if (_resetPin > -1) {
pinMode(_resetPin, OUTPUT);
// Activate slave
digitalWrite(_resetPin, HIGH);
}
// Setup SPI parameters
if (fsck) _fSCK = fsck;
else _fSCK = ADNS_50x0_fSCK;
_spiSettings = SPISettings(_fSCK, MSBFIRST, SPI_MODE3);
// Compute IO timings and delays
_dSWR = (unsigned int)(ADNS_5050_tSWR - 8000000.0/_fSCK);
_dSWW = (unsigned int)(ADNS_5050_tSWW - 16000000.0/_fSCK);
// By now the sensor should have powered up, so we can...
// Test Product_ID2 and Revision_ID
if (read(Product_ID2) != ADNS_5050_Product_ID2) return false;
if (read(Revision_ID) != ADNS_5050_Revision_ID) return false;
if ((unsigned char)(~read(Inv_Rev_ID)) != ADNS_5050_Revision_ID) return false;
return true;
}
unsigned char Adns5050::read (const ADNS_5050_reg address)
{
// A READ following...
switch (_lastOp)
{
// ...a READ
case ADNS_50x0_READ:
// Wait for tSRR
delayMicroseconds(ADNS_5050_tSRR);
break;
// ...a WRITE
case ADNS_50x0_WRITE:
// Wait for dSWR - 1 byte
delayMicroseconds(_dSWR);
break;
}
SPI.beginTransaction(_spiSettings);
if (_ncsPin > -1) digitalWrite(_ncsPin, LOW);
unsigned char recv = SPI.transfer(address | ADNS_50x0_READ);
if (recv != (address | ADNS_50x0_READ)) {
#ifdef ADNS_50x0_DEBUG
Serial.println("ADNS.SDIO: IO error");
#endif
SPI.endTransaction();
return 0xff;
} else {
delayMicroseconds(ADNS_50x0_tSRAD);
#ifdef ADNS_50x0_DEBUG
Serial.print("ADNS.SDIO << 0x");
Serial.print(address, HEX);
Serial.print(" >> 0x");
Serial.println(recv, HEX);
#endif
}
recv = SPI.transfer((unsigned char)0);
#ifdef ADNS_50x0_DEBUG
Serial.print("ADNS.SDIO >> 0x");
Serial.println(recv, HEX);
#endif
SPI.endTransaction();
if (_ncsPin > -1) digitalWrite(_ncsPin, HIGH);
_lastOp = ADNS_50x0_READ;
return recv;
}
unsigned char Adns5050::write (const ADNS_5050_reg address, unsigned char value)
{
switch (_lastOp)
{
case ADNS_50x0_READ:
delayMicroseconds(ADNS_5050_tSRW);
break;
case ADNS_50x0_WRITE:
delayMicroseconds(_dSWW);
break;
}
digitalWrite(_ncsPin, LOW);
SPI.beginTransaction(_spiSettings);
unsigned char recv = SPI.transfer(address | ADNS_50x0_WRITE);
if (recv != (address | ADNS_50x0_WRITE)) {
#ifdef ADNS_50x0_DEBUG
Serial.println("ADNS.SDIO: IO error");
#endif
SPI.endTransaction();
return 0xff;
}
recv = SPI.transfer(value);
digitalWrite(_ncsPin, HIGH);
SPI.endTransaction();
_lastOp = ADNS_50x0_WRITE;
return recv;
}