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
- #include "components/spi_flash/include/esp_partition.h"
41
+ #include "esp_ota_ops.h"
42
+ #include "esp_partition.h"
41
43
44
+ #include "supervisor/filesystem.h"
42
45
#include "supervisor/flash.h"
43
46
#include "supervisor/usb.h"
44
47
45
- STATIC const esp_partition_t * _partition ;
48
+ #define OP_READ 0
49
+ #define OP_WRITE 1
46
50
47
51
// TODO: Split the caching out of supervisor/shared/external_flash so we can use it.
48
52
#define SECTOR_SIZE 4096
49
53
STATIC uint8_t _cache [SECTOR_SIZE ];
50
54
STATIC uint32_t _cache_lba = 0xffffffff ;
51
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
+
52
72
void supervisor_flash_init (void ) {
53
- _partition = esp_partition_find_first (ESP_PARTITION_TYPE_DATA ,
73
+ if (_partition [0 ] != NULL ) {
74
+ return ;
75
+ }
76
+ _partition [0 ] = esp_partition_find_first (ESP_PARTITION_TYPE_DATA ,
54
77
ESP_PARTITION_SUBTYPE_DATA_FAT ,
55
78
NULL );
79
+ #if CIRCUITPY_STORAGE_EXTEND
80
+ _partition [1 ] = esp_ota_get_next_update_partition (NULL );
81
+ #endif
56
82
}
57
83
58
84
uint32_t supervisor_flash_get_block_size (void ) {
59
85
return FILESYSTEM_BLOCK_SIZE ;
60
86
}
61
87
62
88
uint32_t supervisor_flash_get_block_count (void ) {
63
- return _partition -> size / FILESYSTEM_BLOCK_SIZE ;
89
+ #if CIRCUITPY_STORAGE_EXTEND
90
+ return ((storage_extended ) ? (_partition [0 ]-> size + _partition [1 ]-> size ) : _partition [0 ]-> size ) / FILESYSTEM_BLOCK_SIZE ;
91
+ #else
92
+ return _partition [0 ]-> size / FILESYSTEM_BLOCK_SIZE ;
93
+ #endif
64
94
}
65
95
66
96
void port_internal_flash_flush (void ) {
97
+ }
67
98
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
+ }
108
+
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 ) {
112
+ if (offset > _partition [0 ]-> size ) {
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 );
131
+ }
68
132
}
133
+ #endif
69
134
70
135
mp_uint_t supervisor_flash_read_blocks (uint8_t * dest , uint32_t block , uint32_t num_blocks ) {
71
- esp_partition_read (_partition ,
72
- block * FILESYSTEM_BLOCK_SIZE ,
73
- dest ,
74
- num_blocks * FILESYSTEM_BLOCK_SIZE );
75
- return 0 ;
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
76
144
}
77
145
78
146
mp_uint_t supervisor_flash_write_blocks (const uint8_t * src , uint32_t lba , uint32_t num_blocks ) {
@@ -82,12 +150,8 @@ mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32
82
150
uint32_t block_address = lba + block ;
83
151
uint32_t sector_offset = block_address / blocks_per_sector * SECTOR_SIZE ;
84
152
uint8_t block_offset = block_address % blocks_per_sector ;
85
-
86
153
if (_cache_lba != block_address ) {
87
- esp_partition_read (_partition ,
88
- sector_offset ,
89
- _cache ,
90
- SECTOR_SIZE );
154
+ supervisor_flash_read_blocks (_cache , sector_offset / FILESYSTEM_BLOCK_SIZE , blocks_per_sector );
91
155
_cache_lba = sector_offset ;
92
156
}
93
157
for (uint8_t b = block_offset ; b < blocks_per_sector ; b ++ ) {
@@ -100,15 +164,34 @@ mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32
100
164
FILESYSTEM_BLOCK_SIZE );
101
165
block ++ ;
102
166
}
103
- esp_partition_erase_range ( _partition , sector_offset , SECTOR_SIZE );
104
- esp_partition_write ( _partition ,
105
- sector_offset ,
106
- _cache ,
107
- SECTOR_SIZE );
167
+ #if CIRCUITPY_STORAGE_EXTEND
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 );
171
+ #endif
108
172
}
109
-
110
173
return 0 ; // success
111
174
}
112
175
113
176
void supervisor_flash_release_cache (void ) {
114
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