/*
 * 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 <string.h>
#include <assert.h>

#include "nrf.h"
#include "mcu/nrf51_hal.h"

#include <hal/hal_flash_int.h>

#define NRF51_FLASH_SECTOR_SZ	1024

static int nrf51_flash_read(const struct hal_flash *dev, uint32_t address,
        void *dst, uint32_t num_bytes);
static int nrf51_flash_write(const struct hal_flash *dev, uint32_t address,
        const void *src, uint32_t num_bytes);
static int nrf51_flash_erase_sector(const struct hal_flash *dev,
        uint32_t sector_address);
static int nrf51_flash_sector_info(const struct hal_flash *dev, int idx,
        uint32_t *address, uint32_t *sz);
static int nrf51_flash_init(const struct hal_flash *dev);

static const struct hal_flash_funcs nrf51_flash_funcs = {
    .hff_read = nrf51_flash_read,
    .hff_write = nrf51_flash_write,
    .hff_erase_sector = nrf51_flash_erase_sector,
    .hff_sector_info = nrf51_flash_sector_info,
    .hff_init = nrf51_flash_init
};

const struct hal_flash nrf51_flash_dev = {
    .hf_itf = &nrf51_flash_funcs,
    .hf_base_addr = 0x00000000,
    .hf_size = 256 * 1024,	/* XXX read from factory info? */
    .hf_sector_cnt = 256,	/* XXX read from factory info? */
    .hf_align = 1,
    .hf_erased_val = 0xff,
};

#define NRF51_FLASH_READY() (NRF_NVMC->READY == NVMC_READY_READY_Ready)

static int
nrf51_flash_wait_ready(void)
{
    int i;

    for (i = 0; i < 100000; i++) {
        if (NRF_NVMC->READY == NVMC_READY_READY_Ready) {
            return 0;
        }
    }
    return -1;
}

static int
nrf51_flash_read(const struct hal_flash *dev, uint32_t address, void *dst,
        uint32_t num_bytes)
{
    memcpy(dst, (void *)address, num_bytes);
    return 0;
}

/*
 * Flash write is done by writing 4 bytes at a time at a word boundary.
 */
static int
nrf51_flash_write(const struct hal_flash *dev, uint32_t address,
        const void *src, uint32_t num_bytes)
{
    int sr;
    int rc = -1;
    uint32_t val;
    int cnt;
    uint32_t tmp;

    if (nrf51_flash_wait_ready()) {
        return -1;
    }
    __HAL_DISABLE_INTERRUPTS(sr);
    NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen; /* Enable erase OP */
    tmp = address & 0x3;
    if (tmp) {
        if (nrf51_flash_wait_ready()) {
            goto out;
        }
        /*
         * Starts at a non-word boundary. Read 4 bytes which were there
         * before, update with new data, and write back.
         */
        val = *(uint32_t *)(address & ~0x3);
        cnt = 4 - tmp;
        if (cnt > num_bytes) {
            cnt = num_bytes;
        }
        memcpy((uint8_t *)&val + tmp, src, cnt);
        *(uint32_t *)(address & ~0x3) = val;
        address += cnt;
        num_bytes -= cnt;
        src += cnt;
    }

    while (num_bytes >= sizeof(uint32_t)) {
        /*
         * Write data 4 bytes at a time.
         */
        if (nrf51_flash_wait_ready()) {
            goto out;
        }
        memcpy(&val, src, sizeof(uint32_t));
        *(uint32_t *)address = val;
        address += sizeof(uint32_t);
        src += sizeof(uint32_t);
        num_bytes -= sizeof(uint32_t);
    }
    if (num_bytes) {
        /*
         * Deal with the trailing bytes.
         */
        val = *(uint32_t *)address;
        memcpy(&val, src, num_bytes);
        if (nrf51_flash_wait_ready()) {
            goto out;
        }
        *(uint32_t *)address = val;
    }
    rc = 0;
    if (nrf51_flash_wait_ready()) {
        rc = -1;
    }
out:
    NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
    __HAL_ENABLE_INTERRUPTS(sr);
    return rc;
}

static int
nrf51_flash_erase_sector(const struct hal_flash *dev, uint32_t sector_address)
{
    int sr;
    int rc = -1;

    if (nrf51_flash_wait_ready()) {
        return -1;
    }
    __HAL_DISABLE_INTERRUPTS(sr);
    NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Een; /* Enable erase OP */
    if (nrf51_flash_wait_ready()) {
        goto out;
    }

    NRF_NVMC->ERASEPAGE = sector_address;
    if (nrf51_flash_wait_ready()) {
        goto out;
    }
    rc = 0;
out:
    NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren; /* Disable erase OP */
    __HAL_ENABLE_INTERRUPTS(sr);
    return rc;
}

static int
nrf51_flash_sector_info(const struct hal_flash *dev, int idx,
        uint32_t *address, uint32_t *sz)
{
    assert(idx < nrf51_flash_dev.hf_sector_cnt);
    *address = idx * NRF51_FLASH_SECTOR_SZ;
    *sz = NRF51_FLASH_SECTOR_SZ;
    return 0;
}

static int
nrf51_flash_init(const struct hal_flash *dev)
{
    return 0;
}
