2222#include <pbsys/status.h>
2323
2424#include "hmi.h"
25- #include "storage.h"
2625
2726/**
2827 * State of incoming program data.
2928 */
3029static struct {
3130 /** Where incoming program data is placed. */
3231 uint8_t slot ;
33- /** Currently downloading. */
34- bool busy ;
35- /** Latest incoming message time. Only relevant while busy. */
32+ /** Latest incoming message time. */
3633 pbio_os_timer_t timer ;
3734} download_state ;
3835
36+ /**
37+ * Polls storage system for timeouts.
38+ *
39+ * This should be called periodically.
40+ */
41+ void pbsys_storage_poll (void ) {
42+ // If we are receiving a program, check for timeout and clear
43+ // busy state if timed out.
44+ if (pbsys_status_test (PBIO_PYBRICKS_STATUS_FILE_IO_IN_PROGRESS )) {
45+ if (pbio_os_timer_is_expired (& download_state .timer )) {
46+ pbsys_status_clear (PBIO_PYBRICKS_STATUS_FILE_IO_IN_PROGRESS );
47+ }
48+ }
49+ }
50+
3951/**
4052 * Map of loaded data. This is kept in memory between successive runs of the
4153 * end user application (like MicroPython).
@@ -252,19 +264,25 @@ pbio_error_t pbsys_storage_set_program_size(uint32_t new_size) {
252264 // Pybricks Code sends size 0 to clear the state before sending the new
253265 // program, then sends the size on completion.
254266 if (new_size == 0 ) {
255- if (! pbsys_storage_slot_change_is_allowed ( )) {
267+ if (pbsys_status_test ( PBIO_PYBRICKS_STATUS_FILE_IO_IN_PROGRESS )) {
256268 // Cannot start a new download while another is in progress.
257269 return PBIO_ERROR_INVALID_OP ;
258270 }
259271
260272 pbsys_storage_prepare_receive ();
261273
262- // Keep track of busy state to disallow some operations while busy.
263- download_state . busy = true ;
274+ // Set busy status to disallow some operations while busy.
275+ pbsys_status_set ( PBIO_PYBRICKS_STATUS_FILE_IO_IN_PROGRESS ) ;
264276 pbio_os_timer_set (& download_state .timer , 1000 );
265277 return PBIO_SUCCESS ;
266278 }
267279
280+ // This is also called on completion of the program download, in which
281+ // case we expect that a download is in progress.
282+ if (!pbsys_status_test (PBIO_PYBRICKS_STATUS_FILE_IO_IN_PROGRESS )) {
283+ return PBIO_ERROR_INVALID_OP ;
284+ }
285+
268286 // Expecting that the slot has been cleared as per the above.
269287 if (download_state .slot >= PBSYS_CONFIG_STORAGE_NUM_SLOTS || map -> slot_info [download_state .slot ].size != 0 ) {
270288 return PBIO_ERROR_FAILED ;
@@ -278,29 +296,11 @@ pbio_error_t pbsys_storage_set_program_size(uint32_t new_size) {
278296
279297 // Program download complete, so request saving on poweroff.
280298 pbsys_storage_request_write ();
281- download_state .busy = false;
282299
283- return PBIO_SUCCESS ;
284- }
300+ // Clear busy status.
301+ pbsys_status_clear ( PBIO_PYBRICKS_STATUS_FILE_IO_IN_PROGRESS );
285302
286- /**
287- * Tests whether a slot change is allowed.
288- *
289- * @return True when allowed, false if not, i.e. when new a new program is being downloaded.
290- */
291- bool pbsys_storage_slot_change_is_allowed (void ) {
292- #if !PBSYS_CONFIG_HMI_NUM_SLOTS
293- return false;
294- #endif
295-
296- if (download_state .busy && pbio_os_timer_is_expired (& download_state .timer )) {
297- // Download must have been interrupted midway through. Give up
298- // and unblock anything waiting on download to complete.
299- download_state .busy = false;
300- }
301-
302- // Slot change is allowed when no longer busy.
303- return !download_state .busy ;
303+ return PBIO_SUCCESS ;
304304}
305305
306306/**
@@ -328,7 +328,7 @@ pbio_error_t pbsys_storage_set_program_data(uint32_t offset, const void *data, u
328328 }
329329
330330 // A program transfer should have been started.
331- if (!download_state . busy ) {
331+ if (!pbsys_status_test ( PBIO_PYBRICKS_STATUS_FILE_IO_IN_PROGRESS ) ) {
332332 return PBIO_ERROR_INVALID_OP ;
333333 }
334334
0 commit comments