drivers: flash: nrf_qspi_nor: Fix writing from unaligned RAM buffers
Flash API states that drivers should support write requests without any restrictions on location or alignment of the source buffer. Due to hardware limitations of the QSPI peripheral, the nrf_qspi_nor driver currently fails to perform a write from a RAM buffer that is not word-aligned. Fix this by using in such case the same mechanism that is used when the source buffer is located in the internal flash (copy data to a buffer located on stack). Also correct the length parameter for writes from this stack-based buffer to be the actual data chunk length, not always the size of the buffer (as for CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE > 4 this may lead to overwriting of some data located next in the flash). Signed-off-by: Andrzej Głąbek <andrzej.glabek@nordicsemi.no>
This commit is contained in:
parent
9be7b59b4a
commit
41c33d7f32
2 changed files with 14 additions and 12 deletions
|
@ -28,14 +28,15 @@ config NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE
|
|||
size (65536). Other option include the sector size (4096).
|
||||
|
||||
config NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE
|
||||
int "Size of a stack-based buffer to support writes from NVMC"
|
||||
int "Size of a stack-based buffer to handle writes not supported by QSPI"
|
||||
default 4
|
||||
help
|
||||
The QSPI peripheral uses DMA and cannot write data that is
|
||||
read from the internal flash. A non-zero value here enables
|
||||
a stack buffer into which data is copied to allow the write
|
||||
to proceed. Multiple transfers will be initiated if the
|
||||
data is larger than the configured limit. Must be a
|
||||
multiple of 4. The feature is disabled when set to 0.
|
||||
The QSPI peripheral uses DMA and can only write data that is read
|
||||
from a word-aligned location in RAM. A non-zero value here enables
|
||||
a stack buffer to be used for any source data that does not meet
|
||||
these restrictions. Such data will be copied into this buffer to
|
||||
allow the write to proceed. Multiple transfers will be initiated
|
||||
if the data is larger than the configured size.
|
||||
Must be a multiple of 4. When set to 0, the feature is disabled.
|
||||
|
||||
endif # NORDIC_QSPI_NOR
|
||||
|
|
|
@ -1060,8 +1060,8 @@ BUILD_ASSERT((CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE % 4) == 0,
|
|||
*
|
||||
* If not enabled return the error the peripheral would have produced.
|
||||
*/
|
||||
static inline nrfx_err_t write_from_nvmc(const struct device *dev, off_t addr,
|
||||
const void *sptr, size_t slen)
|
||||
static nrfx_err_t write_through_buffer(const struct device *dev, off_t addr,
|
||||
const void *sptr, size_t slen)
|
||||
{
|
||||
nrfx_err_t res = NRFX_SUCCESS;
|
||||
|
||||
|
@ -1073,7 +1073,7 @@ static inline nrfx_err_t write_from_nvmc(const struct device *dev, off_t addr,
|
|||
size_t len = MIN(slen, sizeof(buf));
|
||||
|
||||
memcpy(buf, sp, len);
|
||||
res = nrfx_qspi_write(buf, sizeof(buf), addr);
|
||||
res = nrfx_qspi_write(buf, len, addr);
|
||||
qspi_wait_for_completion(dev, res);
|
||||
|
||||
if (res == NRFX_SUCCESS) {
|
||||
|
@ -1131,8 +1131,9 @@ static int qspi_nor_write(const struct device *dev, off_t addr,
|
|||
if (!res) {
|
||||
if (size < 4U) {
|
||||
res = write_sub_word(dev, addr, src, size);
|
||||
} else if (!nrfx_is_in_ram(src)) {
|
||||
res = write_from_nvmc(dev, addr, src, size);
|
||||
} else if (!nrfx_is_in_ram(src) ||
|
||||
!nrfx_is_word_aligned(src)) {
|
||||
res = write_through_buffer(dev, addr, src, size);
|
||||
} else {
|
||||
res = nrfx_qspi_write(src, size, addr);
|
||||
qspi_wait_for_completion(dev, res);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue