-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathIntanCmd.ino
146 lines (108 loc) · 4.99 KB
/
IntanCmd.ino
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
/*
* Define basic Intan commands of Read, write, calibrate
* Pass in chip select pin to each command so we set which Intan amp we want to communicate with
* Replaced digitalWrite with digitalWriteFast() 10 July 2018, JE
* readRegister()
* convertChannel()
* writeRegister()
* calibrateADC()
*
*/
/* JE: This used to return an unsigned int with readAddress | Register contents.
Result is returned in lower 8 bytes. First 8 bytes (MSBs) are all 0.
unsigned int readRegister(byte thisRegister, int bytesToRead ) {
JE: change to digitalWriteFastFast() for faster toggling of CS...for teh future
*/
uint16_t readRegister(byte thisRegister, int CSpin) {
// ------------------------------------
// SPI READ REGISTER COMMAND
// ------------------------------------
// byte inByte = 0; // incoming byte from the SPI
//byte defaultresult = -1; // result to return, default is -1, will be set to other meaningful value when SPI transfer completes
//unsigned int result; // result to return
byte xtrans = 0b0;
uint16_t result;
byte response1;
byte response2;
//Intan expects the adress after 11
byte readAddress = READ_REG_CMD | thisRegister;
//Serial.println(readAddress, BIN);
// take the chip select low to select the device:
digitalWriteFast(CSpin, LOW);
//send the first byte *(adress)
response1 = SPI.transfer(readAddress);
//read the second byte (data). The intan chip does this with all 0's
response2 = SPI.transfer(xtrans);
// take the chip select high to de-select:
digitalWriteFast(CSpin, HIGH);
result = (response1 << 8) | response2;
return (result);
}
uint16_t convertChannel(byte thisChannel, int CSpin) {
// ---------------------------------------
// CONVERT CHANNEL SPI COMMAND
// ----------------------------------------
/* JE: Intan RHD2132 specifies that 2 bytes will be returned for each convert command, no matter what.
So let's update function prototype to account for this, no variable bytes to read
unsigned int convertChannel(byte thisChannel, int bytesToRead ) {
*/
uint16_t result;
byte response1;
byte response2;
//Intan expects the adress after 00
byte convertAddress = CONVERT_CHAN_CMD | thisChannel;
// take the chip select low to select the device:
digitalWriteFast(CSpin, LOW);
//send the first byte *(adress)
response1 = SPI.transfer(convertAddress);
//transfer second byte. Last bit could be a 1 or 0 depending on desired DSP settings.
response2 = SPI.transfer(0); //JE 03 Nov 2016: Note that a 1 (high) can be sent as LSB for fast recovery from large transient.
// take the chip select high to de-select:
digitalWriteFast(CSpin, HIGH);
// JE: Return result with first SPI byte shifted 8 bits, then OR'd with response2 byte
result = (response1 << 8) | response2;
return (result);
}
uint16_t writeRegister(byte thisRegister, byte thisValue, int CSpin) {
// --------------------------------------
// WRITE REGISTER COMMAND
// --------------------------------------
uint16_t resultWrite;
byte writeAddress = WRITE_REG_CMD | thisRegister;
// take the chip select low to select the device:
digitalWriteFast(CSpin, LOW);
byte check1 = SPI.transfer(writeAddress); //Send register location
byte check2 = SPI.transfer(thisValue); //Send value to record into register
// take the chip select high to de-select:
digitalWriteFast(CSpin, HIGH);
resultWrite = (check1 << 8) | check2;
return resultWrite;
}
// --------------------------------------
// CALIBRATE ADC COMMAND
// --------------------------------------
/* From Intan datasheet: ADC self-calibration should be performed after chip power-up and register configuration....
Self-calibration takes many clock cycles to execute....
Nine dummy commands must be sent after a CALIBRATE command to generate the necessary clock cycles
Calibrate command should be sent only ONCE to initiate a calibration sequence...nine commands following CALIBRATE command are not executed,
; they are ignored until CALIBRATE is complete
*/
void calibrateADC(int CSpin) {
//give the intan at least 100 micros to configure before ADC calibration--see page 19 of RHD2000 datasheet.
// 1 ms is overkill, but barely any wait at all.
delay(1);
// take the chip select low to select the device:
digitalWriteFast(CSpin, LOW);
SPI.transfer(CALIBRATE_REG_CMD_MSBs); //Send first byte (MSBs)
SPI.transfer(CALIBRATE_REG_CMD_LSBs); //Send second byte (LSBs)
// take the chip select high to de-select:
digitalWriteFast(CSpin, HIGH);
// Now send the 9 dummy commands, reading always safer than writing.
int NUM_DUMMY_CMD = 9;
uint16_t dummyRead;
//Serial.print("Sending dummy commands to complete ADC calibration....");
for (int n = 0; n <= NUM_DUMMY_CMD; n++) {
dummyRead = readRegister(60, CSpin); // reg60: die revision
}
Serial.println(F("Calibrated!"));
}