Move to proper files, update data structures

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/5e23a078
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/5e23a078
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/5e23a078

Branch: refs/heads/develop
Commit: 5e23a0782f3ba9349cdaca220bba3fb6acb2b0b9
Parents: 54ee5ce
Author: Fabio Utzig <[email protected]>
Authored: Mon Jan 16 21:48:57 2017 -0200
Committer: Fabio Utzig <[email protected]>
Committed: Fri Jan 20 07:27:40 2017 -0200

----------------------------------------------------------------------
 hw/drivers/flash/at45db/pkg.yml      |  27 ++
 hw/drivers/flash/at45db/src/at45db.c | 423 ++++++++++++++++++++++++++++
 hw/drivers/flash/pkg.yml             |  27 --
 hw/drivers/flash/src/flash.c         | 450 ------------------------------
 4 files changed, 450 insertions(+), 477 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5e23a078/hw/drivers/flash/at45db/pkg.yml
----------------------------------------------------------------------
diff --git a/hw/drivers/flash/at45db/pkg.yml b/hw/drivers/flash/at45db/pkg.yml
new file mode 100644
index 0000000..8a4a93f
--- /dev/null
+++ b/hw/drivers/flash/at45db/pkg.yml
@@ -0,0 +1,27 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: hw/drivers/flash/at45db
+pkg.description: AT45DB SPI flash driver
+pkg.author: "Apache Mynewt <[email protected]>"
+pkg.homepage: "http://mynewt.apache.org/";
+pkg.keywords:
+
+pkg.deps:
+    - hw/hal

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5e23a078/hw/drivers/flash/at45db/src/at45db.c
----------------------------------------------------------------------
diff --git a/hw/drivers/flash/at45db/src/at45db.c 
b/hw/drivers/flash/at45db/src/at45db.c
new file mode 100644
index 0000000..e2bdc0c
--- /dev/null
+++ b/hw/drivers/flash/at45db/src/at45db.c
@@ -0,0 +1,423 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <os/os.h>
+
+#include <hal/hal_spi.h>
+#include <hal/hal_gpio.h>
+//#include <flash/flash.h>
+#include <at45db/at45db.h>
+
+#include <string.h>
+
+/**
+ * Memory Architecture:
+ *
+ * Device can be addressed using pages, blocks or sectors.
+ *
+ * 1) Page
+ *    - device has 8192 pages of 512 (or 528) bytes.
+ *
+ * 2) Block
+ *    - device has 1024 blocks of 4K (or 4K + 128) bytes.
+ *    - Each block contains 8 pages, eg, Block 0 == Page 0 to 7, etc.
+ *
+ * 3) Sector
+ *    - Sector 0 == Block 0.
+ *    - Sector 1 == Blocks 1 to 63 (252K + 8064).
+ *    - Sector 2 to 16 contain 64 blocks (256K + 8192).
+ */
+
+#define MEM_READ                    0x52  /* Read page bypassing buffer */
+#define BUF1_READ                   0x54
+#define BUF2_READ                   0x56
+#define MEM_TO_BUF1_TRANSFER        0x53
+#define MEM_TO_BUF2_TRANSFER        0x55
+#define MEM_TO_BUF1_CMP             0x60
+#define MEM_TO_BUF2_CMP             0x61
+#define BUF1_WRITE                  0x84
+#define BUF2_WRITE                  0x87
+#define BUF1_TO_MEM_ERASE           0x83
+#define BUF2_TO_MEM_ERASE           0x86
+#define BUF1_TO_MEM_NO_ERASE        0x88
+#define BUF2_TO_MEM_NO_ERASE        0x89
+#define PAGE_ERASE                  0x81
+#define BLOCK_ERASE                 0x50
+
+
+#define PAGE_ERASE                  0x81
+#define BLOCK_ERASE                 0x50
+
+#define STATUS_REGISTER             0x57
+
+#define STATUS_BUSY                 (1 << 7)
+#define STATUS_CMP                  (1 << 6)
+
+#define MAX_PAGE_SIZE               528
+
+/**
+ * Reading memory (MEM_READ):
+ * < r, PA12-6 >
+ * < PA5-0, BA9-8 >
+ * < BA7-0 >
+ * < 8 don't care bits >
+ * < 8 don't care bits >
+ * < 8 don't care bits >
+ * < 8 don't care bits >
+ *
+ * Reading a buffer (BUFx_READ):
+ * < 8 don't care bits >
+ * < 6 don't care bits, A9-8 >
+ * < A7-0 >
+ * < 8 don't care bits >
+ *
+ * Memory to buffer copy (MEM_TO_BUFx_TRANSFER):
+ * < r, PA12-PA6 >
+ * < PA5-0, 2 don't care bits >
+ * < 8 don't care bits >
+ *
+ * Memory to buffer compare (MEM_TO_BUFx_CMP):
+ * < r, PA12-PA6 >
+ * < PA5-0, 2 don't care bits >
+ * < 8 don't care bits >
+ *
+ * Buffer write (BUFx_WRITE):
+ * < 8 don't care bits >
+ * < 6 don't care bits, BFA9-8 >
+ * < BFA7-0 >
+ *
+ * Buffer to memory program with erase (BUFx_TO_MEM_ERASE):
+ * < r, PA12-PA6 >
+ * < PA5-0, 2 don't care bits >
+ * < 8 don't care bits >
+ *
+ * Buffer to memory program without erase (BUFx_TO_MEM_NO_ERASE):
+ * < r, PA12-PA6 >
+ * < PA5-0, 2 don't care bits >
+ * < 8 don't care bits >
+ *
+ * Page erase (PAGE_ERASE):
+ * < r, PA12-PA6 >
+ * < PA5-0, 2 don't care bits >
+ * < 8 don't care bits >
+ *
+ * Block erase (BLOCK_ERASE):
+ * < r, PA12-PA6 >
+ * < PA5-PA3, 5 don't care bits >
+ * < 8 don't care bits >
+ */
+
+static struct hal_spi_settings at45db_default_settings = {
+    .data_order = HAL_SPI_MSB_FIRST,
+    .data_mode  = HAL_SPI_MODE3,
+    .baudrate   = 100,
+    .word_size  = HAL_SPI_WORD_SIZE_8BIT,
+};
+
+static uint8_t g_page_buffer[MAX_PAGE_SIZE];
+
+static uint8_t read_status(struct at45db_dev *dev)
+{
+    uint8_t val;
+
+    hal_gpio_write(dev->ss_pin, 0);
+
+    hal_spi_tx_val(dev->spi_num, STATUS_REGISTER);
+    val = hal_spi_tx_val(dev->spi_num, 0xff);
+
+    hal_gpio_write(dev->ss_pin, 1);
+
+    return val;
+}
+
+static inline bool
+device_ready(struct at45db_dev *dev)
+{
+    return ((read_status(dev) & STATUS_BUSY) != 0);
+}
+
+static inline bool
+buffer_equal(struct at45db_dev *dev)
+{
+    return ((read_status(dev) & STATUS_CMP) == 0);
+}
+
+/* FIXME: add timeout */
+static inline void
+wait_ready(struct at45db_dev *dev)
+{
+    while (!device_ready(dev)) {
+        os_time_delay(OS_TICKS_PER_SEC / 10000);
+    }
+}
+
+static inline uint16_t
+calc_page_count(struct at45db_dev *dev, uint32_t addr, size_t len)
+{
+    uint16_t page_count;
+    uint16_t page_size = dev->page_size;
+
+    page_count = 1 + (len / (page_size + 1));
+    if ((addr % page_size) + len > page_size * page_count) {
+        page_count++;
+    }
+
+    return page_count;
+}
+
+static inline uint32_t
+page_start_address(struct at45db_dev *dev, uint32_t addr)
+{
+    /* FIXME: works only for 512? (powers of 2) */
+    return (addr & ~(dev->page_size - 1));
+}
+
+static inline uint32_t
+page_next_addr(struct at45db_dev *dev, uint32_t addr)
+{
+    return (page_start_address(dev, addr) + dev->page_size);
+}
+
+/* FIXME: assume buf has enough space? */
+static uint16_t
+read_page(struct at45db_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;
+    uint16_t page_size;
+
+    hal_gpio_write(dev->ss_pin, 0);
+
+    hal_spi_tx_val(dev->spi_num, MEM_READ);
+
+    page_size = dev->page_size;
+    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);
+    }
+    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
+at45db_init(struct at45db_dev *dev)
+{
+    int rc;
+    struct hal_spi_settings *settings;
+
+    /* only alloc new settings if using non-default */
+    if (dev->baudrate == at45db_default_settings.baudrate) {
+        dev->settings = &at45db_default_settings;
+    } else {
+        settings = malloc(sizeof(at45db_default_settings));
+        if (!settings) {
+            return (-1);
+        }
+        memcpy(settings, &at45db_default_settings, 
sizeof(at45db_default_settings));
+        at45db_default_settings.baudrate = dev->baudrate;
+    }
+
+    hal_gpio_init_out(dev->ss_pin, 1);
+
+    rc = hal_spi_init(dev->spi_num, dev->spi_cfg, HAL_SPI_TYPE_MASTER);
+    if (rc) {
+        return (rc);
+    }
+
+    rc = hal_spi_config(dev->spi_num, dev->settings);
+    if (rc) {
+        return (rc);
+    }
+
+    hal_spi_set_txrx_cb(dev->spi_num, NULL, NULL);
+    hal_spi_enable(dev->spi_num);
+
+    return 0;
+}
+
+int
+at45db_read(struct at45db_dev *dev, uint32_t addr, void *buf, size_t len)
+{
+    uint16_t page_count;
+    uint16_t amount;
+    uint16_t index;
+    uint8_t *u8buf;
+
+    page_count = calc_page_count(dev, addr, len);
+    u8buf = (uint8_t *) buf;
+    index = 0;
+
+    while (page_count--) {
+        wait_ready(dev);
+
+        amount = read_page(dev, addr, len, &u8buf[index]);
+
+        addr = page_next_addr(dev, addr);
+        index += amount;
+        len -= amount;
+    }
+
+    return 0;
+}
+
+int
+at45db_write(struct at45db_dev *dev, uint32_t addr, const void *buf, size_t 
len)
+{
+    uint16_t pa;
+    uint16_t bfa;
+    uint32_t n;
+    uint32_t start_addr;
+    uint16_t index;
+    uint16_t amount;
+    int page_count;
+    uint8_t *u8buf;
+    uint16_t page_size;
+
+    page_size = dev->page_size;
+    page_count = calc_page_count(dev, addr, len);
+    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(dev, addr), page_size, 
g_page_buffer);
+            wait_ready(dev);
+        }
+
+        hal_gpio_write(dev->ss_pin, 0);
+
+        /* TODO: ping-pong between page 1 and 2? */
+        hal_spi_tx_val(dev->spi_num, BUF1_WRITE);
+
+        hal_spi_tx_val(dev->spi_num, 0xff);
+
+        start_addr = page_start_address(dev, addr);
+
+        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);
+        }
+
+        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 (bfa + 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);
+
+        wait_ready(dev);
+
+        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;
+
+        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);
+
+        addr = page_next_addr(dev, addr);
+        len -= amount;
+    }
+
+    return 0;
+}
+
+int
+at45db_erase(struct at45db_dev *dev, uint32_t addr, size_t len)
+{
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5e23a078/hw/drivers/flash/pkg.yml
----------------------------------------------------------------------
diff --git a/hw/drivers/flash/pkg.yml b/hw/drivers/flash/pkg.yml
deleted file mode 100644
index cb37e01..0000000
--- a/hw/drivers/flash/pkg.yml
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#  http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-pkg.name: hw/drivers/flash
-pkg.description: Flash memories
-pkg.author: "Apache Mynewt <[email protected]>"
-pkg.homepage: "http://mynewt.apache.org/";
-pkg.keywords:
-
-pkg.deps:
-    - hw/hal

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/5e23a078/hw/drivers/flash/src/flash.c
----------------------------------------------------------------------
diff --git a/hw/drivers/flash/src/flash.c b/hw/drivers/flash/src/flash.c
deleted file mode 100644
index 40e1706..0000000
--- a/hw/drivers/flash/src/flash.c
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#include <hal/hal_spi.h>
-#include <hal/hal_gpio.h>
-
-#include <flash/flash.h>
-
-#include <stdio.h>
-
-/**
- * Memory Architecture:
- *
- * Device can be addressed using pages, blocks or sectors.
- *
- * 1) Page
- *    - device has 8192 pages of 512 (or 528) bytes.
- *
- * 2) Block
- *    - device has 1024 blocks of 4K (or 4K + 128) bytes.
- *    - Each block contains 8 pages, eg, Block 0 == Page 0 to 7, etc.
- *
- * 3) Sector
- *    - Sector 0 == Block 0.
- *    - Sector 1 == Blocks 1 to 63 (252K + 8064).
- *    - Sector 2 to 16 contain 64 blocks (256K + 8192).
- */
-
-#define MEM_READ                    0x52  /* Read page bypassing buffer */
-#define BUF1_READ                   0x54
-#define BUF2_READ                   0x56
-#define MEM_TO_BUF1_TRANSFER        0x53
-#define MEM_TO_BUF2_TRANSFER        0x55
-#define MEM_TO_BUF1_CMP             0x60
-#define MEM_TO_BUF2_CMP             0x61
-#define BUF1_WRITE                  0x84
-#define BUF2_WRITE                  0x87
-#define BUF1_TO_MEM_ERASE           0x83
-#define BUF2_TO_MEM_ERASE           0x86
-#define BUF1_TO_MEM_NO_ERASE        0x88
-#define BUF2_TO_MEM_NO_ERASE        0x89
-#define PAGE_ERASE                  0x81
-#define BLOCK_ERASE                 0x50
-
-
-#define PAGE_ERASE                  0x81
-#define BLOCK_ERASE                 0x50
-
-#define STATUS_REGISTER             0x57
-
-#define STATUS_BUSY                 (1 << 7)
-#define STATUS_CMP                  (1 << 6)
-
-/* TODO: make configurable to 512/528 */
-#define PAGE_SIZE                   512
-
-/**
- * Reading memory (MEM_READ):
- * < r, PA12-6 >
- * < PA5-0, BA9-8 >
- * < BA7-0 >
- * < 8 don't care bits >
- * < 8 don't care bits >
- * < 8 don't care bits >
- * < 8 don't care bits >
- *
- * Reading a buffer (BUFx_READ):
- * < 8 don't care bits >
- * < 6 don't care bits, A9-8 >
- * < A7-0 >
- * < 8 don't care bits >
- *
- * Memory to buffer copy (MEM_TO_BUFx_TRANSFER):
- * < r, PA12-PA6 >
- * < PA5-0, 2 don't care bits >
- * < 8 don't care bits >
- *
- * Memory to buffer compare (MEM_TO_BUFx_CMP):
- * < r, PA12-PA6 >
- * < PA5-0, 2 don't care bits >
- * < 8 don't care bits >
- *
- * Buffer write (BUFx_WRITE):
- * < 8 don't care bits >
- * < 6 don't care bits, BFA9-8 >
- * < BFA7-0 >
- *
- * Buffer to memory program with erase (BUFx_TO_MEM_ERASE):
- * < r, PA12-PA6 >
- * < PA5-0, 2 don't care bits >
- * < 8 don't care bits >
- *
- * Buffer to memory program without erase (BUFx_TO_MEM_NO_ERASE):
- * < r, PA12-PA6 >
- * < PA5-0, 2 don't care bits >
- * < 8 don't care bits >
- *
- * Page erase (PAGE_ERASE):
- * < r, PA12-PA6 >
- * < PA5-0, 2 don't care bits >
- * < 8 don't care bits >
- *
- * Block erase (BLOCK_ERASE):
- * < r, PA12-PA6 >
- * < PA5-PA3, 5 don't care bits >
- * < 8 don't care bits >
- */
-
-static struct flash_dev {
-    int                      spi_num;
-    int                      ss_pin;
-    void                     *spi_cfg;
-    struct hal_spi_settings  *settings;
-} g_flash_dev;
-
-static struct hal_spi_settings at45db_settings = {
-    .data_order = HAL_SPI_MSB_FIRST,
-    .data_mode  = HAL_SPI_MODE3,
-    .baudrate   = 100,  /* NOTE: default clock to be overwritten by init */
-    .word_size  = HAL_SPI_WORD_SIZE_8BIT,
-};
-
-static uint8_t g_page_buffer[PAGE_SIZE];
-
-static struct flash_dev *
-cfg_dev(uint8_t id)
-{
-    if (id != 0) {
-        return NULL;
-    }
-
-    return &g_flash_dev;
-}
-
-static uint8_t read_status(struct flash_dev *flash)
-{
-    uint8_t val;
-
-    hal_gpio_write(flash->ss_pin, 0);
-
-    hal_spi_tx_val(flash->spi_num, STATUS_REGISTER);
-    val = hal_spi_tx_val(flash->spi_num, 0xff);
-
-    hal_gpio_write(flash->ss_pin, 1);
-
-    return val;
-}
-
-static inline bool
-device_ready(struct flash_dev *dev)
-{
-    return ((read_status(dev) & STATUS_BUSY) != 0);
-}
-
-static inline bool
-buffer_equal(struct flash_dev *dev)
-{
-    return ((read_status(dev) & STATUS_CMP) == 0);
-}
-
-/* FIXME: add timeout */
-static inline void
-wait_ready(struct flash_dev *dev)
-{
-    while (!device_ready(dev)) {
-        os_time_delay(OS_TICKS_PER_SEC / 10000);
-    }
-}
-
-static inline uint16_t
-calc_page_count(uint32_t addr, size_t len)
-{
-    uint16_t page_count;
-
-    page_count = 1 + (len / (PAGE_SIZE + 1));
-    if ((addr % PAGE_SIZE) + len > PAGE_SIZE * page_count) {
-        page_count++;
-    }
-
-    return page_count;
-}
-
-static inline uint32_t
-page_start_address(uint32_t addr)
-{
-    /* FIXME: works only for 512? (powers of 2) */
-    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
-flash_init(int spi_num, void *spi_cfg, int ss_pin, uint32_t baudrate)
-{
-    int rc;
-    struct flash_dev *dev;
-
-    at45db_settings.baudrate = baudrate;
-
-    dev = &g_flash_dev;
-    dev->spi_num = spi_num;
-    dev->ss_pin = ss_pin;
-    dev->spi_cfg = spi_cfg;
-    dev->settings = &at45db_settings;
-
-    hal_gpio_init_out(dev->ss_pin, 1);
-
-    rc = hal_spi_init(dev->spi_num, dev->spi_cfg, HAL_SPI_TYPE_MASTER);
-    if (rc) {
-        return (rc);
-    }
-
-    rc = hal_spi_config(dev->spi_num, dev->settings);
-    if (rc) {
-        return (rc);
-    }
-
-    hal_spi_set_txrx_cb(dev->spi_num, NULL, NULL);
-    hal_spi_enable(dev->spi_num);
-
-    return 0;
-}
-
-int
-flash_read(uint8_t flash_id, uint32_t addr, void *buf, size_t len)
-{
-    struct flash_dev *dev;
-    uint16_t page_count;
-    uint16_t amount;
-    uint16_t index;
-    uint8_t *u8buf;
-
-    dev = cfg_dev(flash_id);
-    if (!dev) {
-        return -1;
-    }
-
-    page_count = calc_page_count(addr, len);
-    u8buf = (uint8_t *) buf;
-    index = 0;
-
-    while (page_count--) {
-        wait_ready(dev);
-
-        amount = read_page(dev, addr, len, &u8buf[index]);
-
-        addr = page_next_addr(addr);
-        index += amount;
-        len -= amount;
-    }
-
-    return 0;
-}
-
-int
-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;
-    uint32_t n;
-    uint32_t start_addr;
-    uint16_t index;
-    uint16_t amount;
-    int page_count;
-    uint8_t *u8buf;
-
-    dev = cfg_dev(flash_id);
-    if (!dev) {
-        return -1;
-    }
-
-    page_count = calc_page_count(addr, len);
-    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);
-
-        /* TODO: ping-pong between page 1 and 2? */
-        hal_spi_tx_val(dev->spi_num, BUF1_WRITE);
-
-        hal_spi_tx_val(dev->spi_num, 0xff);
-
-        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 (bfa + 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);
-
-        wait_ready(dev);
-
-        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;
-
-        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);
-
-        addr = page_next_addr(addr);
-        len -= amount;
-    }
-
-    return 0;
-}
-
-int
-flash_erase(uint8_t flash_id, uint32_t addr, size_t len)
-{
-    struct flash_dev *dev;
-
-    dev = cfg_dev(flash_id);
-    if (!dev) {
-        return -1;
-    }
-
-    return 0;
-}

Reply via email to