/*
 * M95M04.h
 *
 *  Created on: 3/06/2021
 *      Author: alexrayne <alexraynepe196@gmail.com>
 * ------------------------------------------------------------------
    Copyright (c) alexrayne

   All rights reserved.
   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions are met:
   - Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.
   - Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in the
     documentation and/or other materials provided with the distribution.
   - Neither the name of ARM nor the names of its contributors may be used
     to endorse or promote products derived from this software without
     specific prior written permission.
   *
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   POSSIBILITY OF SUCH DAMAGE. *
  ------------------------------------------------------------------------
      драйвера чипов SPI флеш xx25xxx:

      macronix: mx25r3235j
 */

#ifndef BSP_DEV_FLASH_FLASHSPI_X25_H_
#define BSP_DEV_FLASH_FLASHSPI_X25_H_

#include "flash_spi_hal.h"



/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///                         macronix: mx25r3235j

typedef SPIFlash_WritableDevice SPIFLASH_MX25R;

enum FLASHCmdId_MX25{
    MX25_CMD_NOP         = 0,

    MX25_CMD_RDID        = FLASH_CMD_RDID,
    MX25_CMD_RDSFDP      = 0x5A,        //< (Read SFDP
    MX25_CMD_RDCR        = 0x15,        //< (read configuration register

    MX25_CMD_PGM_SUSPEND = 0x75,        //< (Suspends Program/Erase
    MX25_CMD_PGM_SUSPEND2= 0xB0,
    MX25_CMD_PGM_RESUME  = 0x7A,        //< (Resumes Program/Erase
    MX25_CMD_PGM_RESUME2 = 0x30,
    MX25_CMD_DP          = 0xB9,        //< (Deep power down)
    MX25_CMD_SBL         = 0xC0,        //< Set Burst Length

    MX25_CMD_RES         = FLASH_CMD_RES,
    MX25_CMD_REMS        = 0x90,        //< (read electronic manufacturer & device ID

    MX25_CMD_ENSO        = 0xB1,        //< (enter secured OTP
    MX25_CMD_EXSO        = 0xC1,        //< (exit secured OTP
    MX25_CMD_RDSCUR      = 0x2B,        //< (read security register
    MX25_CMD_WRSCUR      = 0x2F,        //< (write security register

    MX25_CMD_RSTEN       = 0x66,        //< (Reset Enable
    MX25_CMD_RST         = 0x99,        //< (Reset
};

enum StatusFlagID_MX25 {
     MX25_SR_BP0       =  (1 << 2) // block protect state
    , MX25_SR_BP1       =  (1 << 3) // block protect state
    , MX25_SR_BP2       =  (1 << 4) // block protect state
    , MX25_SR_BP3       =  (1 << 5) // block protect state

    , MX25_SR_QE        =  (1 << 6) // Quad enable

    /* StatusRegisterWriteDisable bit is operated in conjunction with the write protect (W) signal. The
        status register write disable (SRWD) bit and write protect (W) signal enable the device to be put in the hardware
        protected mode (when the status register write disable (SRWD) bit is set to 1, and write protect (W) is driven low).
        In this mode, the non-volatile bits of the status register (SRWD, BP1, BP0) become read-only bits and the write
        status register (WRSR) instruction is no longer accepted for execution
    */
    , MX25_SR_SWRD      =  (1 << 7)
};

enum MX25Id{
    FLASHID_MACRONIX    = 0xC2,     //< macronix Manufacturer ID
    FLASHID_MX25R       = 0x28,
    FLASHID_MX25U       = 0x25,
    FLASHID_MX25R_16M   = 0x15,         //< 16Mbits
    FLASHID_MX25U_16M   = 0x15 | 0x20,  //< 16Mbits
    FLASHID_MX25R_32M   = 0x16,         //< 32Mbits
    FLASHID_MX25U_32M   = 0x16 | 0x20,  //< 32Mbits
    FLASHID_MX25R_64M   = 0x17,         //< 64Mbits
    FLASHID_MX25U_64M   = 0x17 | 0x20,  //< 64Mbits
};

#define MX25_PAGE_SIZE      256
#define MX25R32_SEC_SIZE    4096
#define MX25R32_SEC_PAGES   (MX25R32_SEC_SIZE / MX25_PAGE_SIZE)
#define MX25R32_SECTORS     1024
#define MX25R32_PAGES       (MX25R32_SECTORS * MX25R32_SEC_PAGES)
#define MX25R32_SIZE        (MX25R32_SECTORS * MX25R32_SEC_SIZE)



/// @brief init flash mx25r/u devices for basic (slow) spi reading connection.
DevResult mx25ru_init(SPIFLASH_MX25R* this);
void      mx25ru_connect(SPIFLASH_MX25R* this, SSP_IOPort*    _port);

/// @return > 0  - manufacerID, devID
///         < 0  - fail
///         == 0 - awaits
long mx25ru_read_id(SPIFLASH_MX25R* self);



enum {
    // 0 - top area, 1 - bottom area protect
    MX25CFG_TB = 1u<<3,
    MX25CFG_OTP_TOP = 0,
    MX25CFG_OTP_BOT = MX25CFG_TB,

    // 0 - UlrtaLow Power mode, 1 - HighPerfomance power mode
    MX25CFG_PM  = 1u << 10,
    MX25CFG_ULP = 0,
    MX25CFG_HP  = MX25CFG_PM,
};

int         mx25ru_read_cfg(SPIFLASH_MX25R* self);
DevResult   mx25ru_write_cfg(SPIFLASH_MX25R* self, unsigned cfg);



// TODO: sectors protection not implemented




#endif /* BSP_DEV_FLASH_EEPROM_M95M04_H_ */
