Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SPI flash API cleanup, add async erase capability. #23894

Merged
merged 3 commits into from
Jul 2, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Cleanup and simplification.
  • Loading branch information
tzarc committed Jun 12, 2024
commit 56f30e2f67a3351390dedb720b8f8a9167cda326
19 changes: 10 additions & 9 deletions drivers/flash/flash.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ enum {
FLASH_STATUS_ERROR = -1, //< An error occurred during the operation.
FLASH_STATUS_TIMEOUT = -2, //< The operation timed out.
FLASH_STATUS_BAD_ADDRESS = -3, //< The address is out of bounds.
FLASH_STATUS_BUSY = -4, //< The flash is busy.
};

/**
Expand All @@ -38,16 +39,16 @@ void flash_init(void);
*
* This function checks if the flash is currently busy with an operation.
*
* @return true if the flash is busy, false otherwise.
* @return FLASH_STATUS_SUCCESS if the flash is not busy, FLASH_STATUS_BUSY if the flash is busy, or FLASH_STATUS_ERROR if an error occurred.
*/
bool flash_is_busy(void);
flash_status_t flash_is_busy(void);

/**
* @brief Initiates a chip erase operation.
*
* This function does not wait for the flash to become ready.
*
* @return FLASH_STATUS_SUCCESS if the erase command was successfully sent, FLASH_STATUS_TIMEOUT if the flash is busy.
* @return FLASH_STATUS_SUCCESS if the erase command was successfully sent, FLASH_STATUS_TIMEOUT if the flash is busy, or FLASH_STATUS_ERROR if an error occurred.
*/
flash_status_t flash_begin_erase_chip(void);

Expand All @@ -56,7 +57,7 @@ flash_status_t flash_begin_erase_chip(void);
*
* This function waits for the chip erase operation to complete.
*
* @return FLASH_STATUS_SUCCESS if the chip erase operation completed successfully, FLASH_STATUS_TIMEOUT if the flash was still busy.
* @return FLASH_STATUS_SUCCESS if the chip erase operation completed successfully, FLASH_STATUS_TIMEOUT if the flash was still busy, or FLASH_STATUS_ERROR if an error occurred.
*/
flash_status_t flash_wait_erase_chip(void);

Expand All @@ -66,7 +67,7 @@ flash_status_t flash_wait_erase_chip(void);
* This function initiates an erase operation to erase the entire flash memory chip.
* It waits for the operation to complete.
*
* @return FLASH_STATUS_SUCCESS if the erase was successfully executed, FLASH_STATUS_TIMEOUT if the flash is busy.
* @return FLASH_STATUS_SUCCESS if the erase was successfully executed, FLASH_STATUS_TIMEOUT if the flash is busy, or FLASH_STATUS_ERROR if an error occurred.
*/
flash_status_t flash_erase_chip(void);

Expand All @@ -78,7 +79,7 @@ flash_status_t flash_erase_chip(void);
*
* @param addr The address of the block to erase.
*
* @return FLASH_STATUS_SUCCESS if the erase was successfully executed, FLASH_STATUS_TIMEOUT if the flash is busy.
* @return FLASH_STATUS_SUCCESS if the erase was successfully executed, FLASH_STATUS_TIMEOUT if the flash is busy, or FLASH_STATUS_ERROR if an error occurred.
*/
flash_status_t flash_erase_block(uint32_t addr);

Expand All @@ -90,7 +91,7 @@ flash_status_t flash_erase_block(uint32_t addr);
*
* @param addr The address of the sector to erase.
*
* @return FLASH_STATUS_SUCCESS if the erase was successfully executed, FLASH_STATUS_TIMEOUT if the flash is busy.
* @return FLASH_STATUS_SUCCESS if the erase was successfully executed, FLASH_STATUS_TIMEOUT if the flash is busy, or FLASH_STATUS_ERROR if an error occurred.
*/
flash_status_t flash_erase_sector(uint32_t addr);

Expand All @@ -103,7 +104,7 @@ flash_status_t flash_erase_sector(uint32_t addr);
* @param buf A pointer to the buffer to read the range into.
* @param len The length of the range to read.
*
* @return FLASH_STATUS_SUCCESS if the range was successfully read, FLASH_STATUS_BAD_ADDRESS if the address is out of bounds.
* @return FLASH_STATUS_SUCCESS if the range was successfully read, FLASH_STATUS_BAD_ADDRESS if the address is out of bounds, FLASH_STATUS_TIMEOUT if the flash is busy, or FLASH_STATUS_ERROR if an error occurred.
*/
flash_status_t flash_read_range(uint32_t addr, void *buf, size_t len);

Expand All @@ -116,7 +117,7 @@ flash_status_t flash_read_range(uint32_t addr, void *buf, size_t len);
* @param buf A pointer to the buffer to write to the range.
* @param len The length of the range to write.
*
* @return FLASH_STATUS_SUCCESS if the range was successfully written, FLASH_STATUS_BAD_ADDRESS if the address is out of bounds.
* @return FLASH_STATUS_SUCCESS if the range was successfully written, FLASH_STATUS_BAD_ADDRESS if the address is out of bounds, FLASH_STATUS_TIMEOUT if the flash is busy, or FLASH_STATUS_ERROR if an error occurred.
*/
flash_status_t flash_write_range(uint32_t addr, const void *buf, size_t len);

Expand Down
34 changes: 12 additions & 22 deletions drivers/flash/flash_spi.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2021 Westberry Technology (ChangZhou) Corp., Ltd

Check failure on line 1 in drivers/flash/flash_spi.c

View workflow job for this annotation

GitHub Actions / lint

Requires Formatting
// Copyright 2024 Nick Brassel (@tzarc)
// SPDX-License-Identifier: GPL-2.0-or-later

Expand Down Expand Up @@ -57,34 +57,25 @@
return spi_start(EXTERNAL_FLASH_SPI_SLAVE_SELECT_PIN, EXTERNAL_FLASH_SPI_LSBFIRST, EXTERNAL_FLASH_SPI_MODE, EXTERNAL_FLASH_SPI_CLOCK_DIVISOR);
}

static flash_status_t spi_flash_wait_while_busy_looped(int counter) {
static flash_status_t spi_flash_wait_while_busy_multiplier(int multiplier) {
flash_status_t response = FLASH_STATUS_SUCCESS;
for (int i = 0; i < counter; ++i) {
uint32_t deadline = timer_read32() + EXTERNAL_FLASH_SPI_TIMEOUT;
bool is_busy;

do {
is_busy = flash_is_busy();
if (timer_read32() >= deadline) {
response = FLASH_STATUS_TIMEOUT;
break;
}
} while (is_busy);

if (!is_busy) {
response = FLASH_STATUS_SUCCESS;
uint32_t deadline = timer_read32() + ((EXTERNAL_FLASH_SPI_TIMEOUT) * multiplier);
do {
if (timer_read32() >= deadline) {
response = FLASH_STATUS_TIMEOUT;
break;
}
}

response = flash_is_busy();
} while (response == FLASH_STATUS_BUSY);
return response;
}

static flash_status_t spi_flash_wait_while_busy(void) {
return spi_flash_wait_while_busy_looped(1);
return spi_flash_wait_while_busy_multiplier(1);
}

bool flash_is_busy(void) {
flash_status_t flash_is_busy(void) {
bool res = spi_flash_start();
if (!res) {
dprint("Failed to start SPI! [spi flash wait while busy]\n");
Expand All @@ -96,11 +87,11 @@
spi_stop();

if (status < 0) {
return false;
return status;
}

uint8_t sr = (uint8_t)status;
return sr & FLASH_FLAG_WIP;
return (sr & FLASH_FLAG_WIP) ? FLASH_STATUS_BUSY : FLASH_STATUS_SUCCESS;
}

static flash_status_t spi_flash_write_enable(void) {
Expand Down Expand Up @@ -200,8 +191,7 @@
}

flash_status_t flash_wait_erase_chip(void) {
flash_status_t response = spi_flash_wait_while_busy_looped(250); // Chip erase can take a long time, wait 250x the usual timeout

flash_status_t response = spi_flash_wait_while_busy_multiplier(250); // Chip erase can take a long time, wait 250x the usual timeout
if (response != FLASH_STATUS_SUCCESS) {
dprint("Failed to check WIP flag! [spi flash erase chip]\n");
return response;
Expand Down
Loading