bool m25p16_waitForReady(uint32_t timeoutMillis) { uint32_t time = millis(); while (!m25p16_isReady()) { if (millis() - time > timeoutMillis) { return false; } } return true; }
/** * Write the given buffers to flash sequentially at the current tail address, advancing the tail address after * each write. * * In synchronous mode, waits for the flash to become ready before writing so that every byte requested can be written. * * In asynchronous mode, if the flash is busy, then the write is aborted and the routine returns immediately. * In this case the returned number of bytes written will be less than the total amount requested. * * Modifies the supplied buffer pointers and sizes to reflect how many bytes remain in each of them. * * bufferCount: the number of buffers provided * buffers: an array of pointers to the beginning of buffers * bufferSizes: an array of the sizes of those buffers * sync: true if we should wait for the device to be idle before writes, otherwise if the device is busy the * write will be aborted and this routine will return immediately. * * Returns the number of bytes written */ static uint32_t flashfsWriteBuffers(uint8_t const **buffers, uint32_t *bufferSizes, int bufferCount, bool sync) { uint32_t bytesTotal = 0; int i; for (i = 0; i < bufferCount; i++) { bytesTotal += bufferSizes[i]; } if (!sync && !m25p16_isReady()) { return 0; } uint32_t bytesTotalRemaining = bytesTotal; while (bytesTotalRemaining > 0) { uint32_t bytesTotalThisIteration; uint32_t bytesRemainThisIteration; /* * Each page needs to be saved in a separate program operation, so * if we would cross a page boundary, only write up to the boundary in this iteration: */ if (tailAddress % M25P16_PAGESIZE + bytesTotalRemaining > M25P16_PAGESIZE) { bytesTotalThisIteration = M25P16_PAGESIZE - tailAddress % M25P16_PAGESIZE; } else { bytesTotalThisIteration = bytesTotalRemaining; } // Are we at EOF already? Abort. if (flashfsIsEOF()) { // May as well throw away any buffered data flashfsClearBuffer(); break; } m25p16_pageProgramBegin(tailAddress); bytesRemainThisIteration = bytesTotalThisIteration; for (i = 0; i < bufferCount; i++) { if (bufferSizes[i] > 0) { // Is buffer larger than our write limit? Write our limit out of it if (bufferSizes[i] >= bytesRemainThisIteration) { m25p16_pageProgramContinue(buffers[i], bytesRemainThisIteration); buffers[i] += bytesRemainThisIteration; bufferSizes[i] -= bytesRemainThisIteration; bytesRemainThisIteration = 0; break; } else { // We'll still have more to write after finishing this buffer off m25p16_pageProgramContinue(buffers[i], bufferSizes[i]); bytesRemainThisIteration -= bufferSizes[i]; buffers[i] += bufferSizes[i]; bufferSizes[i] = 0; } } } m25p16_pageProgramFinish(); bytesTotalRemaining -= bytesTotalThisIteration; // Advance the cursor in the file system to match the bytes we wrote flashfsSetTailAddress(tailAddress + bytesTotalThisIteration); /* * We'll have to wait for that write to complete before we can issue the next one, so if * the user requested asynchronous writes, break now. */ if (!sync) break; } return bytesTotal - bytesTotalRemaining; }
/** * Return true if the flash is not currently occupied with an operation. */ bool flashfsIsReady() { return m25p16_isReady(); }