#ifndef FLASH_DEV_SST26_H
#define FLASH_DEV_SST26_H

#include "../flash.h"

#ifdef __cplusplus
extern "C" {
#endif

#define SST26_ID_MANUFACTURER   0xBF
#define SST26_ID_DEVICE         0x26
#define SST26_ID_CAPACITY       0x41

#define SST26_FLASH_SIZE        (2*1024*1024)

#define SST26_PAGE_SIZE         256
#define SST26_SECTOR_SIZE       4096
#define SST26_BLOCKL_SIZE       (8*1024)
#define SST26_BLOCKM_SIZE       (32*1024)
#define SST26_BLOCKH_SIZE       (64*1024)



extern const t_flash_info flash_info_sst26;


/* Биты регистра статуса. в старшем бите представлены расширенные биты регистра конфигурации */
typedef enum {
    SST26_STATUS_BUSY   = (1UL << 0),
    SST26_STATUS_WEL    = (1UL << 1), /* Write-Enable Latch status */
    SST26_STATUS_WSE    = (1UL << 2),  /* Write Suspend-Erase status */
    SST26_STATUS_WSP    = (1UL << 3), /* Write Suspend-Program status */
    SST26_STATUS_WPLD   = (1UL << 4), /* Write Protection Lock-Down status */
    SST26_STATUS_SEC    = (1UL << 5), /* Security-ID status */
    SST26_STATUS_BUSY2  = (1UL << 7),
    SST26_STATUS_IOC    = (1UL << 9), /* I/O Configuration for SPI-Mode */
    SST26_STATUS_BPNV   = (1UL << 11), /* Block-Protection Volatile State */
    SST26_STATUS_WPEN   = (1UL << 15), /* Write-Protection Pin Enable */
} t_sst26_status_bits;

typedef unsigned long long t_sst26_bpr_value;


t_flash_errs flash_sst26_set(t_flash_iface *iface);

/* получение расширенного статуса из 2-х байт (config в старшей половине) */
t_flash_errs flash_sst26_get_status_ex(t_flash_iface *iface, unsigned short *status);
t_flash_errs flash_sst26_set_status_ex(t_flash_iface *iface, unsigned short status);





#define flash_sst26_get_status flash_generic_get_status
#define flash_sst26_read       flash_generic_read
#define flash_sst26_erase      flash_generic_erase
#define flash_sst26_write      flash_generic_write
#define flash_sst26_write_enable flash_generic_write_enable

const t_flash_erase_cmd  *flash_sst26_get_erase_cmd(t_flash_iface *iface,
                                                    unsigned addr, size_t size);
t_flash_errs flash_sst26_lock_enable(t_flash_iface *iface);
t_flash_errs flash_sst26_lock(t_flash_iface *iface, unsigned addr, unsigned size);
t_flash_errs flash_sst26_unlock(t_flash_iface *iface, unsigned addr, unsigned size);
t_flash_errs flash_sst26_lock_check(t_flash_iface *iface, unsigned addr, unsigned size, int locked, int *check_ok);

/* получение и запись регистры защиты страниц */
t_flash_errs flash_sst26_get_bpr(t_flash_iface *iface, t_sst26_bpr_value *bpr);
t_flash_errs flash_sst26_set_bpr(t_flash_iface *iface, t_sst26_bpr_value bpr);

/* функции проверки защиты, использующие явно значение BPR. В отличие от общего
 * интерфейса позволяет прочитать bpr один раз и вызывать функции обработки */

/* проверка по BPR, защищена ли указанная область (аналогично lock_check) */
int flash_sst26_check_locked_bpr(unsigned addr, unsigned size, t_sst26_bpr_value bpr, int locked);
/* возвращает биты, которые нужно изменить в bpr, чтобы укзанная зона стала защищена или разрешена для записи */
t_sst26_bpr_value flash_sst26_bpr_bpr_diff_msk(unsigned addr, unsigned size, t_sst26_bpr_value bpr, int lock_en);
/* изменение bpr так, чтобы указанная область стала защищена или разрешена для записи */
t_flash_errs flash_sst26_lock_change_bpr(t_flash_iface *iface, unsigned addr, unsigned size, t_sst26_bpr_value bpr, int locked);



#ifdef __cplusplus
}
#endif

#endif // FLASH_DEV_SST26_H
