/*
  ******************************************************************************
  * @file    spl_exmc.h
  * @version V1.0.0
  * @date    2022
  * @brief   Header file of SPL HAL module.
  ******************************************************************************
*/
#ifndef __SPL_EXMC_H__
#define __SPL_EXMC_H__

#include "acm32g103_spl_conf.h"


/**
  * @brief  EXMC NORSRAM Timing parameters structure definition
  */
typedef struct
{
    uint32_t EXMC_AddressSetupTime;             /*!< Defines the number of HCLK cycles to configure
                                                    the duration of the address setup time. */

    uint32_t EXMC_AddressHoldTime;              /*!< Defines the number of HCLK cycles to configure
                                                    the duration of the address hold time. */

    uint32_t EXMC_DataSetupTime;                /*!< Defines the number of HCLK cycles to configure
                                                    the duration of the data setup time. */

    uint32_t EXMC_BusTurnAroundDuration;        /*!< Defines the number of HCLK cycles to configure
                                                    the duration of the bus turnaround. */

    uint32_t EXMC_CLKDivision;                  /*!< Defines the period of CLK clock output signal, 
                                                    expressed in number of HCLK cycles. */

    uint32_t EXMC_DataLatency;                  /*!< Defines the number of memory clock cycles to issue
                                                    to the memory before getting the first data. */

    uint32_t EXMC_AccessMode;                   /*!< Specifies the asynchronous access mode. */

}EXMC_NORSRAMTimingInitTypeDef;
/**
  * @}
  */


/**
  * @brief  EXMC NORSRAM Configuration Structure definition
  */
typedef struct
{
    uint32_t EXMC_Bank;                           /*!< Specifies the NOR/SRAM memory bank that will be used. */

    uint32_t EXMC_DataAddressMux;                 /*!< Specifies whether the address and data values are
                                                    multiplexed on the data bus or not. */

    uint32_t EXMC_MemoryType;                     /*!< Specifies the type of external memory attached to
                                                    the corresponding memory bank. */

    uint32_t EXMC_MemoryDataWidth;                /*!< Specifies the external memory device width. */

    uint32_t EXMC_BurstAccessMode;                /*!< Enables or disables the burst access mode for Flash memory,
                                                    valid only with synchronous burst Flash memories. */                                       

    uint32_t EXMC_WaitSignalPolarity;             /*!< Specifies the wait signal polarity, valid only when accessing
                                                    the Flash memory in burst mode. */

    uint32_t EXMC_WrapMode;                       /*!< Enables or disables the Wrapped burst access mode for Flash
                                                    memory, valid only when accessing Flash memories in burst mode. */

    uint32_t EXMC_WaitSignalActive;               /*!< Specifies if the wait signal is asserted by the memory one
                                                    clock cycle before the wait state or during the wait state,
                                                    valid only when accessing memories in burst mode. */

    uint32_t EXMC_WriteOperation;                 /*!< Enables or disables the write operation in the selected bank by the FSMC. */

    uint32_t EXMC_WaitSignal;                     /*!< Enables or disables the wait state insertion via wait
                                                    signal, valid for Flash memory access in burst mode. */

    uint32_t EXMC_ExtendedMode;                   /*!< Enables or disables the extended mode. */

    uint32_t EXMC_AsynchronousWait;               /*!< Enables or disables wait signal during asynchronous transfers,
                                                    valid only with asynchronous Flash memories. */  

    uint32_t EXMC_CRAMPageSize;                   /*!< Specifies the CRAM page size. */                                                    

    uint32_t EXMC_WriteBurst;                     /*!< Enables or disables the write burst operation. */ 

    EXMC_NORSRAMTimingInitTypeDef* EXMC_ReadWriteTimingStruct; /*!< Timing Parameters for write and read access if the  Extended Mode is not used*/  

    EXMC_NORSRAMTimingInitTypeDef* EXMC_WriteTimingStruct;     /*!< Timing Parameters for write access if the  Extended Mode is used*/      
}EXMC_NORSRAMInitTypeDef;
/**
  * @}
  */


/** @defgroup EXMC NOR/SRAM Bank
  * @{
  */
#define EXMC_NORSRAM_BANK1                      (0x00000000U)
#define EXMC_NORSRAM_BANK2                      (0x00000002U)
#define EXMC_NORSRAM_BANK3                      (0x00000004U)
#define EXMC_NORSRAM_BANK4                      (0x00000006U)
#define IS_EXMC_NORSRAM_BANK(BANK)              (((BANK) == EXMC_NORSRAM_BANK1) || \
                                                ((BANK) == EXMC_NORSRAM_BANK2) || \
                                                ((BANK) == EXMC_NORSRAM_BANK3) || \
                                                ((BANK) == EXMC_NORSRAM_BANK4))
/**
  * @}
  */
  
  
/** @defgroup EXMC Data Address Bus Multiplexing
  * @{
  */
#define EXMC_DATA_ADDRESS_MUX_DISABLE           (0x00000000U)
#define EXMC_DATA_ADDRESS_MUX_ENABLE            (0x00000002U)
#define IS_EXMC_MUX(MUX)                        (((MUX) == EXMC_DATA_ADDRESS_MUX_DISABLE) || \
                                                ((MUX) == EXMC_DATA_ADDRESS_MUX_ENABLE))
