15
15
*/
16
16
17
17
#include " SPIFBlockDevice.h"
18
-
18
+ # include " mbed_critical.h "
19
19
20
20
// Read/write/erase sizes
21
21
#define SPIF_READ_SIZE 1
@@ -49,14 +49,24 @@ enum ops {
49
49
50
50
SPIFBlockDevice::SPIFBlockDevice (
51
51
PinName mosi, PinName miso, PinName sclk, PinName cs, int freq)
52
- : _spi(mosi, miso, sclk), _cs(cs), _size(0 )
52
+ : _spi(mosi, miso, sclk), _cs(cs), _size(0 ), _is_initialized( false ), _init_ref_count( 0 )
53
53
{
54
54
_cs = 1 ;
55
55
_spi.frequency (freq);
56
56
}
57
57
58
58
int SPIFBlockDevice::init ()
59
59
{
60
+ if (!_is_initialized) {
61
+ _init_ref_count = 0 ;
62
+ }
63
+
64
+ uint32_t val = core_util_atomic_incr_u32 (&_init_ref_count, 1 );
65
+
66
+ if (val != 1 ) {
67
+ return BD_ERROR_OK;
68
+ }
69
+
60
70
// Check for vendor specific hacks, these should move into more general
61
71
// handling when possible. RDID is not used to verify a device is attached.
62
72
uint8_t id[3 ];
@@ -125,15 +135,28 @@ int SPIFBlockDevice::init()
125
135
(table[4 ] << 0 ));
126
136
_size = (density/8 ) + 1 ;
127
137
138
+ _is_initialized = true ;
128
139
return 0 ;
129
140
}
130
141
131
142
int SPIFBlockDevice::deinit ()
132
143
{
144
+ if (!_is_initialized) {
145
+ _init_ref_count = 0 ;
146
+ return 0 ;
147
+ }
148
+
149
+ uint32_t val = core_util_atomic_decr_u32 (&_init_ref_count, 1 );
150
+
151
+ if (val) {
152
+ return 0 ;
153
+ }
154
+
133
155
// Latch write disable just to keep noise
134
156
// from changing the device
135
157
_cmdwrite (SPIF_WRDI, 0 , 0 , 0x0 , NULL );
136
158
159
+ _is_initialized = false ;
137
160
return 0 ;
138
161
}
139
162
@@ -249,6 +272,10 @@ int SPIFBlockDevice::_wren()
249
272
250
273
int SPIFBlockDevice::read (void *buffer, bd_addr_t addr, bd_size_t size)
251
274
{
275
+ if (!_is_initialized) {
276
+ return BD_ERROR_DEVICE_ERROR;
277
+ }
278
+
252
279
// Check the address and size fit onto the chip.
253
280
MBED_ASSERT (is_valid_read (addr, size));
254
281
@@ -261,6 +288,10 @@ int SPIFBlockDevice::program(const void *buffer, bd_addr_t addr, bd_size_t size)
261
288
// Check the address and size fit onto the chip.
262
289
MBED_ASSERT (is_valid_program (addr, size));
263
290
291
+ if (!_is_initialized) {
292
+ return BD_ERROR_DEVICE_ERROR;
293
+ }
294
+
264
295
while (size > 0 ) {
265
296
int err = _wren ();
266
297
if (err) {
@@ -292,6 +323,10 @@ int SPIFBlockDevice::erase(bd_addr_t addr, bd_size_t size)
292
323
// Check the address and size fit onto the chip.
293
324
MBED_ASSERT (is_valid_erase (addr, size));
294
325
326
+ if (!_is_initialized) {
327
+ return BD_ERROR_DEVICE_ERROR;
328
+ }
329
+
295
330
while (size > 0 ) {
296
331
int err = _wren ();
297
332
if (err) {
@@ -336,6 +371,10 @@ bd_size_t SPIFBlockDevice::get_erase_size(bd_addr_t addr) const
336
371
337
372
bd_size_t SPIFBlockDevice::size () const
338
373
{
374
+ if (!_is_initialized) {
375
+ return BD_ERROR_DEVICE_ERROR;
376
+ }
377
+
339
378
return _size;
340
379
}
341
380
0 commit comments