1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

drivers/mtd_spi_nor: implement mtd_spi_nor_write_page()

This commit is contained in:
Benjamin Valentin 2020-05-07 15:07:47 +02:00
parent c436c39ea8
commit 68a47b63e3

View File

@ -56,6 +56,8 @@
#define MBIT_AS_BYTES ((1024 * 1024) / 8)
#define MIN(a, b) ((a) > (b) ? (b) : (a))
/**
* @brief JEDEC memory manufacturer ID codes.
*
@ -75,14 +77,6 @@ static int mtd_spi_nor_write(mtd_dev_t *mtd, const void *src, uint32_t addr, uin
static int mtd_spi_nor_erase(mtd_dev_t *mtd, uint32_t addr, uint32_t size);
static int mtd_spi_nor_power(mtd_dev_t *mtd, enum mtd_power_state power);
const mtd_desc_t mtd_spi_nor_driver = {
.init = mtd_spi_nor_init,
.read = mtd_spi_nor_read,
.write = mtd_spi_nor_write,
.erase = mtd_spi_nor_erase,
.power = mtd_spi_nor_power,
};
static void mtd_spi_acquire(const mtd_spi_nor_t *dev)
{
spi_acquire(dev->params->spi, dev->params->cs,
@ -464,7 +458,7 @@ static int mtd_spi_nor_read(mtd_dev_t *mtd, void *dest, uint32_t addr, uint32_t
DEBUG("mtd_spi_nor_read: %p, %p, 0x%" PRIx32 ", 0x%" PRIx32 "\n",
(void *)mtd, dest, addr, size);
const mtd_spi_nor_t *dev = (mtd_spi_nor_t *)mtd;
size_t chipsize = mtd->page_size * mtd->pages_per_sector * mtd->sector_count;
uint32_t chipsize = mtd->page_size * mtd->pages_per_sector * mtd->sector_count;
if (addr > chipsize) {
return -EOVERFLOW;
}
@ -521,6 +515,35 @@ static int mtd_spi_nor_write(mtd_dev_t *mtd, const void *src, uint32_t addr, uin
return 0;
}
static int mtd_spi_nor_write_page(mtd_dev_t *mtd, const void *src, uint32_t page, uint32_t offset,
uint32_t size)
{
const mtd_spi_nor_t *dev = (mtd_spi_nor_t *)mtd;
DEBUG("mtd_spi_nor_write_page: %p, %p, 0x%" PRIx32 ", 0x%" PRIx32 ", 0x%" PRIx32 "\n",
(void *)mtd, src, page, offset, size);
uint32_t remaining = mtd->page_size - offset;
size = MIN(remaining, size);
be_uint32_t addr_be = byteorder_htonl(page * mtd->page_size + offset);
mtd_spi_acquire(dev);
/* write enable */
mtd_spi_cmd(dev, dev->params->opcode->wren);
/* Page program */
mtd_spi_cmd_addr_write(dev, dev->params->opcode->page_program, addr_be, src, size);
/* waiting for the command to complete before returning */
wait_for_write_complete(dev, 0);
mtd_spi_release(dev);
return size;
}
static int mtd_spi_nor_erase(mtd_dev_t *mtd, uint32_t addr, uint32_t size)
{
DEBUG("mtd_spi_nor_erase: %p, 0x%" PRIx32 ", 0x%" PRIx32 "\n",
@ -619,3 +642,12 @@ static int mtd_spi_nor_power(mtd_dev_t *mtd, enum mtd_power_state power)
return 0;
}
const mtd_desc_t mtd_spi_nor_driver = {
.init = mtd_spi_nor_init,
.read = mtd_spi_nor_read,
.write = mtd_spi_nor_write,
.write_page = mtd_spi_nor_write_page,
.erase = mtd_spi_nor_erase,
.power = mtd_spi_nor_power,
};