/**
  * @}
  */

/** @defgroup EXMC Memory Type
  * @{
  */
#define EXMC_MEMORY_TYPE_SRAM                   (0x00000000U)
#define EXMC_MEMORY_TYPE_PSRAM                  (0x00000004U)
#define EXMC_MEMORY_TYPE_NOR                    (0x00000008U)
#define IS_EXMC_MEMORY(MEMORY)                  (((MEMORY) == EXMC_MEMORY_TYPE_SRAM) || \
                                                ((MEMORY) == EXMC_MEMORY_TYPE_PSRAM)|| \
                                                ((MEMORY) == EXMC_MEMORY_TYPE_NOR))
/**
  * @}
  */
  
/** @defgroup EXMC NORSRAM Data Width
  * @{
  */
#define EXMC_NORSRAM_MEM_BUS_WIDTH_8            (0x00000000U)
#define EXMC_NORSRAM_MEM_BUS_WIDTH_16           (0x00000010U)
#define EXMC_NORSRAM_MEM_BUS_WIDTH_32           (0x00000020U)
#define IS_EXMC_MEMORY_WIDTH(WIDTH)             (((WIDTH) == EXMC_NORSRAM_MEM_BUS_WIDTH_8) || \
                                                ((WIDTH) == EXMC_NORSRAM_MEM_BUS_WIDTH_16) || \
                                                ((WIDTH) == EXMC_NORSRAM_MEM_BUS_WIDTH_32))
/**
  * @}
  */

/** @defgroup EXMC NOR/SRAM Flash Access
  * @{
  */
#define EXMC_NORSRAM_FLASH_ACCESS_DISABLE       (0x00000000U)
#define EXMC_NORSRAM_FLASH_ACCESS_ENABLE        (0x00000040U)
/**
  * @}
  */


/** @defgroup EXMC Burst Access Mode
  * @{
  */
#define EXMC_BURST_ACCESS_MODE_DISABLE          (0x00000000U)
#define EXMC_BURST_ACCESS_MODE_ENABLE           (0x00000100U)
#define IS_EXMC_BURSTMODE(STATE)                (((STATE) == EXMC_BURST_ACCESS_MODE_DISABLE) || \
                                                ((STATE) == EXMC_BURST_ACCESS_MODE_ENABLE))
/**
  * @}
  */
  
/** @defgroup EXMC Wait Signal Polarity
  * @{
  */
#define EXMC_WAIT_SIGNAL_POLARITY_LOW           (0x00000000U)
#define EXMC_WAIT_SIGNAL_POLARITY_HIGH          (0x00000200U)
#define IS_EXMC_WAIT_POLARITY(POLARITY)         (((POLARITY) == EXMC_WAIT_SIGNAL_POLARITY_LOW) || \
                                                ((POLARITY) == EXMC_WAIT_SIGNAL_POLARITY_HIGH))
/**
  * @}
  */

/** @defgroup EXMC Wrap Mode 
  * @{
  */
#define EXMC_WRAP_MODE_DISABLE                  (0x00000000U)
#define EXMC_WRAP_MODE_ENABLE                   (0x00000400U)
#define IS_EXMC_WRAP_MODE(MODE)                 (((MODE) == EXMC_WRAP_MODE_DISABLE) || \
                                                ((MODE) == EXMC_WRAP_MODE_ENABLE))
/**
  * @}
  */

/** @defgroup EXMC Wait Timing
  * @{
  */
#define EXMC_WAITSIGNALACTIVE_BEFOREWAITSTATE   (0x00000000U)
#define EXMC_WAITSIGNALACTIVE_DURINGWAITSTATE   (0x00000800U)
#define IS_EXMC_WAIT_SIGNAL_ACTIVE(ACTIVE)      (((ACTIVE) == EXMC_WAITSIGNALACTIVE_BEFOREWAITSTATE) || \
                                                ((ACTIVE) == EXMC_WAITSIGNALACTIVE_DURINGWAITSTATE))
/**
  * @}
  */

/** @defgroup EXMC Write Operation
  * @{
  */
#define EXMC_WRITEOPERATION_DISABLE             (0x00000000U)
#define EXMC_WRITEOPERATION_ENABLE              (0x00001000U)
#define IS_EXMC_WRITE_OPERATION(OPERATION)      (((OPERATION) == EXMC_WRITEOPERATION_DISABLE) || \
                                                ((OPERATION) == EXMC_WRITEOPERATION_ENABLE)) 
/**
  * @}
  */

/** @defgroup EXMC Wait Signal
  * @{
  */
#define EXMC_WAIT_SIGNAL_DISABLE                (0x00000000U)
#define EXMC_WAIT_SIGNAL_ENABLE                 (0x00002000U)
#define IS_EXMC_WAITE_SIGNAL(SIGNAL)            (((SIGNAL) == EXMC_WAIT_SIGNAL_DISABLE) || \
                                                ((SIGNAL) == EXMC_WAIT_SIGNAL_ENABLE))
