24
24
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25
25
* THE SOFTWARE.
26
26
*/
27
+
27
28
#include "supervisor/internal_flash.h"
28
29
29
30
#include <stdint.h>
32
33
33
34
#include "extmod/vfs.h"
34
35
#include "extmod/vfs_fat.h"
36
+
35
37
#include "py/mphal.h"
36
38
#include "py/obj.h"
37
39
#include "py/runtime.h"
38
- #include "lib/oofatfs/ff.h"
39
40
40
41
#include "esp_ota_ops.h"
41
42
#include "esp_partition.h"
42
43
44
+ #include "supervisor/filesystem.h"
43
45
#include "supervisor/flash.h"
44
46
#include "supervisor/usb.h"
45
47
46
- #if CIRCUITPY_STORAGE_EXTEND
47
- #define PARTITION_NUM (2)
48
- #else
49
- #define PARTITION_NUM (1)
50
- #endif
51
-
52
- STATIC const esp_partition_t * _partition [PARTITION_NUM ];
48
+ #define OP_READ 0
49
+ #define OP_WRITE 1
53
50
54
51
// TODO: Split the caching out of supervisor/shared/external_flash so we can use it.
55
52
#define SECTOR_SIZE 4096
56
53
STATIC uint8_t _cache [SECTOR_SIZE ];
57
54
STATIC uint32_t _cache_lba = 0xffffffff ;
58
55
56
+ #if CIRCUITPY_STORAGE_EXTEND
57
+ #if FF_MAX_SS == FF_MIN_SS
58
+ #define SECSIZE (fs ) (FF_MIN_SS)
59
+ #else
60
+ #define SECSIZE (fs ) ((fs)->ssize)
61
+ #endif // FF_MAX_SS == FF_MIN_SS
62
+ STATIC DWORD fatfs_bytes (void ) {
63
+ FATFS * fatfs = filesystem_circuitpy ();
64
+ return (fatfs -> csize * SECSIZE (fatfs )) * (fatfs -> n_fatent - 2 );
65
+ }
66
+ STATIC bool storage_extended = true;
67
+ STATIC const esp_partition_t * _partition [2 ];
68
+ #else
69
+ STATIC const esp_partition_t * _partition [1 ];
70
+ #endif // CIRCUITPY_STORAGE_EXTEND
71
+
59
72
void supervisor_flash_init (void ) {
73
+ if (_partition [0 ] != NULL ) {
74
+ return ;
75
+ }
60
76
_partition [0 ] = esp_partition_find_first (ESP_PARTITION_TYPE_DATA ,
61
77
ESP_PARTITION_SUBTYPE_DATA_FAT ,
62
78
NULL );
@@ -71,38 +87,60 @@ uint32_t supervisor_flash_get_block_size(void) {
71
87
72
88
uint32_t supervisor_flash_get_block_count (void ) {
73
89
#if CIRCUITPY_STORAGE_EXTEND
74
- return (_partition [0 ]-> size + _partition [1 ]-> size ) / FILESYSTEM_BLOCK_SIZE ;
90
+ return (( storage_extended ) ? ( _partition [0 ]-> size + _partition [1 ] -> size ) : _partition [ 0 ]-> size ) / FILESYSTEM_BLOCK_SIZE ;
75
91
#else
76
92
return _partition [0 ]-> size / FILESYSTEM_BLOCK_SIZE ;
77
93
#endif
78
94
}
79
95
80
96
void port_internal_flash_flush (void ) {
81
-
82
97
}
83
98
84
- mp_uint_t supervisor_flash_read_blocks (uint8_t * dest , uint32_t block , uint32_t num_blocks ) {
85
- uint32_t offset = block * FILESYSTEM_BLOCK_SIZE ;
86
- uint32_t read_total = num_blocks * FILESYSTEM_BLOCK_SIZE ;
99
+ STATIC void single_partition_rw (const esp_partition_t * partition , uint8_t * data ,
100
+ const uint32_t offset , const uint32_t size_total , const bool op ) {
101
+ if (op == OP_READ ) {
102
+ esp_partition_read (partition , offset , data , size_total );
103
+ } else {
104
+ esp_partition_erase_range (partition , offset , size_total );
105
+ esp_partition_write (partition , offset , _cache , size_total );
106
+ }
107
+ }
87
108
88
- #if CIRCUITPY_STORAGE_EXTEND
109
+ #if CIRCUITPY_STORAGE_EXTEND
110
+ STATIC void multi_partition_rw (uint8_t * data ,
111
+ const uint32_t offset , const uint32_t size_total , const bool op ) {
89
112
if (offset > _partition [0 ]-> size ) {
90
- // only read from partition 1
91
- esp_partition_read (_partition [1 ], (offset - _partition [0 ]-> size ), dest , read_total );
92
- } else if ((offset + read_total ) > _partition [0 ]-> size ) {
93
- // first read from partition 0, then partition 1
94
- uint32_t read_0 = _partition [0 ]-> size - offset ;
95
- uint32_t read_1 = read_total - read_0 ;
96
- esp_partition_read (_partition [0 ], offset , dest , read_0 );
97
- esp_partition_read (_partition [1 ], 0 , (dest + read_0 ), read_1 );
98
- } else
99
- #endif
100
- {
101
- // only read from partition 0
102
- esp_partition_read (_partition [0 ], offset , dest , read_total );
113
+ // only r/w partition 1
114
+ single_partition_rw (_partition [1 ], data , (offset - _partition [0 ]-> size ), size_total , op );
115
+ } else if ((offset + size_total ) > _partition [0 ]-> size ) {
116
+ // first r/w partition 0, then partition 1
117
+ uint32_t size_0 = _partition [0 ]-> size - offset ;
118
+ uint32_t size_1 = size_total - size_0 ;
119
+ if (op == OP_READ ) {
120
+ esp_partition_read (_partition [0 ], offset , data , size_0 );
121
+ esp_partition_read (_partition [1 ], 0 , (data + size_0 ), size_1 );
122
+ } else {
123
+ esp_partition_erase_range (_partition [0 ], offset , size_0 );
124
+ esp_partition_write (_partition [0 ], offset , _cache , size_0 );
125
+ esp_partition_erase_range (_partition [1 ], 0 , size_1 );
126
+ esp_partition_write (_partition [1 ], 0 , (_cache + size_0 ), size_1 );
127
+ }
128
+ } else {
129
+ // only r/w partition 0
130
+ single_partition_rw (_partition [0 ], data , offset , size_total , op );
103
131
}
132
+ }
133
+ #endif
104
134
105
- return 0 ;
135
+ mp_uint_t supervisor_flash_read_blocks (uint8_t * dest , uint32_t block , uint32_t num_blocks ) {
136
+ const uint32_t offset = block * FILESYSTEM_BLOCK_SIZE ;
137
+ const uint32_t read_total = num_blocks * FILESYSTEM_BLOCK_SIZE ;
138
+ #if CIRCUITPY_STORAGE_EXTEND
139
+ multi_partition_rw (dest , offset , read_total , OP_READ );
140
+ #else
141
+ single_partition_rw (_partition [0 ], dest , offset , read_total , OP_READ );
142
+ #endif
143
+ return 0 ; // success
106
144
}
107
145
108
146
mp_uint_t supervisor_flash_write_blocks (const uint8_t * src , uint32_t lba , uint32_t num_blocks ) {
@@ -112,12 +150,10 @@ mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32
112
150
uint32_t block_address = lba + block ;
113
151
uint32_t sector_offset = block_address / blocks_per_sector * SECTOR_SIZE ;
114
152
uint8_t block_offset = block_address % blocks_per_sector ;
115
-
116
153
if (_cache_lba != block_address ) {
117
154
supervisor_flash_read_blocks (_cache , sector_offset / FILESYSTEM_BLOCK_SIZE , blocks_per_sector );
118
155
_cache_lba = sector_offset ;
119
156
}
120
-
121
157
for (uint8_t b = block_offset ; b < blocks_per_sector ; b ++ ) {
122
158
// Stop copying after the last block.
123
159
if (block >= num_blocks ) {
@@ -128,31 +164,34 @@ mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32
128
164
FILESYSTEM_BLOCK_SIZE );
129
165
block ++ ;
130
166
}
131
-
132
167
#if CIRCUITPY_STORAGE_EXTEND
133
- if (sector_offset > _partition [0 ]-> size ) {
134
- // only write to partition 1
135
- esp_partition_erase_range (_partition [1 ], sector_offset - _partition [0 ]-> size , SECTOR_SIZE );
136
- esp_partition_write (_partition [1 ], sector_offset - _partition [0 ]-> size , _cache , SECTOR_SIZE );
137
- } else if ((sector_offset + SECTOR_SIZE ) > _partition [0 ]-> size ) {
138
- // first write to partition 0, then partition 1
139
- uint32_t write_0 = _partition [0 ]-> size - sector_offset ;
140
- uint32_t write_1 = SECTOR_SIZE - write_0 ;
141
- esp_partition_erase_range (_partition [0 ], sector_offset , write_0 );
142
- esp_partition_write (_partition [0 ], sector_offset , _cache , write_0 );
143
- esp_partition_erase_range (_partition [1 ], 0 , write_1 );
144
- esp_partition_write (_partition [1 ], 0 , _cache + write_0 , write_1 );
145
- } else
168
+ multi_partition_rw (_cache , sector_offset , SECTOR_SIZE , OP_WRITE );
169
+ #else
170
+ single_partition_rw (_partition [0 ], _cache , sector_offset , SECTOR_SIZE , OP_READ );
146
171
#endif
147
- {
148
- // only write to partition 0
149
- esp_partition_erase_range (_partition [0 ], sector_offset , SECTOR_SIZE );
150
- esp_partition_write (_partition [0 ], sector_offset , _cache , SECTOR_SIZE );
151
- }
152
172
}
153
-
154
173
return 0 ; // success
155
174
}
156
175
157
176
void supervisor_flash_release_cache (void ) {
158
177
}
178
+
179
+ void supervisor_flash_set_extended (bool extended ) {
180
+ #if CIRCUITPY_STORAGE_EXTEND
181
+ storage_extended = extended ;
182
+ #endif
183
+ }
184
+
185
+ bool supervisor_flash_get_extended (void ) {
186
+ #if CIRCUITPY_STORAGE_EXTEND
187
+ return storage_extended ;
188
+ #else
189
+ return false;
190
+ #endif
191
+ }
192
+
193
+ void supervisor_flash_update_extended (void ) {
194
+ #if CIRCUITPY_STORAGE_EXTEND
195
+ storage_extended = (_partition [0 ]-> size < fatfs_bytes ());
196
+ #endif
197
+ }
0 commit comments