Shield Code 6.0
Loading...
Searching...
No Matches
AT25M02.cpp
Go to the documentation of this file.
1
12#include <Arduino.h>
13#include <SPI.h>
14#include <AT25M02.hpp>
15
16// Define chip select. MO,MI,SLK all are default values.
17#define CHIP_SELECT_PIN 4
18
19// Arduino to RAM data rate. In Hz.
20#define SPI_DATA_RATE 5000000
21
22// Define RAM parameters
23#define PAGE_LEN 256
24const uint32_t RAM_SIZE = (1L << 18);
25#define NUM_PAGES (RAM_SIZE / PAGE_LEN)
26
27/* // Constructor
28
29AT25M02::AT25M02()
30{
31
32} */
33
34// Public Methods
35
40 // Set up SPI device settings
41 spi_settings = SPISettings(SPI_DATA_RATE, MSBFIRST, SPI_MODE0);
42 // Set pin out information. Could be passed in via constructor params.
44 pinMode(chip_select_pin, OUTPUT);
45 mem_start = 0;
46 mem_end = 0;
47 ram_full = false;
48 wb_end = 0;
49 setWRSR(0x00);
50}
51
56{
57 return RAM_SIZE - usedBytes();
58}
59
64{
66}
67
69{
70 if (mem_end >= mem_start) {
71 return mem_end - mem_start;
72 } else {
73 return (RAM_SIZE - mem_start) + mem_end;
74 }
75}
76
78{
79 return RAM_SIZE - usedMemoryBytes();
80}
81
83{
84 return wb_end;
85}
86
88{
89 return PAGE_LEN - wb_end;
90}
91
92
98bool AT25M02::writeData(byte* bytes, uint32_t length)
99{
100 // Bail out if we don't have enough space
101 if (length > freeBytes() || ram_full) {
102 return false;
103 } else if (length == freeBytes()) {
104 ram_full = true;
105 }
106 // Loop over in the input and move it first to the buffer, and then to
107 // the RAM chip when the write buffer is full.
108 uint32_t buf_len;
109 for(;;) {
110 // Move to bytes to write buffer.
111 buf_len = min(length, freeBufferBytes());
112 //copies given buffer into write buffer
113 //write buffer is 256 byte array
114 memcpy(write_buffer + wb_end, bytes, buf_len);
115 wb_end += buf_len;
116 bytes += buf_len;
117 length -= buf_len;
118 // Break when write buffer is not full.
119 // Breaking means the input buffer is exhausted.
120 if (wb_end != PAGE_LEN) break;
121 // Write to page.
122 // Will be slow when writing multiple pages at once.
125 wb_end = 0;
126 }
127 return true;
128}
129
130uint32_t AT25M02::readWriteBuffer(byte *dest, uint32_t length)
131{
132 uint32_t len = min(length, usedBufferBytes());
133 if (len == 0)
134 return len;
135 memcpy(dest, write_buffer, len);
136 memmove(write_buffer, write_buffer + len, usedBufferBytes() - len);
137 wb_end -= len;
138 return len;
139}
140
141uint32_t AT25M02::readMemory(byte *dest, uint32_t length)
142{
143 uint32_t len = min(length, usedMemoryBytes());
144 if (len == 0)
145 return len;
147
148 // Have to pull out each byte to give to the RAM one at a time
149 byte addr_byte2 = (byte) ((mem_start >> 16) & 0xFF);
150 byte addr_byte1 = (byte) ((mem_start >> 8) & 0xFF);
151 byte addr_byte0 = (byte) (mem_start & 0xFF);
152
153 SPI.beginTransaction(spi_settings);
154 csl();
155 SPI.transfer(READ);
156 SPI.transfer(addr_byte2);
157 SPI.transfer(addr_byte1);
158 SPI.transfer(addr_byte0);
159 SPI.transfer(dest, len);
160 csh();
161 SPI.endTransaction();
162 mem_start += len;
163 ram_full = false;
164 return len;
165}
166
172int AT25M02::readData(byte* dest, uint32_t length)
173{
174 uint32_t memlen = readMemory(dest, length);
175 uint32_t buflen = 0;
176 if (memlen < length) {
177 dest += memlen;
178 length -= memlen;
179 buflen = readWriteBuffer(dest, length);
180 }
181 return memlen + buflen;
182}
183
188{
189 bool ready;
190 SPI.beginTransaction(spi_settings);
191 csl();
192 SPI.transfer(READ_STATUS);
193 // Bit 0 of READ_STATUS response is 0 when the device is ready
194 ready = (SPI.transfer(0) & 0x01) == 0;
195 csh();
196 SPI.endTransaction();
197 return ready;
198}
199
200// Private Methods
201
206void AT25M02::writePage(uint32_t addr, byte* bytes, uint32_t length)
207{
208 // Have to pull out each byte to give to the RAM one at a time
209 byte addr_byte2 = (byte) ((addr >> 16) & 0xFF);
210 byte addr_byte1 = (byte) ((addr >> 8) & 0xFF);
211 byte addr_byte0 = (byte) (addr & 0xFF);
212 // Enable writing
214 // Write everything over SPI
215 SPI.beginTransaction(spi_settings);
216 csl();
217 SPI.transfer(WRITE_PAGE);
218 SPI.transfer(addr_byte2);
219 SPI.transfer(addr_byte1);
220 SPI.transfer(addr_byte0);
221 SPI.transfer(bytes, length);
222 csh();
223 SPI.endTransaction();
224 mem_end += min(PAGE_LEN, length) % RAM_SIZE;
225}
226
227
228/*
229 * Set chip select low
230 */
232{
233 digitalWrite(CHIP_SELECT_PIN, LOW);
234}
235
236/*
237 * Set chip select high
238 */
240{
241 digitalWrite(CHIP_SELECT_PIN, HIGH);
242}
243
244
246{
247 byte ret;
248 SPI.beginTransaction(spi_settings);
249 csl();
250 SPI.transfer(READ_STATUS);
251 ret = SPI.transfer(0);
252 csh();
253 SPI.endTransaction();
254 return ret;
255}
256
257/*
258 * Sends the specified command to the chip.
259 */
261{
262 SPI.beginTransaction(spi_settings);
263 csl();
264 SPI.transfer(cmd);
265 csh();
266 SPI.endTransaction();
267}
268
272void AT25M02::setWRSR(byte val)
273{
276 SPI.beginTransaction(spi_settings);
277 csl();
278 SPI.transfer(0x01);
279 SPI.transfer(val);
280 SPI.transfer(READ_STATUS);
281 volatile byte status = SPI.transfer(0);
282 csh();
283 SPI.endTransaction();
284}
285
290{
291 // TODO: Guard timing w/ DEBUG macro
292 // int startt = micros();
293 SPI.beginTransaction(spi_settings);
294 csl();
295 do {
296 SPI.transfer(READ_STATUS);
297 } while ((SPI.transfer(0) & 0x01) != 0);
298 csh();
299 SPI.endTransaction();
300 // int endt = micros();
301 // char buf[100];
302 // sprintf(buf, "\nwait until ready blocked time %d\n", endt - startt);
303 // Serial.write(buf);
304}
#define SPI_DATA_RATE
Definition: AT25M02.cpp:20
#define PAGE_LEN
Definition: AT25M02.cpp:23
#define CHIP_SELECT_PIN
Definition: AT25M02.cpp:17
const uint32_t RAM_SIZE
Definition: AT25M02.cpp:24
Provides a library to interact with Microchip's AT25M02 chip. This treats the chip as a circular queu...
Command
Commands for the AT25M02 chip. Pulled from the data sheet for this chip. All commands are MSB first.
Definition: AT25M02.hpp:19
@ READ_STATUS
Definition: AT25M02.hpp:20
@ WRITE_ENABLE
Definition: AT25M02.hpp:22
@ READ
Definition: AT25M02.hpp:25
@ WRITE_PAGE
Definition: AT25M02.hpp:27
void setWRSR(byte val)
Sets the WRSR (Write status reg)
Definition: AT25M02.cpp:272
uint32_t freeBufferBytes()
Definition: AT25M02.cpp:87
int readData(byte *dest, uint32_t length)
Write the given number of bytes from the ram into the destination array. These bytes are taken from t...
Definition: AT25M02.cpp:172
uint8_t write_buffer[256]
Definition: AT25M02.hpp:99
void init()
Initialize the AT25M02 EEPROM device. Define spi settings, chip select pin, and set initial variables...
Definition: AT25M02.cpp:39
void writePage(uint32_t addr, byte *bytes, uint32_t length)
Write the given data to the RAM in a page write. Increments mem_end when done.
Definition: AT25M02.cpp:206
void waitUntilReady()
Waits until the RAM is ready to write.
Definition: AT25M02.cpp:289
uint32_t readMemory(byte *dest, uint32_t length)
Definition: AT25M02.cpp:141
SPISettings spi_settings
Definition: AT25M02.hpp:105
uint32_t wb_end
Definition: AT25M02.hpp:100
uint32_t usedMemoryBytes()
Definition: AT25M02.cpp:68
uint32_t mem_end
Definition: AT25M02.hpp:102
bool writeData(byte *bytes, uint32_t length)
Write from the given array to the memory. This data is appended to the end of the queue....
Definition: AT25M02.cpp:98
bool ram_full
Definition: AT25M02.hpp:103
uint32_t mem_start
Definition: AT25M02.hpp:101
uint32_t usedBufferBytes()
Definition: AT25M02.cpp:82
bool isReady()
Checks if the RAM is ready for a new command.
Definition: AT25M02.cpp:187
void csl()
Definition: AT25M02.cpp:231
uint32_t freeBytes()
Returns how many bytes are free and available to be written to.
Definition: AT25M02.cpp:55
uint32_t readWriteBuffer(byte *dest, uint32_t length)
Definition: AT25M02.cpp:130
void sendCommand(Command cmd)
Definition: AT25M02.cpp:260
int chip_select_pin
Definition: AT25M02.hpp:128
void csh()
Definition: AT25M02.cpp:239
uint32_t freeMemoryBytes()
Definition: AT25M02.cpp:77
byte readStatusReg()
Definition: AT25M02.cpp:245
uint32_t usedBytes()
Returns the number of bytes currently being used.
Definition: AT25M02.cpp:63