Files
Motor_v2/Robot_V2/RTE/Device/GD32C103CB/gd32c10x_exmc.c
T

251 lines
11 KiB
C
Raw Normal View History

2025-09-23 00:27:51 +08:00
/*!
\file gd32c10x_exmc.c
\brief EXMC driver
\version 2026-01-30, V1.7.0, firmware for GD32C10x
2025-09-23 00:27:51 +08:00
*/
/*
Copyright (c) 2026, GigaDevice Semiconductor Inc.
2025-09-23 00:27:51 +08:00
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 "gd32c10x_exmc.h"
/* EXMC bank0 register reset value */
/** @brief BANK0_SNCTL_RESET 宏定义 */
2025-09-23 00:27:51 +08:00
#define BANK0_SNCTL_RESET ((uint32_t)0x000030DBU)
/** @brief BANK0_SNTCFG_RESET 宏定义 */
2025-09-23 00:27:51 +08:00
#define BANK0_SNTCFG_RESET ((uint32_t)0x0FFFFFFFU)
/** @brief BANK0_SNWTCFG_RESET 宏定义 */
2025-09-23 00:27:51 +08:00
#define BANK0_SNWTCFG_RESET ((uint32_t)0x0FFFFFFFU)
/* EXMC register bit offset */
/** @brief SNCTL_NRMUX_OFFSET 宏定义 */
2025-09-23 00:27:51 +08:00
#define SNCTL_NRMUX_OFFSET ((uint32_t)1U)
/** @brief SNCTL_SBRSTEN_OFFSET 宏定义 */
2025-09-23 00:27:51 +08:00
#define SNCTL_SBRSTEN_OFFSET ((uint32_t)8U)
/** @brief SNCTL_WRAPEN_OFFSET 宏定义 */
2025-09-23 00:27:51 +08:00
#define SNCTL_WRAPEN_OFFSET ((uint32_t)10U)
/** @brief SNCTL_WREN_OFFSET 宏定义 */
2025-09-23 00:27:51 +08:00
#define SNCTL_WREN_OFFSET ((uint32_t)12U)
/** @brief SNCTL_NRWTEN_OFFSET 宏定义 */
2025-09-23 00:27:51 +08:00
#define SNCTL_NRWTEN_OFFSET ((uint32_t)13U)
/** @brief SNCTL_EXMODEN_OFFSET 宏定义 */
2025-09-23 00:27:51 +08:00
#define SNCTL_EXMODEN_OFFSET ((uint32_t)14U)
/** @brief SNCTL_ASYNCWAIT_OFFSET 宏定义 */
2025-09-23 00:27:51 +08:00
#define SNCTL_ASYNCWAIT_OFFSET ((uint32_t)15U)
/** @brief SNTCFG_AHLD_OFFSET 宏定义 */
2025-09-23 00:27:51 +08:00
#define SNTCFG_AHLD_OFFSET ((uint32_t)4U)
/** @brief SNTCFG_DSET_OFFSET 宏定义 */
2025-09-23 00:27:51 +08:00
#define SNTCFG_DSET_OFFSET ((uint32_t)8U)
/** @brief SNTCFG_BUSLAT_OFFSET 宏定义 */
2025-09-23 00:27:51 +08:00
#define SNTCFG_BUSLAT_OFFSET ((uint32_t)16U)
/** @brief SNWTCFG_WAHLD_OFFSET 宏定义 */
2025-09-23 00:27:51 +08:00
#define SNWTCFG_WAHLD_OFFSET ((uint32_t)4U)
/** @brief SNWTCFG_WDSET_OFFSET 宏定义 */
2025-09-23 00:27:51 +08:00
#define SNWTCFG_WDSET_OFFSET ((uint32_t)8U)
/** @brief SNWTCFG_WBUSLAT_OFFSET 宏定义 */
2025-09-23 00:27:51 +08:00
#define SNWTCFG_WBUSLAT_OFFSET ((uint32_t)16U)
/*!
\brief deinitialize EXMC NOR/SRAM bank
\param[in] none
\param[out] none
\retval none
*/
void exmc_norsram_deinit(void)
{
/* reset the registers */
EXMC_SNCTL = BANK0_SNCTL_RESET;
EXMC_SNTCFG = BANK0_SNTCFG_RESET;
EXMC_SNWTCFG = BANK0_SNWTCFG_RESET;
}
/*!
\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->address_data_mux = ENABLE;
exmc_norsram_init_struct->memory_type = EXMC_MEMORY_TYPE_NOR;
exmc_norsram_init_struct->databus_width = EXMC_NOR_DATABUS_WIDTH_16B;
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 initialize EXMC NOR/SRAM bank
\param[in] exmc_norsram_parameter_struct: configure the EXMC NOR/SRAM parameter
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
*/
/**
* @brief exmc_norsram_init 函数
* @param[in] exmc_norsram_init_struct 参数
* @return void
*/
2025-09-23 00:27:51 +08:00
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;
/* clear relative bits */
snctl &= ((uint32_t)~(EXMC_SNCTL_NRMUX | EXMC_SNCTL_NRTP | EXMC_SNCTL_NRW | EXMC_SNCTL_SBRSTEN |
EXMC_SNCTL_NREN | EXMC_SNCTL_NRWTPOL | EXMC_SNCTL_WRAPEN | EXMC_SNCTL_NRWTCFG |
EXMC_SNCTL_WREN | EXMC_SNCTL_NRWTEN | EXMC_SNCTL_EXMODEN | EXMC_SNCTL_ASYNCWAIT |
EXMC_SNCTL_SYNCWR ));
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 ) << SNWTCFG_WAHLD_OFFSET ) & EXMC_SNWTCFG_WAHLD )|
(((exmc_norsram_init_struct->write_timing->asyn_data_setuptime -1U ) << SNWTCFG_WDSET_OFFSET ) & EXMC_SNWTCFG_WDSET )|
(((exmc_norsram_init_struct->write_timing->bus_latency - 1U ) << SNWTCFG_WBUSLAT_OFFSET ) & EXMC_SNWTCFG_WBUSLAT ) |
exmc_norsram_init_struct->write_timing->asyn_access_mode;
}else{
snwtcfg = BANK0_SNWTCFG_RESET;
}
/* configure the registers */
EXMC_SNCTL = snctl;
EXMC_SNTCFG = sntcfg;
EXMC_SNWTCFG = snwtcfg;
}
/*!
\brief enable EXMC NOR/PSRAM bank
\param[in] none
\param[out] none
\retval none
*/
void exmc_norsram_enable(void)
{
EXMC_SNCTL |= (uint32_t)EXMC_SNCTL_NRBKEN;
}
/*!
\brief disable EXMC NOR/PSRAM bank
\param[in] none
\param[out] none
\retval none
*/
void exmc_norsram_disable(void)
{
EXMC_SNCTL &= ~(uint32_t)EXMC_SNCTL_NRBKEN;
}
/*!
\brief configure CRAM page size
\param[in] page_size: CRAM page size
only one parameter can be selected which is shown as below:
\arg EXMC_CRAM_AUTO_SPLIT: the clock is generated only during synchronous access
\arg EXMC_CRAM_PAGE_SIZE_128_BYTES: page size is 128 bytes
\arg EXMC_CRAM_PAGE_SIZE_256_BYTES: page size is 256 bytes
\arg EXMC_CRAM_PAGE_SIZE_512_BYTES: page size is 512 bytes
\arg EXMC_CRAM_PAGE_SIZE_1024_BYTES: page size is 1024 bytes
\param[out] none
\retval none
*/
void exmc_norsram_page_size_config(uint32_t page_size)
{
/* reset the bits */
EXMC_SNCTL &= ~EXMC_SNCTL_CPS;
/* set the CPS bits */
EXMC_SNCTL |= page_size;
}