/**
  * @}
  */

/** @defgroup EXMC Extended Mode
  * @{
  */
#define EXMC_EXTENDED_MODE_DISABLE              (0x00000000U)
#define EXMC_EXTENDED_MODE_ENABLE               (0x00004000U)
#define IS_EXMC_EXTENDED_MODE(MODE)             (((MODE) == EXMC_EXTENDED_MODE_DISABLE) || \
                                                ((MODE) == EXMC_EXTENDED_MODE_ENABLE)) 
/**
  * @}
  */

/** @defgroup EXMC Asynchronous Wait
  * @{
  */
#define EXMC_ASYNCHRONOUS_WAIT_DISABLE          (0x00000000U)
#define EXMC_ASYNCHRONOUS_WAIT_ENABLE           (0x00008000U)
#define IS_EXMC_ASYNWAIT(STATE)                 (((STATE) == EXMC_ASYNCHRONOUS_WAIT_DISABLE) || \
                                                ((STATE) == EXMC_ASYNCHRONOUS_WAIT_ENABLE))
/**
  * @}
  */

/** @defgroup EXMC CRAM Page Size
  * @{
  */
#define EXMC_CRAMPAGE_SIZE_AUTO                 (0x00000000U)
#define EXMC_CRAMPPAGE_SIZE_128                 (0x00010000U)
#define EXMC_CRAMPPAGE_SIZE_256                 (0x00020000U)
#define EXMC_CRAMPPAGE_SIZE_512                 (0x00030000U)
#define EXMC_CRAMPPAGE_SIZE_1024                (0x00040000U)
#define IS_EXMC_CRAMPPAGE_SIZE(SIZE)            (((SIZE) == EXMC_CRAMPAGE_SIZE_AUTO) || \
                                                ((SIZE) == EXMC_CRAMPPAGE_SIZE_128) || \
                                                ((SIZE) == EXMC_CRAMPPAGE_SIZE_256) || \
                                                ((SIZE) == EXMC_CRAMPPAGE_SIZE_512) || \
                                                ((SIZE) == EXMC_CRAMPPAGE_SIZE_1024))
/**
  * @}
  */

/** @defgroup EXMC Write Burst
  * @{
  */
#define EXMC_WRITE_BURST_DISABLE                (0x00000000U)
#define EXMC_WRITE_BURST_ENABLE                 (0x00080000U)
#define IS_EXMC_WRITE_BURST(BURST)              (((BURST) == EXMC_WRITE_BURST_DISABLE) || \
                                                ((BURST) == EXMC_WRITE_BURST_ENABLE))
/**
  * @}
  */

/** @defgroup EXMC Address Setup Time 
  * @{
  */
#define IS_EXMC_ADDRESS_SETUP_TIME(TIME)        ((TIME) <= 0xF)
/**
  * @}
  */

/** @defgroup EXMC Address Hold Time 
  * @{
  */
#define IS_EXMC_ADDRESS_HOLD_TIME(TIME)         ((TIME) <= 0xF)
/**
  * @}
  */

/** @defgroup EXMC Data Setup Time 
  * @{
  */
#define IS_EXMC_DATASETUP_TIME(TIME)            ((TIME) <= 0xFF)
/**
  * @}
  */

/** @defgroup EXMC Bus Turn around Duration 
  * @{
  */
#define IS_EXMC_TURNAROUND_TIME(TIME)           ((TIME) <= 0xF)
/**
  * @}
  */

/** @defgroup EXMC CLK Division 
  * @{
  */
#define IS_EXMC_CLK_DIV(DIV)                    ((DIV) <= 0xF)
/**
  * @}
  */

/** @defgroup EXMC Data Latency 
  * @{
  */
#define IS_EXMC_DATA_LATENCY(LATENCY)           ((LATENCY) <= 0xF)
/**
  * @}
  */

/** @defgroup EXMC_Access_Mode EXMC Access Mode
* @{
*/
#define EXMC_ACCESS_MODE_A                      (0x00000000U)
#define EXMC_ACCESS_MODE_B                      (0x10000000U)
#define EXMC_ACCESS_MODE_C                      (0x20000000U)
#define EXMC_ACCESS_MODE_D                      (0x30000000U)
#define IS_EXMC_ACCESS_MODE(MODE)               (((MODE) == EXMC_ACCESS_MODE_A) || \
                                                ((MODE) == EXMC_ACCESS_MODE_B) || \
                                                ((MODE) == EXMC_ACCESS_MODE_C) || \
                                                ((MODE) == EXMC_ACCESS_MODE_D))
/**
* @}
*/


/*  Function used to set the EXMC configuration to the default reset state */
void EXMC_NORSRAMDeInit(void);

/* Initialization and Configuration functions */
void EXMC_NORSRAMInit(EXMC_NORSRAMInitTypeDef* EXMC_NORSRAMInitStruct);
void EXMC_NORSRAMStructInit(EXMC_NORSRAMInitTypeDef* EXMC_NORSRAMInitStruct);
void EXMC_NORSRAMCmd(uint32_t EXMC_Bank, FunctionalState NewState);


#endif
