COSA
An Object-Oriented Platform for Arduino Programming
S25FL127S.cpp
Go to the documentation of this file.
1 
21 #include "S25FL127S.hh"
22 
23 bool
25 {
26  // Check that the device is ready
27  if (!is_ready()) return (false);
28 
29  // Read identification
30  spi.acquire(this);
31  spi.begin();
33  spi.transfer(0);
34  spi.transfer(0);
35  spi.transfer(0);
36  uint8_t manufacturer = spi.transfer(0);
37  uint8_t device = spi.transfer(0);
38  spi.end();
39  spi.release();
40 
41  // And check
42  return (manufacturer == MANUFACTURER && device == DEVICE);
43 }
44 
45 bool
47 {
48  // Read Status Register 1
49  spi.acquire(this);
50  spi.begin();
52  m_status = spi.transfer(0);
53  spi.end();
54  spi.release();
55 
56  // Return Write-In-Progress is off
57  return (!m_status.WIP);
58 }
59 
60 int
61 S25FL127S::read(void* dest, uint32_t src, size_t size)
62 {
63  // Use READ with 24-bit address; Big-endian
64  uint8_t* sp = (uint8_t*) &src;
65  int res = (int) size;
66  spi.acquire(this);
67  spi.begin();
68  spi.transfer(READ);
69  spi.transfer(sp[2]);
70  spi.transfer(sp[1]);
71  spi.transfer(sp[0]);
72  spi.read(dest, size);
73  spi.end();
74  spi.release();
75 
76  // Return number of bytes read
77  return (res);
78 }
79 
80 int
81 S25FL127S::erase(uint32_t dest, uint8_t size)
82 {
83  uint8_t op;
84  switch (size) {
85  case 4: op = P4E; break;
86  case 64: op = SER; break;
87  case 255: op = BER; break;
88  default: return (EINVAL);
89  }
90  spi.acquire(this);
91  // Write enable before page erase.
92  spi.begin();
93  spi.transfer(WREN);
94  spi.end();
95  // Use erase(P4E/SER/BER) with possible 24-bit address; Big-endian
96  uint8_t* dp = (uint8_t*) &dest;
97  spi.begin();
98  spi.transfer(op);
99  if (op != BER) {
100  spi.transfer(dp[2]);
101  spi.transfer(dp[1]);
102  spi.transfer(dp[0]);
103  }
104  spi.end();
105  spi.release();
106 
107  // Wait for completion
108  while (!is_ready()) yield();
109 
110  // Return error code(-1) if erase error otherwise zero
111  return (m_status.E_ERR ? EFAULT : 0);
112 }
113 
114 int
115 S25FL127S::write(uint32_t dest, const void* src, size_t size)
116 {
117  // Check for zero buffer size
118  if (UNLIKELY(size == 0)) return (0);
119 
120  // Set up destination and source pointers
121  uint8_t* dp = (uint8_t*) &dest;
122  uint8_t* sp = (uint8_t*) src;
123  int res = (int) size;
124 
125  // Calculate block size of first program
126  size_t count = PAGE_MAX - (dest & PAGE_MASK);
127  if (UNLIKELY(count > size)) count = size;
128 
129  while (1) {
130  spi.acquire(this);
131  // Write enable before program
132  spi.begin();
133  spi.transfer(WREN);
134  spi.end();
135  // Use PP with 24-bit address; Big-endian
136  spi.begin();
137  spi.transfer(PP);
138  spi.transfer(dp[2]);
139  spi.transfer(dp[1]);
140  spi.transfer(dp[0]);
141  spi.write(sp, count);
142  spi.end();
143  spi.release();
144 
145  // Wait for completion
146  while (!is_ready()) yield();
147 
148  // Check for program error
149  if (UNLIKELY(m_status.P_ERR)) return (EFAULT);
150 
151  // Step to next page
152  size -= count;
153  if (UNLIKELY(size == 0)) break;
154  dest += count;
155  sp += count;
156  count = (size > PAGE_MAX ? PAGE_MAX : size);
157  }
158 
159  // Return number of bytes programmed
160  return (res);
161 }
162 
163 int
164 S25FL127S::write_P(uint32_t dest, const void* src, size_t size)
165 {
166  // Check for zero buffer size
167  if (UNLIKELY(size == 0)) return (0);
168 
169  // Set up destination and source pointers
170  uint8_t* dp = (uint8_t*) &dest;
171  uint8_t* sp = (uint8_t*) src;
172  int res = (int) size;
173 
174  // Calculate block size of first program
175  size_t count = PAGE_MAX - (dest & PAGE_MASK);
176  if (UNLIKELY(count > size)) count = size;
177 
178  while (1) {
179  spi.acquire(this);
180  // Write enable before program
181  spi.begin();
182  spi.transfer(WREN);
183  spi.end();
184  // Use PP with 24-bit address; Big-endian
185  spi.begin();
186  spi.transfer(PP);
187  spi.transfer(dp[2]);
188  spi.transfer(dp[1]);
189  spi.transfer(dp[0]);
190  spi.write_P(sp, count);
191  spi.end();
192  spi.release();
193 
194  // Wait for completion
195  while (!is_ready()) yield();
196 
197  // Check for program error
198  if (UNLIKELY(m_status.P_ERR)) return (EFAULT);
199 
200  // Step to next page
201  size -= count;
202  if (UNLIKELY(size == 0)) break;
203  dest += count;
204  sp += count;
205  count = (size > PAGE_MAX ? PAGE_MAX : size);
206  }
207 
208  // Return number of bytes programmed
209  return (res);
210 }
211 
212 uint8_t
214 {
215  spi.acquire(this);
216  spi.begin();
217  spi.transfer(cmd);
218  uint8_t res = spi.transfer(0);
219  spi.end();
220  spi.release();
221  return (res);
222 }
virtual int write_P(uint32_t dest, const void *buf, size_t size)
Definition: S25FL127S.cpp:164
#define EINVAL
Definition: Errno.h:49
virtual int read(void *dest, uint32_t src, size_t size)
Definition: S25FL127S.cpp:61
uint8_t transfer(uint8_t data)
Definition: SOFT_SPI.cpp:87
uint8_t WIP
< As bit-fields.
Definition: S25FL127S.hh:168
virtual int erase(uint32_t dest, uint8_t size=4)
Definition: S25FL127S.cpp:81
void acquire(Driver *dev)
Definition: SOFT_SPI.cpp:43
uint8_t E_ERR
Erase Error Occurred.
Definition: S25FL127S.hh:171
void read(void *buf, size_t count)
Definition: SPI.hh:308
Page Program (3- or 4-byte address).
Definition: S25FL127S.hh:269
uint8_t issue(Command cmd)
Definition: S25FL127S.cpp:213
uint8_t P_ERR
Programming Error Occurred.
Definition: S25FL127S.hh:172
status1_t m_status
Definition: S25FL127S.hh:322
static const uint8_t MANUFACTURER
Definition: S25FL127S.hh:309
Read Electronic Manufacturer Signature.
Definition: S25FL127S.hh:232
Bulk Erase.
Definition: S25FL127S.hh:279
Parameter 4-kB, sector erase.
Definition: S25FL127S.hh:277
void write(const void *buf, size_t count)
Definition: SPI.hh:321
static const size_t PAGE_MASK
Definition: S25FL127S.hh:45
void(* yield)()
void begin()
Definition: SPI.hh:216
void end()
Definition: SPI.hh:226
virtual bool begin()
Definition: S25FL127S.cpp:24
static const size_t PAGE_MAX
Definition: S25FL127S.hh:44
Read Status Register#1.
Definition: S25FL127S.hh:238
virtual bool is_ready()
Definition: S25FL127S.cpp:46
Read (3- or 4-byte address).
Definition: S25FL127S.hh:255
void write_P(const uint8_t *buf, size_t count)
Definition: SPI.hh:334
SPI spi
Definition: SPI.cpp:29
void release()
Definition: SOFT_SPI.cpp:64
virtual int write(uint32_t dest, const void *src, size_t size)
Definition: S25FL127S.cpp:115
static const uint8_t DEVICE
Definition: S25FL127S.hh:312
#define UNLIKELY(x)
Definition: Types.h:153
Erase 64 kB or 256 kB.
Definition: S25FL127S.hh:280
#define EFAULT
Definition: Errno.h:41
Write Enable.
Definition: S25FL127S.hh:243