You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ma...@apache.org on 2017/01/20 18:24:56 UTC
[07/12] incubator-mynewt-core git commit: Add offset+len support to
writes
Add offset+len support to writes
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/3f6222cf
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/3f6222cf
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/3f6222cf
Branch: refs/heads/develop
Commit: 3f6222cff16fa25f3d170b95cabe2daf6c9c171c
Parents: 92f8a32
Author: Fabio Utzig <ut...@utzig.org>
Authored: Tue Jan 3 22:59:45 2017 -0200
Committer: Fabio Utzig <ut...@utzig.org>
Committed: Fri Jan 20 07:27:40 2017 -0200
----------------------------------------------------------------------
hw/drivers/flash/src/flash.c | 195 +++++++++++++++++++++++++-------------
1 file changed, 130 insertions(+), 65 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/3f6222cf/hw/drivers/flash/src/flash.c
----------------------------------------------------------------------
diff --git a/hw/drivers/flash/src/flash.c b/hw/drivers/flash/src/flash.c
index 7b4c57a..0ffa2cc 100644
--- a/hw/drivers/flash/src/flash.c
+++ b/hw/drivers/flash/src/flash.c
@@ -67,11 +67,8 @@
#define STATUS_BUSY (1 << 7)
#define STATUS_CMP (1 << 6)
-#define MIN(n, m) (((n) < (m)) ? (n) : (m))
-
/* TODO: make configurable to 512/528 */
#define PAGE_SIZE 512
-#define PAGE_BITS 9
/**
* Reading memory (MEM_READ):
@@ -139,6 +136,8 @@ static struct hal_spi_settings at45db_settings = {
.word_size = HAL_SPI_WORD_SIZE_8BIT,
};
+static uint8_t g_page_buffer[PAGE_SIZE];
+
static struct flash_dev *
cfg_dev(uint8_t id)
{
@@ -160,8 +159,6 @@ static uint8_t read_status(struct flash_dev *flash)
hal_gpio_write(flash->ss_pin, 1);
- //printf("STATUS=[%02x]\n", val);
-
return val;
}
@@ -200,10 +197,65 @@ calc_page_count(uint32_t addr, size_t len)
}
static inline uint32_t
-next_page_addr(uint32_t addr)
+page_start_address(uint32_t addr)
{
/* FIXME: works only for 512? (powers of 2) */
- return (addr & ~(PAGE_SIZE - 1)) + PAGE_SIZE;
+ return (addr & ~(PAGE_SIZE - 1));
+}
+
+static inline uint32_t
+page_next_addr(uint32_t addr)
+{
+ return (page_start_address(addr) + PAGE_SIZE);
+}
+
+/* FIXME: assume buf has enough space? */
+static uint16_t
+read_page(struct flash_dev *dev, uint32_t addr, uint16_t len, uint8_t *buf)
+{
+ uint16_t amount;
+ uint16_t pa;
+ uint16_t ba;
+ uint16_t n;
+ uint8_t val;
+
+ hal_gpio_write(dev->ss_pin, 0);
+
+ hal_spi_tx_val(dev->spi_num, MEM_READ);
+
+ pa = addr / PAGE_SIZE;
+ ba = addr % PAGE_SIZE;
+
+ val = (pa >> 6) & ~0x80;
+ hal_spi_tx_val(dev->spi_num, val);
+
+#if (PAGE_SIZE == 512)
+ val = (pa << 2) | ((ba >> 8) & 1);
+#else
+ val = (pa << 2) | ((ba >> 8) & 3);
+#endif
+ hal_spi_tx_val(dev->spi_num, val);
+
+ hal_spi_tx_val(dev->spi_num, ba);
+
+ hal_spi_tx_val(dev->spi_num, 0xff);
+ hal_spi_tx_val(dev->spi_num, 0xff);
+ hal_spi_tx_val(dev->spi_num, 0xff);
+ hal_spi_tx_val(dev->spi_num, 0xff);
+
+ if (len + ba <= PAGE_SIZE) {
+ amount = len;
+ } else {
+ amount = PAGE_SIZE - ba;
+ }
+
+ for (n = 0; n < amount; n++) {
+ buf[n] = hal_spi_tx_val(dev->spi_num, 0xff);
+ }
+
+ hal_gpio_write(dev->ss_pin, 1);
+
+ return amount;
}
int
@@ -242,10 +294,6 @@ int
flash_read(uint8_t flash_id, uint32_t addr, void *buf, size_t len)
{
struct flash_dev *dev;
- uint16_t pa;
- uint16_t ba;
- uint8_t val;
- uint32_t n;
uint16_t page_count;
uint16_t amount;
uint16_t index;
@@ -257,53 +305,16 @@ flash_read(uint8_t flash_id, uint32_t addr, void *buf, size_t len)
}
page_count = calc_page_count(addr, len);
- index = 0;
u8buf = (uint8_t *) buf;
+ index = 0;
+
while (page_count--) {
wait_ready(dev);
- hal_gpio_write(dev->ss_pin, 0);
-
- hal_spi_tx_val(dev->spi_num, MEM_READ);
-
- pa = addr / PAGE_SIZE;
- ba = addr % PAGE_SIZE;
-
- /* < r, PA12-6 > */
- val = (pa >> 6) & ~0x80;
- hal_spi_tx_val(dev->spi_num, val);
-
- /* < PA5-0, BA9-8 > */
+ amount = read_page(dev, addr, len, &u8buf[index]);
-#if (PAGE_SIZE == 512)
- val = (pa << 2) | ((ba >> 8) & 1);
-#else
- val = (pa << 2) | ((ba >> 8) & 3);
-#endif
- hal_spi_tx_val(dev->spi_num, val);
-
- /* < BA7-0 > */
- hal_spi_tx_val(dev->spi_num, ba);
-
- /* send 32 don't care bits */
- hal_spi_tx_val(dev->spi_num, 0xff);
- hal_spi_tx_val(dev->spi_num, 0xff);
- hal_spi_tx_val(dev->spi_num, 0xff);
- hal_spi_tx_val(dev->spi_num, 0xff);
-
- if (len + ba <= PAGE_SIZE) {
- amount = len;
- } else {
- amount = PAGE_SIZE - ba;
- }
-
- for (n = 0; n < amount; n++) {
- u8buf[index++] = hal_spi_tx_val(dev->spi_num, 0xff);
- }
-
- hal_gpio_write(dev->ss_pin, 1);
-
- addr = next_page_addr(addr);
+ addr = page_next_addr(addr);
+ index += amount;
len -= amount;
}
@@ -315,10 +326,12 @@ flash_write(uint8_t flash_id, uint32_t addr, const void *buf, size_t len)
{
struct flash_dev *dev;
uint16_t pa;
- //uint16_t bfa;
+ uint16_t bfa;
uint32_t n;
+ uint32_t start_addr;
+ uint16_t index;
+ uint16_t amount;
int page_count;
- int offset;
uint8_t *u8buf;
dev = cfg_dev(flash_id);
@@ -327,23 +340,75 @@ flash_write(uint8_t flash_id, uint32_t addr, const void *buf, size_t len)
}
page_count = calc_page_count(addr, len);
- offset = 0;
u8buf = (uint8_t *) buf;
+ index = 0;
+
while (page_count--) {
wait_ready(dev);
+ bfa = addr % PAGE_SIZE;
+
+ /**
+ * If the page is not being written from the beginning,
+ * read first the current data to rewrite back.
+ *
+ * The whole page is read here for the case of some the
+ * real data ending before the end of the page, data must
+ * be written back again.
+ */
+ if (bfa || len < PAGE_SIZE) {
+ read_page(dev, page_start_address(addr), PAGE_SIZE, g_page_buffer);
+ wait_ready(dev);
+ }
+
hal_gpio_write(dev->ss_pin, 0);
- /* FIXME: ping-pong between page 1 and 2 */
+ /* TODO: ping-pong between page 1 and 2? */
hal_spi_tx_val(dev->spi_num, BUF1_WRITE);
- /* FIXME: always writing at 0 on buffer */
hal_spi_tx_val(dev->spi_num, 0xff);
- hal_spi_tx_val(dev->spi_num, 0xfc);
- hal_spi_tx_val(dev->spi_num, 0);
- for (n = 0; n < len; n++) {
- hal_spi_tx_val(dev->spi_num, u8buf[n]);
+ start_addr = page_start_address(addr);
+
+ /* FIXME */
+#if (PAGE_SIZE == 512)
+ hal_spi_tx_val(dev->spi_num, (start_addr >> 8) & 1);
+#else
+ hal_spi_tx_val(dev->spi_num, (start_addr >> 8) & 3);
+#endif
+
+ hal_spi_tx_val(dev->spi_num, start_addr);
+
+ /**
+ * Write back extra stuff at the beginning of page.
+ */
+ if (bfa) {
+ amount = addr - start_addr;
+ for (n = 0; n < amount; n++) {
+ hal_spi_tx_val(dev->spi_num, g_page_buffer[n]);
+ }
+ }
+
+ if (len + bfa <= PAGE_SIZE) {
+ amount = len;
+ } else {
+ amount = PAGE_SIZE - bfa;
+ }
+
+ /**
+ * Write the stuff we're really want to write!
+ */
+ for (n = 0; n < amount; n++) {
+ hal_spi_tx_val(dev->spi_num, u8buf[index++]);
+ }
+
+ /**
+ * Write back extra stuff at the ending of page.
+ */
+ if (len < PAGE_SIZE) {
+ for (n = len; n < PAGE_SIZE; n++) {
+ hal_spi_tx_val(dev->spi_num, g_page_buffer[n]);
+ }
}
hal_gpio_write(dev->ss_pin, 1);
@@ -352,20 +417,20 @@ flash_write(uint8_t flash_id, uint32_t addr, const void *buf, size_t len)
hal_gpio_write(dev->ss_pin, 0);
+ /* TODO: make command configurable (accept non erasing) */
hal_spi_tx_val(dev->spi_num, BUF1_TO_MEM_ERASE);
/* FIXME: check that pa doesn't overflow capacity */
pa = addr / PAGE_SIZE;
- printf("Writing at addr=%04lx, pa=%04x\n", addr, pa);
-
hal_spi_tx_val(dev->spi_num, (pa >> 6) & ~0x80);
hal_spi_tx_val(dev->spi_num, (pa << 2) | 0x3);
hal_spi_tx_val(dev->spi_num, 0xff);
hal_gpio_write(dev->ss_pin, 1);
- offset += PAGE_SIZE;
+ addr = page_next_addr(addr);
+ len -= amount;
}
return 0;