-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathOTSR-FLASH-Arduino.ino
207 lines (186 loc) · 5.25 KB
/
OTSR-FLASH-Arduino.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
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
204
205
206
207
#include <SPI.h>
#define ENABLE 7
#define LED 9
unsigned char sensor;
#define minSensor 0
#define maxSensor 3
unsigned char CS;
#define minCS 2
#define maxCS 3
unsigned long address;
bool memFull;
#define memMarker 0x00000
#define minAddress 0x00004
#define maxAddress 0xFFFFE
void setup()
{
Serial.begin(9600);
pinMode(ENABLE, INPUT);
pinMode(LED, OUTPUT);
digitalWrite(LED, LOW);
// Initialize SPI
SPI.begin();
for (int i = minCS; i <= maxCS; i++)
{
pinMode(i, OUTPUT);
digitalWrite(i, HIGH);
}
SPI.beginTransaction(SPISettings(25000000, MSBFIRST, SPI_MODE0));
// Initialize STATUS registers
for (int i = minCS; i <= maxCS; i++)
{
digitalWrite(i, LOW);
SPI.transfer(0x50); // Instruction to enable write STATUS register
digitalWrite(i, HIGH);
digitalWrite(i, LOW);
SPI.transfer(0x01); // Instruction to write STATUS register
SPI.transfer(0); // Set all bits in the STATUS register to 0
digitalWrite(i, HIGH);
}
Serial.println("Searching for starting memory location...");
// Find starting memory location
for (CS = minCS; CS <= maxCS; CS++)
{
if (read4Bytes(CS, memMarker) == 0) continue; // Marker indicates chip memory is full
digitalWrite(CS, LOW);
SPI.transfer(0x03); // Instruction to read memory
send3Bytes(minAddress); // Send starting address
for (address = minAddress; address <= maxAddress; address += 2)
{
if (SPI.transfer16(0) == -1) break;
}
digitalWrite(CS, HIGH);
if (address > maxAddress)
{
// If chip memory is full, set marker
write4Bytes(CS, memMarker, 0);
}
else
{
break;
}
}
memFull = (CS > maxCS);
if (memFull)
{
Serial.println("No memory available.");
}
else
{
Serial.print("CS: ");
Serial.print(CS);
Serial.print("; address: ");
Serial.println(address, HEX);
}
// Initialize sensor
sensor = minSensor;
}
void loop()
{
if (memFull)
{
digitalWrite(LED, HIGH);
}
else if (digitalRead(ENABLE))
{
// Check address
if (address > maxAddress)
{
write4Bytes(CS, memMarker, 0); // Set marker to indicate chip memory is full
CS++; // Go to next chip
address = minAddress; // Reset address
}
// Check CS
memFull = (CS > maxCS);
// Proceed to read/write sensor data
if (!memFull)
{
if (sensor > maxSensor) sensor = minSensor; // Check/reset sensor number
write2Bytes(CS, address, (analogRead(sensor + 14) << 4) + sensor); // Combine reading and sensor into one 16-bit value
address += 2; // Increment address
sensor++; // Increment sensor number
}
}
}
// Read four bytes from device memory
unsigned long read4Bytes(unsigned char chip, unsigned long add)
{
unsigned long output = 0;
digitalWrite(chip, LOW);
SPI.transfer(0x03); // Instruction to read memory
send3Bytes(add); // Send address
for (int i = 1; i <= 4; i++)
{
// Read next byte and append it to output
output = (output << 8) + SPI.transfer(0);
}
digitalWrite(chip, HIGH);
return output;
}
// Write four bytes to device memory
void write4Bytes(unsigned char chip, unsigned long add, unsigned long data)
{
writeByte(chip, add, data >> 24);
add++;
writeByte(chip, add, data >> 16);
add++;
writeByte(chip, add, data >> 8);
add++;
writeByte(chip, add, data);
}
// Write two bytes to device memory
void write2Bytes(unsigned char chip, unsigned long add, unsigned int data)
{
writeByte(chip, add, data >> 8);
add++;
writeByte(chip, add, data);
}
// Write one byte to device memory
void writeByte(unsigned char chip, unsigned long add, unsigned char data)
{
digitalWrite(chip, LOW);
SPI.transfer(0x06); // Instruction to write enable
digitalWrite(chip, HIGH);
digitalWrite(chip, LOW);
SPI.transfer(0x02); // Instruction to program one byte
send3Bytes(add); // Send address
SPI.transfer(data); // Send data byte
digitalWrite(chip, HIGH);
}
// Send 3 bytes; useful for address
void send3Bytes(unsigned long send)
{
SPI.transfer(send >> 16);
SPI.transfer(send >> 8);
SPI.transfer(send);
}
// Erase full memory array for all chips
void eraseChips()
{
for (int i = minCS; i <= maxCS; i++)
{
digitalWrite(i, LOW);
SPI.transfer(0x06); // Instruction to write enable
digitalWrite(i, HIGH);
digitalWrite(i, LOW);
SPI.transfer(0x60); // Instruction to erase full memory array
digitalWrite(i, HIGH);
}
}
// Testing functions --------------------------------------------------
void printBytes(unsigned char chip, unsigned long add, int num)
{
unsigned char output;
digitalWrite(chip, LOW);
SPI.transfer(0x03);
send3Bytes(add);
for (int i = 1; i <= num; i++)
{
output = SPI.transfer(0);
if (output >> 4 == 0) Serial.print('0');
Serial.print(output, HEX);
Serial.print(' ');
}
digitalWrite(chip, HIGH);
Serial.println();
}