//
// Created by imi415 on 2019/12/19.
//

#ifndef STM32H750VB_BOOTLOADER_W25_QSPI_H
#define STM32H750VB_BOOTLOADER_W25_QSPI_H

#include <stm32h7xx_hal_qspi.h>

#define W25_CMD_WRITE_ENABLE 0x06
#define W25_CMD_WRITE_VOLATILE_ENABLE 0x50
#define W25_CMD_PAGE_PROGRAM 0x02
#define W25_CMD_PAGE_PROGRAM_QUAD 0x32
#define W25_CMD_QPI_ENABLE 0x38
#define W25_CMD_QPI_DISABLE 0xFF
#define W25_CMD_READ 0x03
#define W25_CMD_READ_QUAD 0x6B
#define W25_CMD_SECTOR_ERASE 0x20
#define W25_CMD_READ_STATUS_1 0x05
#define W25_CMD_READ_STATUS_2 0x35
#define W25_CMD_WRITE_STATUS_2 0x31
#define W25_CMD_READ_JEDEC_ID 0x9F
#define W25_CMD_READ_MFG_DEV_ID 0x90
#define W25_CMD_QPI_READ_PARAMS 0xC0

typedef enum {
    W25_MODE_SINGLE,
    W25_MODE_DUAL,
    W25_MODE_QUAD
} w25_mode_t;

typedef enum {
    W25_ADDRESS_24BITS,
    W25_ADDRESS_32BITS
} w25_address_size_t;

typedef enum {
    W25_QPI_DUMMY_2 = 0,
    W25_QPI_DUMMY_4,
    W25_QPI_DUMMY_6,
    W25_QPI_DUMMY_8
} w25_qpi_dummy_t;

typedef enum {
    W25_QPI_WRAP_LENGTH_8 = 0,
    W25_QPI_WRAP_LENGTH_16,
    W25_QPI_WRAP_LENGTH_32,
    W25_QPI_WRAP_LENGTH_64
} w25_qpi_wrap_t;

typedef struct {
    QSPI_HandleTypeDef *interface;
    w25_mode_t mode;
    w25_address_size_t address_size;
    uint32_t capacity;
    uint8_t manufacturer;
    uint8_t memory_type;
} w25_qspi_t;

HAL_StatusTypeDef W25_QSPI_Init(w25_qspi_t *flash);
HAL_StatusTypeDef W25_QSPI_Erase_Sector(w25_qspi_t *flash, uint32_t address);
HAL_StatusTypeDef W25_QSPI_Program_Page(w25_qspi_t *flash, uint32_t address, uint8_t *data);
HAL_StatusTypeDef W25_QSPI_Read(w25_qspi_t *flash, uint32_t address, uint8_t *data, uint32_t length);
HAL_StatusTypeDef W25_QSPI_QuadEnable(w25_qspi_t *flash, uint8_t permanent);
HAL_StatusTypeDef W25_QPI_Mode(w25_qspi_t *flash, uint8_t enable);
HAL_StatusTypeDef W25_QPI_ReadParams(w25_qspi_t *flash, w25_qpi_dummy_t dummy_clocks, w25_qpi_wrap_t wrap_length);

#endif //STM32H750VB_BOOTLOADER_W25_QSPI_H
