647 lines
29 KiB
C
647 lines
29 KiB
C
|
/*!
|
||
|
\file gd32f10x_exmc.c
|
||
|
\brief EXMC driver
|
||
|
|
||
|
\version 2014-12-26, V1.0.0, firmware for GD32F10x
|
||
|
\version 2017-06-20, V2.0.0, firmware for GD32F10x
|
||
|
\version 2018-07-31, V2.1.0, firmware for GD32F10x
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
Copyright (c) 2018, GigaDevice Semiconductor Inc.
|
||
|
|
||
|
All rights reserved.
|
||
|
|
||
|
Redistribution and use in source and binary forms, with or without modification,
|
||
|
are permitted provided that the following conditions are met:
|
||
|
|
||
|
1. Redistributions of source code must retain the above copyright notice, this
|
||
|
list of conditions and the following disclaimer.
|
||
|
2. 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.
|
||
|
3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR 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.
|
||
|
*/
|
||
|
|
||
|
#include "gd32f10x_exmc.h"
|
||
|
|
||
|
/* EXMC bank0 register reset value */
|
||
|
#define BANK0_SNCTL0_REGION_RESET ((uint32_t)0x000030DBU)
|
||
|
#define BANK0_SNCTL1_2_3_REGION_RESET ((uint32_t)0x000030D2U)
|
||
|
#define BANK0_SNTCFG_RESET ((uint32_t)0x0FFFFFFFU)
|
||
|
#define BANK0_SNWTCFG_RESET ((uint32_t)0x0FFFFFFFU)
|
||
|
|
||
|
/* EXMC bank1/2 register reset mask*/
|
||
|
#define BANK1_2_NPCTL_RESET ((uint32_t)0x00000018U)
|
||
|
#define BANK1_2_NPINTEN_RESET ((uint32_t)0x00000040U)
|
||
|
#define BANK1_2_NPCTCFG_RESET ((uint32_t)0xFCFCFCFCU)
|
||
|
#define BANK1_2_NPATCFG_RESET ((uint32_t)0xFCFCFCFCU)
|
||
|
|
||
|
/* EXMC bank3 register reset mask*/
|
||
|
#define BANK3_NPCTL_RESET ((uint32_t)0x00000018U)
|
||
|
#define BANK3_NPINTEN_RESET ((uint32_t)0x00000040U)
|
||
|
#define BANK3_NPCTCFG_RESET ((uint32_t)0xFCFCFCFCU)
|
||
|
#define BANK3_NPATCFG_RESET ((uint32_t)0xFCFCFCFCU)
|
||
|
#define BANK3_PIOTCFG3_RESET ((uint32_t)0xFCFCFCFCU)
|
||
|
|
||
|
/* EXMC register bit offset */
|
||
|
#define SNCTL_NRMUX_OFFSET ((uint32_t)1U)
|
||
|
#define SNCTL_SBRSTEN_OFFSET ((uint32_t)8U)
|
||
|
#define SNCTL_WRAPEN_OFFSET ((uint32_t)10U)
|
||
|
#define SNCTL_WREN_OFFSET ((uint32_t)12U)
|
||
|
#define SNCTL_NRWTEN_OFFSET ((uint32_t)13U)
|
||
|
#define SNCTL_EXMODEN_OFFSET ((uint32_t)14U)
|
||
|
#define SNCTL_ASYNCWAIT_OFFSET ((uint32_t)15U)
|
||
|
|
||
|
#define SNTCFG_AHLD_OFFSET ((uint32_t)4U)
|
||
|
#define SNTCFG_DSET_OFFSET ((uint32_t)8U)
|
||
|
#define SNTCFG_BUSLAT_OFFSET ((uint32_t)16U)
|
||
|
|
||
|
#define SNWTCFG_WAHLD_OFFSET ((uint32_t)4U)
|
||
|
#define SNWTCFG_WDSET_OFFSET ((uint32_t)8U)
|
||
|
#define SNWTCFG_WBUSLAT_OFFSET ((uint32_t)16U)
|
||
|
|
||
|
#define NPCTL_NDWTEN_OFFSET ((uint32_t)1U)
|
||
|
#define NPCTL_ECCEN_OFFSET ((uint32_t)6U)
|
||
|
|
||
|
#define NPCTCFG_COMWAIT_OFFSET ((uint32_t)8U)
|
||
|
#define NPCTCFG_COMHLD_OFFSET ((uint32_t)16U)
|
||
|
#define NPCTCFG_COMHIZ_OFFSET ((uint32_t)24U)
|
||
|
|
||
|
#define NPATCFG_ATTWAIT_OFFSET ((uint32_t)8U)
|
||
|
#define NPATCFG_ATTHLD_OFFSET ((uint32_t)16U)
|
||
|
#define NPATCFG_ATTHIZ_OFFSET ((uint32_t)24U)
|
||
|
|
||
|
#define PIOTCFG_IOWAIT_OFFSET ((uint32_t)8U)
|
||
|
#define PIOTCFG_IOHLD_OFFSET ((uint32_t)16U)
|
||
|
#define PIOTCFG_IOHIZ_OFFSET ((uint32_t)24U)
|
||
|
|
||
|
#define INTEN_INTS_OFFSET ((uint32_t)3U)
|
||
|
|
||
|
/*!
|
||
|
\brief deinitialize EXMC NOR/SRAM region
|
||
|
\param[in] norsram_region: select the region of bank0
|
||
|
\arg EXMC_BANK0_NORSRAM_REGIONx(x=0..3)
|
||
|
\param[out] none
|
||
|
\retval none
|
||
|
*/
|
||
|
void exmc_norsram_deinit(uint32_t norsram_region)
|
||
|
{
|
||
|
/* reset the registers */
|
||
|
if(EXMC_BANK0_NORSRAM_REGION0 == norsram_region){
|
||
|
EXMC_SNCTL(norsram_region) = BANK0_SNCTL0_REGION_RESET;
|
||
|
}else{
|
||
|
EXMC_SNCTL(norsram_region) = BANK0_SNCTL1_2_3_REGION_RESET;
|
||
|
}
|
||
|
|
||
|
EXMC_SNTCFG(norsram_region) = BANK0_SNTCFG_RESET;
|
||
|
EXMC_SNWTCFG(norsram_region) = BANK0_SNWTCFG_RESET;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief initialize EXMC NOR/SRAM region
|
||
|
\param[in] exmc_norsram_parameter_struct: configure the EXMC NOR/SRAM parameter
|
||
|
norsram_region: EXMC_BANK0_NORSRAM_REGIONx,x=0..3
|
||
|
write_mode: EXMC_ASYN_WRITE,EXMC_SYN_WRITE
|
||
|
extended_mode: ENABLE or DISABLE
|
||
|
asyn_wait: ENABLE or DISABLE
|
||
|
nwait_signal: ENABLE or DISABLE
|
||
|
memory_write: ENABLE or DISABLE
|
||
|
nwait_config: EXMC_NWAIT_CONFIG_BEFORE,EXMC_NWAIT_CONFIG_DURING
|
||
|
wrap_burst_mode: ENABLE or DISABLE
|
||
|
nwait_polarity: EXMC_NWAIT_POLARITY_LOW,EXMC_NWAIT_POLARITY_HIGH
|
||
|
burst_mode: ENABLE or DISABLE
|
||
|
databus_width: EXMC_NOR_DATABUS_WIDTH_8B,EXMC_NOR_DATABUS_WIDTH_16B
|
||
|
memory_type: EXMC_MEMORY_TYPE_SRAM,EXMC_MEMORY_TYPE_PSRAM,EXMC_MEMORY_TYPE_NOR
|
||
|
address_data_mux: ENABLE or DISABLE
|
||
|
read_write_timing: struct exmc_norsram_timing_parameter_struct set the time
|
||
|
write_timing: struct exmc_norsram_timing_parameter_struct set the time
|
||
|
\param[out] none
|
||
|
\retval none
|
||
|
*/
|
||
|
void exmc_norsram_init(exmc_norsram_parameter_struct* exmc_norsram_init_struct)
|
||
|
{
|
||
|
uint32_t snctl = 0x00000000U, sntcfg = 0x00000000U, snwtcfg = 0x00000000U;
|
||
|
|
||
|
/* get the register value */
|
||
|
snctl = EXMC_SNCTL(exmc_norsram_init_struct->norsram_region);
|
||
|
|
||
|
/* clear relative bits */
|
||
|
snctl &= ((uint32_t)~(EXMC_SNCTL_NREN | EXMC_SNCTL_NRTP | EXMC_SNCTL_NRW | EXMC_SNCTL_SBRSTEN |
|
||
|
EXMC_SNCTL_NRWTPOL | EXMC_SNCTL_WRAPEN | EXMC_SNCTL_NRWTCFG | EXMC_SNCTL_WREN |
|
||
|
EXMC_SNCTL_NRWTEN | EXMC_SNCTL_EXMODEN | EXMC_SNCTL_ASYNCWAIT | EXMC_SNCTL_SYNCWR |
|
||
|
EXMC_SNCTL_NRMUX ));
|
||
|
|
||
|
snctl |= (uint32_t)(exmc_norsram_init_struct->address_data_mux << SNCTL_NRMUX_OFFSET) |
|
||
|
exmc_norsram_init_struct->memory_type |
|
||
|
exmc_norsram_init_struct->databus_width |
|
||
|
(exmc_norsram_init_struct->burst_mode << SNCTL_SBRSTEN_OFFSET) |
|
||
|
exmc_norsram_init_struct->nwait_polarity |
|
||
|
(exmc_norsram_init_struct->wrap_burst_mode << SNCTL_WRAPEN_OFFSET) |
|
||
|
exmc_norsram_init_struct->nwait_config |
|
||
|
(exmc_norsram_init_struct->memory_write << SNCTL_WREN_OFFSET) |
|
||
|
(exmc_norsram_init_struct->nwait_signal << SNCTL_NRWTEN_OFFSET) |
|
||
|
(exmc_norsram_init_struct->extended_mode << SNCTL_EXMODEN_OFFSET) |
|
||
|
(exmc_norsram_init_struct->asyn_wait << SNCTL_ASYNCWAIT_OFFSET) |
|
||
|
exmc_norsram_init_struct->write_mode;
|
||
|
|
||
|
sntcfg = (uint32_t)((exmc_norsram_init_struct->read_write_timing->asyn_address_setuptime - 1U ) & EXMC_SNTCFG_ASET )|
|
||
|
(((exmc_norsram_init_struct->read_write_timing->asyn_address_holdtime - 1U ) << SNTCFG_AHLD_OFFSET ) & EXMC_SNTCFG_AHLD ) |
|
||
|
(((exmc_norsram_init_struct->read_write_timing->asyn_data_setuptime - 1U ) << SNTCFG_DSET_OFFSET ) & EXMC_SNTCFG_DSET ) |
|
||
|
(((exmc_norsram_init_struct->read_write_timing->bus_latency - 1U ) << SNTCFG_BUSLAT_OFFSET ) & EXMC_SNTCFG_BUSLAT )|
|
||
|
exmc_norsram_init_struct->read_write_timing->syn_clk_division |
|
||
|
exmc_norsram_init_struct->read_write_timing->syn_data_latency |
|
||
|
exmc_norsram_init_struct->read_write_timing->asyn_access_mode;
|
||
|
|
||
|
/* nor flash access enable */
|
||
|
if(EXMC_MEMORY_TYPE_NOR == exmc_norsram_init_struct->memory_type){
|
||
|
snctl |= (uint32_t)EXMC_SNCTL_NREN;
|
||
|
}
|
||
|
|
||
|
/* extended mode configure */
|
||
|
if(ENABLE == exmc_norsram_init_struct->extended_mode){
|
||
|
snwtcfg = (uint32_t)(((exmc_norsram_init_struct->write_timing->asyn_address_setuptime - 1U) & EXMC_SNWTCFG_WASET) |
|
||
|
(((exmc_norsram_init_struct->write_timing->asyn_address_holdtime - 1U) << SNTCFG_AHLD_OFFSET ) & EXMC_SNWTCFG_WAHLD)|
|
||
|
(((exmc_norsram_init_struct->write_timing->asyn_data_setuptime - 1U) << SNTCFG_DSET_OFFSET) & EXMC_SNWTCFG_WDSET) |
|
||
|
exmc_norsram_init_struct->write_timing->asyn_access_mode);
|
||
|
}else{
|
||
|
snwtcfg = BANK0_SNWTCFG_RESET;
|
||
|
}
|
||
|
|
||
|
/* configure the registers */
|
||
|
EXMC_SNCTL(exmc_norsram_init_struct->norsram_region) = snctl;
|
||
|
EXMC_SNTCFG(exmc_norsram_init_struct->norsram_region) = sntcfg;
|
||
|
EXMC_SNWTCFG(exmc_norsram_init_struct->norsram_region) = snwtcfg;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief initialize the struct exmc_norsram_parameter_struct
|
||
|
\param[in] none
|
||
|
\param[out] exmc_norsram_init_struct: the initialized struct exmc_norsram_parameter_struct pointer
|
||
|
\retval none
|
||
|
*/
|
||
|
void exmc_norsram_struct_para_init(exmc_norsram_parameter_struct* exmc_norsram_init_struct)
|
||
|
{
|
||
|
/* configure the structure with default value */
|
||
|
exmc_norsram_init_struct->norsram_region = EXMC_BANK0_NORSRAM_REGION0;
|
||
|
exmc_norsram_init_struct->address_data_mux = ENABLE;
|
||
|
exmc_norsram_init_struct->memory_type = EXMC_MEMORY_TYPE_SRAM;
|
||
|
exmc_norsram_init_struct->databus_width = EXMC_NOR_DATABUS_WIDTH_8B;
|
||
|
exmc_norsram_init_struct->burst_mode = DISABLE;
|
||
|
exmc_norsram_init_struct->nwait_polarity = EXMC_NWAIT_POLARITY_LOW;
|
||
|
exmc_norsram_init_struct->wrap_burst_mode = DISABLE;
|
||
|
exmc_norsram_init_struct->nwait_config = EXMC_NWAIT_CONFIG_BEFORE;
|
||
|
exmc_norsram_init_struct->memory_write = ENABLE;
|
||
|
exmc_norsram_init_struct->nwait_signal = ENABLE;
|
||
|
exmc_norsram_init_struct->extended_mode = DISABLE;
|
||
|
exmc_norsram_init_struct->asyn_wait = DISABLE;
|
||
|
exmc_norsram_init_struct->write_mode = EXMC_ASYN_WRITE;
|
||
|
|
||
|
/* read/write timing configure */
|
||
|
exmc_norsram_init_struct->read_write_timing->asyn_address_setuptime = 0xFU;
|
||
|
exmc_norsram_init_struct->read_write_timing->asyn_address_holdtime = 0xFU;
|
||
|
exmc_norsram_init_struct->read_write_timing->asyn_data_setuptime = 0xFFU;
|
||
|
exmc_norsram_init_struct->read_write_timing->bus_latency = 0xFU;
|
||
|
exmc_norsram_init_struct->read_write_timing->syn_clk_division = EXMC_SYN_CLOCK_RATIO_16_CLK;
|
||
|
exmc_norsram_init_struct->read_write_timing->syn_data_latency = EXMC_DATALAT_17_CLK;
|
||
|
exmc_norsram_init_struct->read_write_timing->asyn_access_mode = EXMC_ACCESS_MODE_A;
|
||
|
|
||
|
/* write timing configure, when extended mode is used */
|
||
|
exmc_norsram_init_struct->write_timing->asyn_address_setuptime = 0xFU;
|
||
|
exmc_norsram_init_struct->write_timing->asyn_address_holdtime = 0xFU;
|
||
|
exmc_norsram_init_struct->write_timing->asyn_data_setuptime = 0xFFU;
|
||
|
exmc_norsram_init_struct->write_timing->bus_latency = 0xFU;
|
||
|
exmc_norsram_init_struct->write_timing->asyn_access_mode = EXMC_ACCESS_MODE_A;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief enable EXMC NOR/PSRAM bank region
|
||
|
\param[in] norsram_region: specifie the region of NOR/PSRAM bank
|
||
|
\arg EXMC_BANK0_NORSRAM_REGIONx(x=0..3)
|
||
|
\param[out] none
|
||
|
\retval none
|
||
|
*/
|
||
|
void exmc_norsram_enable(uint32_t norsram_region)
|
||
|
{
|
||
|
EXMC_SNCTL(norsram_region) |= (uint32_t)EXMC_SNCTL_NRBKEN;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief disable EXMC NOR/PSRAM bank region
|
||
|
\param[in] norsram_region: specifie the region of NOR/PSRAM Bank
|
||
|
\arg EXMC_BANK0_NORSRAM_REGIONx(x=0..3)
|
||
|
\param[out] none
|
||
|
\retval none
|
||
|
*/
|
||
|
void exmc_norsram_disable(uint32_t norsram_region)
|
||
|
{
|
||
|
EXMC_SNCTL(norsram_region) &= ~(uint32_t)EXMC_SNCTL_NRBKEN;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief deinitialize EXMC NAND bank
|
||
|
\param[in] nand_bank: select the bank of NAND
|
||
|
\arg EXMC_BANKx_NAND(x=1..2)
|
||
|
\param[out] none
|
||
|
\retval none
|
||
|
*/
|
||
|
void exmc_nand_deinit(uint32_t nand_bank)
|
||
|
{
|
||
|
/* EXMC_BANK1_NAND or EXMC_BANK2_NAND */
|
||
|
EXMC_NPCTL(nand_bank) = BANK1_2_NPCTL_RESET;
|
||
|
EXMC_NPINTEN(nand_bank) = BANK1_2_NPINTEN_RESET;
|
||
|
EXMC_NPCTCFG(nand_bank) = BANK1_2_NPCTCFG_RESET;
|
||
|
EXMC_NPATCFG(nand_bank) = BANK1_2_NPATCFG_RESET;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief initialize EXMC NAND bank
|
||
|
\param[in] exmc_nand_parameter_struct: configure the EXMC NAND parameter
|
||
|
nand_bank: EXMC_BANK1_NAND,EXMC_BANK2_NAND
|
||
|
ecc_size: EXMC_ECC_SIZE_xBYTES,x=256,512,1024,2048,4096
|
||
|
atr_latency: EXMC_ALE_RE_DELAY_x_HCLK,x=1..16
|
||
|
ctr_latency: EXMC_CLE_RE_DELAY_x_HCLK,x=1..16
|
||
|
ecc_logic: ENABLE or DISABLE
|
||
|
databus_width: EXMC_NAND_DATABUS_WIDTH_8B,EXMC_NAND_DATABUS_WIDTH_16B
|
||
|
wait_feature: ENABLE or DISABLE
|
||
|
common_space_timing: struct exmc_nand_pccard_timing_parameter_struct set the time
|
||
|
attribute_space_timing: struct exmc_nand_pccard_timing_parameter_struct set the time
|
||
|
\param[out] none
|
||
|
\retval none
|
||
|
*/
|
||
|
void exmc_nand_init(exmc_nand_parameter_struct* exmc_nand_init_struct)
|
||
|
{
|
||
|
uint32_t npctl = 0x00000000U, npctcfg = 0x00000000U, npatcfg = 0x00000000U;
|
||
|
|
||
|
npctl = (uint32_t)(exmc_nand_init_struct->wait_feature << NPCTL_NDWTEN_OFFSET)|
|
||
|
EXMC_NPCTL_NDTP |
|
||
|
exmc_nand_init_struct->databus_width |
|
||
|
(exmc_nand_init_struct->ecc_logic << NPCTL_ECCEN_OFFSET)|
|
||
|
exmc_nand_init_struct->ecc_size |
|
||
|
exmc_nand_init_struct->ctr_latency |
|
||
|
exmc_nand_init_struct->atr_latency;
|
||
|
|
||
|
npctcfg = (uint32_t)((exmc_nand_init_struct->common_space_timing->setuptime - 1U) & EXMC_NPCTCFG_COMSET ) |
|
||
|
(((exmc_nand_init_struct->common_space_timing->waittime - 1U) << NPCTCFG_COMWAIT_OFFSET) & EXMC_NPCTCFG_COMWAIT ) |
|
||
|
((exmc_nand_init_struct->common_space_timing->holdtime << NPCTCFG_COMHLD_OFFSET) & EXMC_NPCTCFG_COMHLD ) |
|
||
|
(((exmc_nand_init_struct->common_space_timing->databus_hiztime - 1U) << NPCTCFG_COMHIZ_OFFSET) & EXMC_NPCTCFG_COMHIZ );
|
||
|
|
||
|
npatcfg = (uint32_t)((exmc_nand_init_struct->attribute_space_timing->setuptime - 1U) & EXMC_NPATCFG_ATTSET ) |
|
||
|
(((exmc_nand_init_struct->attribute_space_timing->waittime - 1U) << NPATCFG_ATTWAIT_OFFSET) & EXMC_NPATCFG_ATTWAIT ) |
|
||
|
((exmc_nand_init_struct->attribute_space_timing->holdtime << NPATCFG_ATTHLD_OFFSET) & EXMC_NPATCFG_ATTHLD ) |
|
||
|
(((exmc_nand_init_struct->attribute_space_timing->databus_hiztime -1U) << NPATCFG_ATTHIZ_OFFSET) & EXMC_NPATCFG_ATTHIZ );
|
||
|
|
||
|
/* EXMC_BANK1_NAND or EXMC_BANK2_NAND initialize */
|
||
|
EXMC_NPCTL(exmc_nand_init_struct->nand_bank) = npctl;
|
||
|
EXMC_NPCTCFG(exmc_nand_init_struct->nand_bank) = npctcfg;
|
||
|
EXMC_NPATCFG(exmc_nand_init_struct->nand_bank) = npatcfg;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief initialize the struct exmc_nand_init_struct
|
||
|
\param[in] none
|
||
|
\param[out] the initialized struct exmc_nand_init_struct pointer
|
||
|
\retval none
|
||
|
*/
|
||
|
void exmc_nand_struct_para_init(exmc_nand_parameter_struct* exmc_nand_init_struct)
|
||
|
{
|
||
|
/* configure the structure with default value */
|
||
|
exmc_nand_init_struct->nand_bank = EXMC_BANK1_NAND;
|
||
|
exmc_nand_init_struct->wait_feature = DISABLE;
|
||
|
exmc_nand_init_struct->databus_width = EXMC_NAND_DATABUS_WIDTH_8B;
|
||
|
exmc_nand_init_struct->ecc_logic = DISABLE;
|
||
|
exmc_nand_init_struct->ecc_size = EXMC_ECC_SIZE_256BYTES;
|
||
|
exmc_nand_init_struct->ctr_latency = 0x0U;
|
||
|
exmc_nand_init_struct->atr_latency = 0x0U;
|
||
|
exmc_nand_init_struct->common_space_timing->setuptime = 0xFCU;
|
||
|
exmc_nand_init_struct->common_space_timing->waittime = 0xFCU;
|
||
|
exmc_nand_init_struct->common_space_timing->holdtime = 0xFCU;
|
||
|
exmc_nand_init_struct->common_space_timing->databus_hiztime = 0xFCU;
|
||
|
exmc_nand_init_struct->attribute_space_timing->setuptime = 0xFCU;
|
||
|
exmc_nand_init_struct->attribute_space_timing->waittime = 0xFCU;
|
||
|
exmc_nand_init_struct->attribute_space_timing->holdtime = 0xFCU;
|
||
|
exmc_nand_init_struct->attribute_space_timing->databus_hiztime = 0xFCU;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief enable NAND bank
|
||
|
\param[in] nand_bank: specifie the NAND bank
|
||
|
\arg EXMC_BANKx_NAND(x=1,2)
|
||
|
\param[out] none
|
||
|
\retval none
|
||
|
*/
|
||
|
void exmc_nand_enable(uint32_t nand_bank)
|
||
|
{
|
||
|
EXMC_NPCTL(nand_bank) |= EXMC_NPCTL_NDBKEN;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief disable NAND bank
|
||
|
\param[in] nand_bank: specifie the NAND bank
|
||
|
\arg EXMC_BANKx_NAND(x=1,2)
|
||
|
\param[out] none
|
||
|
\retval none
|
||
|
*/
|
||
|
void exmc_nand_disable(uint32_t nand_bank)
|
||
|
{
|
||
|
EXMC_NPCTL(nand_bank) &= ~EXMC_NPCTL_NDBKEN;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief enable or disable the EXMC NAND ECC function
|
||
|
\param[in] nand_bank: specifie the NAND bank
|
||
|
\arg EXMC_BANKx_NAND(x=1,2)
|
||
|
\param[in] newvalue: ENABLE or DISABLE
|
||
|
\param[out] none
|
||
|
\retval none
|
||
|
*/
|
||
|
void exmc_nand_ecc_config(uint32_t nand_bank, ControlStatus newvalue)
|
||
|
{
|
||
|
if (ENABLE == newvalue){
|
||
|
/* enable the selected NAND bank ECC function */
|
||
|
EXMC_NPCTL(nand_bank) |= EXMC_NPCTL_ECCEN;
|
||
|
}else{
|
||
|
/* disable the selected NAND bank ECC function */
|
||
|
EXMC_NPCTL(nand_bank) &= ~EXMC_NPCTL_ECCEN;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief get the EXMC ECC value
|
||
|
\param[in] nand_bank: specifie the NAND bank
|
||
|
\arg EXMC_BANKx_NAND(x=1,2)
|
||
|
\param[out] none
|
||
|
\retval the error correction code(ECC) value
|
||
|
*/
|
||
|
uint32_t exmc_ecc_get(uint32_t nand_bank)
|
||
|
{
|
||
|
return (EXMC_NECC(nand_bank));
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief deinitialize EXMC PC card bank
|
||
|
\param[in] none
|
||
|
\param[out] none
|
||
|
\retval none
|
||
|
*/
|
||
|
void exmc_pccard_deinit(void)
|
||
|
{
|
||
|
/* EXMC_BANK3_PCCARD */
|
||
|
EXMC_NPCTL3 = BANK3_NPCTL_RESET;
|
||
|
EXMC_NPINTEN3 = BANK3_NPINTEN_RESET;
|
||
|
EXMC_NPCTCFG3 = BANK3_NPCTCFG_RESET;
|
||
|
EXMC_NPATCFG3 = BANK3_NPATCFG_RESET;
|
||
|
EXMC_PIOTCFG3 = BANK3_PIOTCFG3_RESET;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief initialize EXMC PC card bank
|
||
|
\param[in] exmc_pccard_parameter_struct: configure the EXMC NAND parameter
|
||
|
atr_latency: EXMC_ALE_RE_DELAY_x_HCLK,x=1..16
|
||
|
ctr_latency: EXMC_CLE_RE_DELAY_x_HCLK,x=1..16
|
||
|
wait_feature: ENABLE or DISABLE
|
||
|
common_space_timing: struct exmc_nand_pccard_timing_parameter_struct set the time
|
||
|
attribute_space_timing: struct exmc_nand_pccard_timing_parameter_struct set the time
|
||
|
io_space_timing: exmc_nand_pccard_timing_parameter_struct set the time
|
||
|
\param[out] none
|
||
|
\retval none
|
||
|
*/
|
||
|
void exmc_pccard_init(exmc_pccard_parameter_struct* exmc_pccard_init_struct)
|
||
|
{
|
||
|
/* configure the EXMC bank3 PC card control register */
|
||
|
EXMC_NPCTL3 = (uint32_t)(exmc_pccard_init_struct->wait_feature << NPCTL_NDWTEN_OFFSET) |
|
||
|
EXMC_NAND_DATABUS_WIDTH_16B |
|
||
|
exmc_pccard_init_struct->ctr_latency |
|
||
|
exmc_pccard_init_struct->atr_latency ;
|
||
|
|
||
|
/* configure the EXMC bank3 PC card common space timing configuration register */
|
||
|
EXMC_NPCTCFG3 = (uint32_t)((exmc_pccard_init_struct->common_space_timing->setuptime - 1U)& EXMC_NPCTCFG_COMSET ) |
|
||
|
(((exmc_pccard_init_struct->common_space_timing->waittime - 1U) << NPCTCFG_COMWAIT_OFFSET) & EXMC_NPCTCFG_COMWAIT ) |
|
||
|
((exmc_pccard_init_struct->common_space_timing->holdtime << NPCTCFG_COMHLD_OFFSET) & EXMC_NPCTCFG_COMHLD ) |
|
||
|
(((exmc_pccard_init_struct->common_space_timing->databus_hiztime - 1U) << NPCTCFG_COMHIZ_OFFSET) & EXMC_NPCTCFG_COMHIZ );
|
||
|
|
||
|
/* configure the EXMC bank3 PC card attribute space timing configuration register */
|
||
|
EXMC_NPATCFG3 = (uint32_t)((exmc_pccard_init_struct->attribute_space_timing->setuptime - 1U) & EXMC_NPATCFG_ATTSET ) |
|
||
|
(((exmc_pccard_init_struct->attribute_space_timing->waittime - 1U) << NPATCFG_ATTWAIT_OFFSET) & EXMC_NPATCFG_ATTWAIT ) |
|
||
|
((exmc_pccard_init_struct->attribute_space_timing->holdtime << NPATCFG_ATTHLD_OFFSET) & EXMC_NPATCFG_ATTHLD )|
|
||
|
(((exmc_pccard_init_struct->attribute_space_timing->databus_hiztime -1U) << NPATCFG_ATTHIZ_OFFSET) & EXMC_NPATCFG_ATTHIZ );
|
||
|
|
||
|
/* configure the EXMC bank3 PC card io space timing configuration register */
|
||
|
EXMC_PIOTCFG3 = (uint32_t)((exmc_pccard_init_struct->io_space_timing->setuptime - 1U) & EXMC_PIOTCFG3_IOSET ) |
|
||
|
(((exmc_pccard_init_struct->io_space_timing->waittime - 1U) << PIOTCFG_IOWAIT_OFFSET) & EXMC_PIOTCFG3_IOWAIT ) |
|
||
|
((exmc_pccard_init_struct->io_space_timing->holdtime << PIOTCFG_IOHLD_OFFSET) & EXMC_PIOTCFG3_IOHLD )|
|
||
|
((exmc_pccard_init_struct->io_space_timing->databus_hiztime << PIOTCFG_IOHIZ_OFFSET) & EXMC_PIOTCFG3_IOHIZ );
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief initialize the struct exmc_pccard_parameter_struct
|
||
|
\param[in] none
|
||
|
\param[out] the initialized struct exmc_pccard_parameter_struct pointer
|
||
|
\retval none
|
||
|
*/
|
||
|
void exmc_pccard_struct_para_init(exmc_pccard_parameter_struct* exmc_pccard_init_struct)
|
||
|
{
|
||
|
/* configure the structure with default value */
|
||
|
exmc_pccard_init_struct->wait_feature = DISABLE;
|
||
|
exmc_pccard_init_struct->ctr_latency = 0x0U;
|
||
|
exmc_pccard_init_struct->atr_latency = 0x0U;
|
||
|
exmc_pccard_init_struct->common_space_timing->setuptime = 0xFCU;
|
||
|
exmc_pccard_init_struct->common_space_timing->waittime = 0xFCU;
|
||
|
exmc_pccard_init_struct->common_space_timing->holdtime = 0xFCU;
|
||
|
exmc_pccard_init_struct->common_space_timing->databus_hiztime = 0xFCU;
|
||
|
exmc_pccard_init_struct->attribute_space_timing->setuptime = 0xFCU;
|
||
|
exmc_pccard_init_struct->attribute_space_timing->waittime = 0xFCU;
|
||
|
exmc_pccard_init_struct->attribute_space_timing->holdtime = 0xFCU;
|
||
|
exmc_pccard_init_struct->attribute_space_timing->databus_hiztime = 0xFCU;
|
||
|
exmc_pccard_init_struct->io_space_timing->setuptime = 0xFCU;
|
||
|
exmc_pccard_init_struct->io_space_timing->waittime = 0xFCU;
|
||
|
exmc_pccard_init_struct->io_space_timing->holdtime = 0xFCU;
|
||
|
exmc_pccard_init_struct->io_space_timing->databus_hiztime = 0xFCU;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief enable PC Card Bank
|
||
|
\param[in] none
|
||
|
\param[out] none
|
||
|
\retval none
|
||
|
*/
|
||
|
void exmc_pccard_enable(void)
|
||
|
{
|
||
|
EXMC_NPCTL3 |= EXMC_NPCTL_NDBKEN;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief disable PC Card Bank
|
||
|
\param[in] none
|
||
|
\param[out] none
|
||
|
\retval none
|
||
|
*/
|
||
|
void exmc_pccard_disable(void)
|
||
|
{
|
||
|
EXMC_NPCTL3 &= ~EXMC_NPCTL_NDBKEN;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief enable EXMC interrupt
|
||
|
\param[in] bank: specifies the NAND bank, PC card bank
|
||
|
only one parameter can be selected which is shown as below:
|
||
|
\arg EXMC_BANK1_NAND: the NAND bank1
|
||
|
\arg EXMC_BANK2_NAND: the NAND bank2
|
||
|
\arg EXMC_BANK3_PCCARD: the PC card bank
|
||
|
\param[in] interrupt_source: specify get which interrupt flag
|
||
|
one or more parameters can be selected which is shown as below:
|
||
|
\arg EXMC_NAND_PCCARD_INT_RISE: interrupt source of rising edge
|
||
|
\arg EXMC_NAND_PCCARD_INT_LEVEL: interrupt source of high-level
|
||
|
\arg EXMC_NAND_PCCARD_INT_FALL: interrupt source of falling edge
|
||
|
\param[out] none
|
||
|
\retval none
|
||
|
*/
|
||
|
void exmc_interrupt_enable(uint32_t bank, uint32_t interrupt_source)
|
||
|
{
|
||
|
/* NAND bank1, bank2 or PC card bank3 */
|
||
|
EXMC_NPINTEN(bank) |= interrupt_source;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief disable EXMC interrupt
|
||
|
\param[in] bank: specifies the NAND bank, PC card bank
|
||
|
only one parameter can be selected which is shown as below:
|
||
|
\arg EXMC_BANK1_NAND: the NAND bank1
|
||
|
\arg EXMC_BANK2_NAND: the NAND bank2
|
||
|
\arg EXMC_BANK3_PCCARD: the PC card bank
|
||
|
\param[in] interrupt_source: specify get which interrupt flag
|
||
|
one or more parameters can be selected which is shown as below:
|
||
|
\arg EXMC_NAND_PCCARD_INT_RISE: interrupt source of rising edge
|
||
|
\arg EXMC_NAND_PCCARD_INT_LEVEL: interrupt source of high-level
|
||
|
\arg EXMC_NAND_PCCARD_INT_FALL: interrupt source of falling edge
|
||
|
\param[out] none
|
||
|
\retval none
|
||
|
*/
|
||
|
void exmc_interrupt_disable(uint32_t bank, uint32_t interrupt_source)
|
||
|
{
|
||
|
/* NAND bank1,bank2 or PC card bank3 */
|
||
|
EXMC_NPINTEN(bank) &= ~interrupt_source;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief check EXMC flag is set or not
|
||
|
\param[in] bank: specifies the NAND bank, PC card bank
|
||
|
only one parameter can be selected which is shown as below:
|
||
|
\arg EXMC_BANK1_NAND: the NAND bank1
|
||
|
\arg EXMC_BANK2_NAND: the NAND bank2
|
||
|
\arg EXMC_BANK3_PCCARD: the PC Card bank
|
||
|
\param[in] flag: specify get which flag
|
||
|
only one parameter can be selected which is shown as below:
|
||
|
\arg EXMC_NAND_PCCARD_FLAG_RISE: interrupt rising edge status
|
||
|
\arg EXMC_NAND_PCCARD_FLAG_LEVEL: interrupt high-level status
|
||
|
\arg EXMC_NAND_PCCARD_FLAG_FALL: interrupt falling edge status
|
||
|
\arg EXMC_NAND_PCCARD_FLAG_FIFOE: FIFO empty flag
|
||
|
\param[out] none
|
||
|
\retval FlagStatus: SET or RESET
|
||
|
*/
|
||
|
FlagStatus exmc_flag_get(uint32_t bank, uint32_t flag)
|
||
|
{
|
||
|
uint32_t status = 0x00000000U;
|
||
|
|
||
|
/* NAND bank1,bank2 or PC card bank3 */
|
||
|
status = EXMC_NPINTEN(bank);
|
||
|
|
||
|
if ((status & flag) != (uint32_t)flag ){
|
||
|
/* flag is reset */
|
||
|
return RESET;
|
||
|
}else{
|
||
|
/* flag is set */
|
||
|
return SET;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief clear EXMC flag
|
||
|
\param[in] bank: specifie the NAND bank, PCCARD bank
|
||
|
only one parameter can be selected which is shown as below:
|
||
|
\arg EXMC_BANK1_NAND: the NAND bank1
|
||
|
\arg EXMC_BANK2_NAND: the NAND bank2
|
||
|
\arg EXMC_BANK3_PCCARD: the PC card bank
|
||
|
\param[in] flag: specify get which flag
|
||
|
one or more parameters can be selected which is shown as below:
|
||
|
\arg EXMC_NAND_PCCARD_FLAG_RISE: interrupt rising edge status
|
||
|
\arg EXMC_NAND_PCCARD_FLAG_LEVEL: interrupt high-level status
|
||
|
\arg EXMC_NAND_PCCARD_FLAG_FALL: interrupt falling edge status
|
||
|
\arg EXMC_NAND_PCCARD_FLAG_FIFOE: FIFO empty flag
|
||
|
\param[out] none
|
||
|
\retval none
|
||
|
*/
|
||
|
void exmc_flag_clear(uint32_t bank, uint32_t flag)
|
||
|
{
|
||
|
/* NAND bank1,bank2 or PC card bank3 */
|
||
|
EXMC_NPINTEN(bank) &= ~flag;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief check EXMC interrupt flag is set or not
|
||
|
\param[in] bank: specifies the NAND bank, PC card bank
|
||
|
only one parameter can be selected which is shown as below:
|
||
|
\arg EXMC_BANK1_NAND: the NAND bank1
|
||
|
\arg EXMC_BANK2_NAND: the NAND bank2
|
||
|
\arg EXMC_BANK3_PCCARD: the PC card bank
|
||
|
\param[in] interrupt_source: specify get which interrupt flag
|
||
|
only one parameter can be selected which is shown as below:
|
||
|
\arg EXMC_NAND_PCCARD_INT_RISE: interrupt source of rising edge
|
||
|
\arg EXMC_NAND_PCCARD_INT_LEVEL: interrupt source of high-level
|
||
|
\arg EXMC_NAND_PCCARD_INT_FALL: interrupt source of falling edge
|
||
|
\param[out] none
|
||
|
\retval FlagStatus: SET or RESET
|
||
|
*/
|
||
|
FlagStatus exmc_interrupt_flag_get(uint32_t bank, uint32_t interrupt_source)
|
||
|
{
|
||
|
uint32_t status = 0x00000000U,interrupt_enable = 0x00000000U,interrupt_state = 0x00000000U;
|
||
|
|
||
|
/* NAND bank1,bank2 or PC card bank3 */
|
||
|
status = EXMC_NPINTEN(bank);
|
||
|
interrupt_state = (status & (interrupt_source >> INTEN_INTS_OFFSET));
|
||
|
|
||
|
interrupt_enable = (status & interrupt_source);
|
||
|
|
||
|
if ((interrupt_enable) && (interrupt_state)){
|
||
|
/* interrupt flag is set */
|
||
|
return SET;
|
||
|
}else{
|
||
|
/* interrupt flag is reset */
|
||
|
return RESET;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\brief clear EXMC interrupt flag
|
||
|
\param[in] bank: specifies the NAND bank, PC card bank
|
||
|
only one parameter can be selected which is shown as below:
|
||
|
\arg EXMC_BANK1_NAND: the NAND bank1
|
||
|
\arg EXMC_BANK2_NAND: the NAND bank2
|
||
|
\arg EXMC_BANK3_PCCARD: the PC card bank
|
||
|
\param[in] interrupt_source: specify get which interrupt flag
|
||
|
one or more parameters can be selected which is shown as below:
|
||
|
\arg EXMC_NAND_PCCARD_INT_RISE: interrupt source of rising edge
|
||
|
\arg EXMC_NAND_PCCARD_INT_LEVEL: interrupt source of high-level
|
||
|
\arg EXMC_NAND_PCCARD_INT_FALL: interrupt source of falling edge
|
||
|
\param[out] none
|
||
|
\retval none
|
||
|
*/
|
||
|
void exmc_interrupt_flag_clear(uint32_t bank, uint32_t interrupt_source)
|
||
|
{
|
||
|
/* NAND bank1, bank2 or PC card bank3 */
|
||
|
EXMC_NPINTEN(bank) &= ~(interrupt_source >> INTEN_INTS_OFFSET);
|
||
|
}
|