Initial commit: CCU621_M firmware project with BLE debug link support.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,732 @@
|
||||
/*!
|
||||
\file gd32h7xx_cau.c
|
||||
\brief CAU driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_cau.h"
|
||||
#include "gd32h7xx_rcu.h"
|
||||
|
||||
#define STAT0_AESDES_MASK ((uint32_t)0x00000015U)
|
||||
#define STAT0_TDES_MASK ((uint32_t)0x00000014U)
|
||||
|
||||
/*!
|
||||
\brief reset the CAU peripheral
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cau_deinit(void)
|
||||
{
|
||||
/* enable CAU reset state */
|
||||
rcu_periph_reset_enable(RCU_CAURST);
|
||||
/* release CAU from reset state */
|
||||
rcu_periph_reset_disable(RCU_CAURST);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the CAU encrypt and decrypt parameter struct with the default values
|
||||
\param[in] none
|
||||
\param[out] cau_parameter:
|
||||
alg_dir: algorithm directory
|
||||
CAU_ENCRYPT, CAU_DECRYPT
|
||||
key: key
|
||||
key_size: key size in bytes
|
||||
iv: initialization vector
|
||||
iv_size: iv size in bytes
|
||||
input: input data
|
||||
in_length: input data length in bytes
|
||||
aad: additional authentication data
|
||||
aad_size: header size
|
||||
\retval none
|
||||
*/
|
||||
void cau_struct_para_init(cau_parameter_struct *cau_parameter)
|
||||
{
|
||||
/* set the CAU encrypt and decrypt parameters struct with the default values */
|
||||
cau_parameter->alg_dir = CAU_ENCRYPT;
|
||||
cau_parameter->key = 0U;
|
||||
cau_parameter->key_size = 0U;
|
||||
cau_parameter->iv = 0U;
|
||||
cau_parameter->iv_size = 0U;
|
||||
cau_parameter->input = 0U;
|
||||
cau_parameter->in_length = 0U;
|
||||
cau_parameter->aad = 0U;
|
||||
cau_parameter->aad_size = 0U;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the key parameter structure with the default values
|
||||
\param[in] none
|
||||
\param[out] key_initpara:
|
||||
key_0_high: key 0 high
|
||||
key_0_low: key 0 low
|
||||
key_1_high: key 1 high
|
||||
key_1_low: key 1 low
|
||||
key_2_high: key 2 high
|
||||
key_2_low: key 2 low
|
||||
key_3_high: key 3 high
|
||||
key_3_low: key 3 low
|
||||
\retval none
|
||||
*/
|
||||
void cau_key_struct_para_init(cau_key_parameter_struct *key_initpara)
|
||||
{
|
||||
/* set the key parameters struct with the default values */
|
||||
key_initpara->key_0_high = 0U;
|
||||
key_initpara->key_0_low = 0U;
|
||||
key_initpara->key_1_high = 0U;
|
||||
key_initpara->key_1_low = 0U;
|
||||
key_initpara->key_2_high = 0U;
|
||||
key_initpara->key_2_low = 0U;
|
||||
key_initpara->key_3_high = 0U;
|
||||
key_initpara->key_3_low = 0U;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the vectors parameter struct with the default values
|
||||
\param[in] none
|
||||
\param[out] iv_initpara:
|
||||
iv_0_high: init vector 0 high
|
||||
iv_0_low: init vector 0 low
|
||||
iv_1_high: init vector 1 high
|
||||
iv_1_low: init vector 1 low
|
||||
\retval none
|
||||
*/
|
||||
void cau_iv_struct_para_init(cau_iv_parameter_struct *iv_initpara)
|
||||
{
|
||||
/* set the vectors parameters struct with the default values */
|
||||
iv_initpara->iv_0_high = 0U;
|
||||
iv_initpara->iv_0_low = 0U;
|
||||
iv_initpara->iv_1_high = 0U;
|
||||
iv_initpara->iv_1_low = 0U;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the context parameter struct with the default values
|
||||
\param[in] none
|
||||
\param[out] cau_context:
|
||||
ctl_config: current configuration
|
||||
iv_0_high: init vector 0 high
|
||||
iv_0_low: init vector 0 low
|
||||
iv_1_high: init vector 1 high
|
||||
iv_1_low: init vector 1 low
|
||||
key_0_high: key 0 high
|
||||
key_0_low: key 0 low
|
||||
key_1_high: key 1 high
|
||||
key_1_low: key 1 low
|
||||
key_2_high: key 2 high
|
||||
key_2_low: key 2 low
|
||||
key_3_high: key 3 high
|
||||
key_3_low: key 3 low
|
||||
gcmccmctxs[8]: GCM or CCM mode context switch
|
||||
gcmctxs[8]: GCM mode context switch
|
||||
\retval none
|
||||
*/
|
||||
void cau_context_struct_para_init(cau_context_parameter_struct *cau_context)
|
||||
{
|
||||
cau_context->ctl_config = 0U;
|
||||
|
||||
/* set the vectors parameters with the default values */
|
||||
cau_context->iv_0_high = 0U;
|
||||
cau_context->iv_0_low = 0U;
|
||||
cau_context->iv_1_high = 0U;
|
||||
cau_context->iv_1_low = 0U;
|
||||
|
||||
/* set the key parameters with the default values */
|
||||
cau_context->key_0_high = 0U;
|
||||
cau_context->key_0_low = 0U;
|
||||
cau_context->key_1_high = 0U;
|
||||
cau_context->key_1_low = 0U;
|
||||
cau_context->key_2_high = 0U;
|
||||
cau_context->key_2_low = 0U;
|
||||
cau_context->key_3_high = 0U;
|
||||
cau_context->key_3_low = 0U;
|
||||
|
||||
/* set the context switch with the default values */
|
||||
cau_context->gcmccmctxs[0] = 0U;
|
||||
cau_context->gcmccmctxs[1] = 0U;
|
||||
cau_context->gcmccmctxs[2] = 0U;
|
||||
cau_context->gcmccmctxs[3] = 0U;
|
||||
cau_context->gcmccmctxs[4] = 0U;
|
||||
cau_context->gcmccmctxs[5] = 0U;
|
||||
cau_context->gcmccmctxs[6] = 0U;
|
||||
cau_context->gcmccmctxs[7] = 0U;
|
||||
|
||||
cau_context->gcmctxs[0] = 0U;
|
||||
cau_context->gcmctxs[1] = 0U;
|
||||
cau_context->gcmctxs[2] = 0U;
|
||||
cau_context->gcmctxs[3] = 0U;
|
||||
cau_context->gcmctxs[4] = 0U;
|
||||
cau_context->gcmctxs[5] = 0U;
|
||||
cau_context->gcmctxs[6] = 0U;
|
||||
cau_context->gcmctxs[7] = 0U;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the CAU peripheral
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cau_enable(void)
|
||||
{
|
||||
/* enable the CAU processor */
|
||||
CAU_CTL |= CAU_CTL_CAUEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the CAU peripheral
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cau_disable(void)
|
||||
{
|
||||
/* disable the CAU processor */
|
||||
CAU_CTL &= ~CAU_CTL_CAUEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the CAU DMA interface
|
||||
\param[in] dma_req: specify the CAU DMA transfer request to be enabled
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg CAU_DMA_INFIFO: DMA for incoming(Rx) data transfer
|
||||
\arg CAU_DMA_OUTFIFO: DMA for outgoing(Tx) data transfer
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cau_dma_enable(uint32_t dma_req)
|
||||
{
|
||||
/* enable the selected CAU DMA request */
|
||||
CAU_DMAEN |= dma_req;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the CAU DMA interface
|
||||
\param[in] dma_req: specify the CAU DMA transfer request to be disabled
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg CAU_DMA_INFIFO: DMA for incoming(Rx) data transfer
|
||||
\arg CAU_DMA_OUTFIFO: DMA for outgoing(Tx) data transfer
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cau_dma_disable(uint32_t dma_req)
|
||||
{
|
||||
/* disable the selected CAU DMA request */
|
||||
CAU_DMAEN &= ~(dma_req);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the CAU peripheral
|
||||
\param[in] alg_dir: algorithm direction
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CAU_ENCRYPT: encrypt
|
||||
\arg CAU_DECRYPT: decrypt
|
||||
\param[in] algo_mode: algorithm mode selection
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CAU_MODE_TDES_ECB: TDES-ECB (3DES Electronic codebook)
|
||||
\arg CAU_MODE_TDES_CBC: TDES-CBC (3DES Cipher block chaining)
|
||||
\arg CAU_MODE_DES_ECB: DES-ECB (simple DES Electronic codebook)
|
||||
\arg CAU_MODE_DES_CBC: DES-CBC (simple DES Cipher block chaining)
|
||||
\arg CAU_MODE_AES_ECB: AES-ECB (AES Electronic codebook)
|
||||
\arg CAU_MODE_AES_CBC: AES-CBC (AES Cipher block chaining)
|
||||
\arg CAU_MODE_AES_CTR: AES-CTR (AES counter mode)
|
||||
\arg CAU_MODE_AES_KEY: AES decryption key preparation mode
|
||||
\arg CAU_MODE_AES_GCM: AES-GCM (AES Galois/counter mode)
|
||||
\arg CAU_MODE_AES_CCM: AES-CCM (AES combined cipher machine mode)
|
||||
\arg CAU_MODE_AES_CFB: AES-CFB (cipher feedback mode)
|
||||
\arg CAU_MODE_AES_OFB: AES-OFB (output feedback mode)
|
||||
\param[in] swapping: data swapping selection
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CAU_SWAPPING_32BIT: no swapping
|
||||
\arg CAU_SWAPPING_16BIT: half-word swapping
|
||||
\arg CAU_SWAPPING_8BIT: bytes swapping
|
||||
\arg CAU_SWAPPING_1BIT: bit swapping
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cau_init(uint32_t alg_dir, uint32_t algo_mode, uint32_t swapping)
|
||||
{
|
||||
/* select algorithm mode */
|
||||
CAU_CTL &= ~CAU_CTL_ALGM;
|
||||
CAU_CTL |= algo_mode;
|
||||
|
||||
/* select data swapping */
|
||||
CAU_CTL &= ~CAU_CTL_DATAM;
|
||||
CAU_CTL |= swapping;
|
||||
|
||||
/* select algorithm direction */
|
||||
CAU_CTL &= ~CAU_CTL_CAUDIR;
|
||||
CAU_CTL |= alg_dir;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure key selection
|
||||
\param[in] key_selection: key source selection when aes mode
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CAU_KEY: use the key from CAU register
|
||||
\arg CAU_EFUSE_KEY: use the key from EFUSE
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cau_aes_key_select(uint32_t key_selection)
|
||||
{
|
||||
CAU_CTL &= ~CAU_CTL_KEY_SEL;
|
||||
CAU_CTL |= key_selection;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure key size if use AES algorithm
|
||||
\param[in] key_size: key length selection when aes mode
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CAU_KEYSIZE_128BIT: 128 bit key length
|
||||
\arg CAU_KEYSIZE_192BIT: 192 bit key length
|
||||
\arg CAU_KEYSIZE_256BIT: 256 bit key length
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cau_aes_keysize_config(uint32_t key_size)
|
||||
{
|
||||
CAU_CTL &= ~CAU_CTL_KEYM;
|
||||
CAU_CTL |= key_size;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the key parameters
|
||||
\param[in] key_initpara: key init parameter struct
|
||||
key_0_high: key 0 high
|
||||
key_0_low: key 0 low
|
||||
key_1_high: key 1 high
|
||||
key_1_low: key 1 low
|
||||
key_2_high: key 2 high
|
||||
key_2_low: key 2 low
|
||||
key_3_high: key 3 high
|
||||
key_3_low: key 3 low
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cau_key_init(cau_key_parameter_struct *key_initpara)
|
||||
{
|
||||
CAU_KEY0H = key_initpara->key_0_high;
|
||||
CAU_KEY0L = key_initpara->key_0_low;
|
||||
CAU_KEY1H = key_initpara->key_1_high;
|
||||
CAU_KEY1L = key_initpara->key_1_low;
|
||||
CAU_KEY2H = key_initpara->key_2_high;
|
||||
CAU_KEY2L = key_initpara->key_2_low;
|
||||
CAU_KEY3H = key_initpara->key_3_high;
|
||||
CAU_KEY3L = key_initpara->key_3_low;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the vectors parameters
|
||||
\param[in] iv_initpara: vectors init parameter struct
|
||||
iv_0_high: init vector 0 high
|
||||
iv_0_low: init vector 0 low
|
||||
iv_1_high: init vector 1 high
|
||||
iv_1_low: init vector 1 low
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cau_iv_init(cau_iv_parameter_struct *iv_initpara)
|
||||
{
|
||||
CAU_IV0H = iv_initpara->iv_0_high;
|
||||
CAU_IV0L = iv_initpara->iv_0_low;
|
||||
CAU_IV1H = iv_initpara->iv_1_high;
|
||||
CAU_IV1L = iv_initpara->iv_1_low;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure phase
|
||||
\param[in] phase: gcm or ccm phase
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CAU_PREPARE_PHASE: prepare phase
|
||||
\arg CAU_AAD_PHASE: AAD phase
|
||||
\arg CAU_ENCRYPT_DECRYPT_PHASE: encryption/decryption phase
|
||||
\arg CAU_TAG_PHASE: tag phase
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cau_phase_config(uint32_t phase)
|
||||
{
|
||||
uint32_t temp;
|
||||
/* Get the CTL register */
|
||||
temp = CAU_CTL;
|
||||
/* Reset the phase configuration bits */
|
||||
temp &= ~CAU_CTL_GCM_CCMPH;
|
||||
/* Set the selected phase */
|
||||
temp |= phase;
|
||||
/* Set the CTL register */
|
||||
CAU_CTL = temp;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief flush the IN and OUT FIFOs
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cau_fifo_flush(void)
|
||||
{
|
||||
/* reset the read and write pointers of the FIFOs */
|
||||
CAU_CTL |= CAU_CTL_FFLUSH;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief return whether CAU peripheral is enabled or disabled
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval ControlStatus: ENABLE or DISABLE
|
||||
*/
|
||||
ControlStatus cau_enable_state_get(void)
|
||||
{
|
||||
ControlStatus ret = DISABLE;
|
||||
if(RESET != (CAU_CTL & CAU_CTL_CAUEN)) {
|
||||
ret = ENABLE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief write data to the IN FIFO
|
||||
\param[in] data: data to write (0 - 0xFFFFFFFF)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cau_data_write(uint32_t data)
|
||||
{
|
||||
CAU_DI = data;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief return the last data entered into the output FIFO
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval last data entered into the output FIFO
|
||||
*/
|
||||
uint32_t cau_data_read(void)
|
||||
{
|
||||
return CAU_DO;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief save context before context switching
|
||||
\param[in] key_initpara: key init parameter struct
|
||||
key_0_high: key 0 high
|
||||
key_0_low: key 0 low
|
||||
key_1_high: key 1 high
|
||||
key_1_low: key 1 low
|
||||
key_2_high: key 2 high
|
||||
key_2_low: key 2 low
|
||||
key_3_high: key 3 high
|
||||
key_3_low: key 3 low
|
||||
\param[out] cau_context:
|
||||
ctl_config: current configuration
|
||||
iv_0_high: init vector 0 high
|
||||
iv_0_low: init vector 0 low
|
||||
iv_1_high: init vector 1 high
|
||||
iv_1_low: init vector 1 low
|
||||
key_0_high: key 0 high
|
||||
key_0_low: key 0 low
|
||||
key_1_high: key 1 high
|
||||
key_1_low: key 1 low
|
||||
key_2_high: key 2 high
|
||||
key_2_low: key 2 low
|
||||
key_3_high: key 3 high
|
||||
key_3_low: key 3 low
|
||||
gcmccmctxs[8]: GCM or CCM mode context switch
|
||||
gcmctxs[8]: GCM mode context switch
|
||||
\retval none
|
||||
*/
|
||||
void cau_context_save(cau_context_parameter_struct *cau_context, cau_key_parameter_struct *key_initpara)
|
||||
{
|
||||
uint32_t checkmask = 0U;
|
||||
uint32_t checkbits = 0U;
|
||||
uint32_t algm_reg = 0U;
|
||||
|
||||
/* stop DMA transfers on the IN FIFO by clearing the DMAIEN bit in the CAU_DMAEN */
|
||||
CAU_DMAEN &= ~CAU_DMA_INFIFO;
|
||||
|
||||
algm_reg = CAU_CTL & CAU_CTL_ALGM;
|
||||
/* AES or DES */
|
||||
if((uint32_t)0 != (algm_reg & (~CAU_MODE_TDES_CBC))) {
|
||||
/* wait until both the IN and OUT FIFOs are empty (IEM=1 and ONE=0 in the CAU_STAT0 register) and BUSY=0 */
|
||||
checkbits = CAU_STAT0_IEM;
|
||||
checkmask = STAT0_AESDES_MASK;
|
||||
/* TDES */
|
||||
} else {
|
||||
/* wait until OUT FIFO is empty (ONE=0 in the CAU_STAT0 register) and BUSY=0 */
|
||||
checkbits = 0U;
|
||||
checkmask = STAT0_TDES_MASK;
|
||||
}
|
||||
|
||||
while((CAU_STAT0 & checkmask) != checkbits) {
|
||||
}
|
||||
|
||||
/* stop DMA transfers on the OUT FIFO by clear CAU_DMAEN_DMAOEN=0 */
|
||||
CAU_DMAEN &= ~CAU_DMAEN_DMAOEN;
|
||||
/* disable CAU */
|
||||
CAU_CTL &= ~CAU_CTL_CAUEN;
|
||||
|
||||
/* save the current configuration (bit 19, bit[17:16] and bit[9:2] in the CAU_CTL register) */
|
||||
cau_context->ctl_config = CAU_CTL & (CAU_CTL_GCM_CCMPH |
|
||||
CAU_CTL_KEYM |
|
||||
CAU_CTL_DATAM |
|
||||
CAU_CTL_ALGM |
|
||||
CAU_CTL_CAUDIR |
|
||||
CAU_CTL_NBPILB);
|
||||
|
||||
/* save the key value */
|
||||
cau_context->key_0_high = key_initpara->key_0_high;
|
||||
cau_context->key_0_low = key_initpara->key_0_low;
|
||||
cau_context->key_1_high = key_initpara->key_1_high;
|
||||
cau_context->key_1_low = key_initpara->key_1_low;
|
||||
cau_context->key_2_high = key_initpara->key_2_high;
|
||||
cau_context->key_2_low = key_initpara->key_2_low;
|
||||
cau_context->key_3_high = key_initpara->key_3_high;
|
||||
cau_context->key_3_low = key_initpara->key_3_low;
|
||||
|
||||
if((CAU_MODE_TDES_ECB != algm_reg) && (CAU_MODE_DES_ECB != algm_reg) && (CAU_MODE_AES_ECB != algm_reg)) {
|
||||
/* if not in ECB mode, save the initialization vectors */
|
||||
cau_context->iv_0_high = CAU_IV0H;
|
||||
cau_context->iv_0_low = CAU_IV0L;
|
||||
cau_context->iv_1_high = CAU_IV1H;
|
||||
cau_context->iv_1_low = CAU_IV1L;
|
||||
}
|
||||
|
||||
/* if in GCM/CCM mode, save the context switch registers */
|
||||
if((CAU_MODE_AES_GCM == algm_reg) || (CAU_MODE_AES_CCM == algm_reg)) {
|
||||
cau_context->gcmccmctxs[0U] = CAU_GCMCCMCTXSx(0U);
|
||||
cau_context->gcmccmctxs[1U] = CAU_GCMCCMCTXSx(1U);
|
||||
cau_context->gcmccmctxs[2U] = CAU_GCMCCMCTXSx(2U);
|
||||
cau_context->gcmccmctxs[3U] = CAU_GCMCCMCTXSx(3U);
|
||||
cau_context->gcmccmctxs[4U] = CAU_GCMCCMCTXSx(4U);
|
||||
cau_context->gcmccmctxs[5U] = CAU_GCMCCMCTXSx(5U);
|
||||
cau_context->gcmccmctxs[6U] = CAU_GCMCCMCTXSx(6U);
|
||||
cau_context->gcmccmctxs[7U] = CAU_GCMCCMCTXSx(7U);
|
||||
}
|
||||
|
||||
/* if in GCM mode, save the context switch registers */
|
||||
if(CAU_MODE_AES_GCM == algm_reg) {
|
||||
cau_context->gcmctxs[0U] = CAU_GCMCTXSx(0U);
|
||||
cau_context->gcmctxs[1U] = CAU_GCMCTXSx(1U);
|
||||
cau_context->gcmctxs[2U] = CAU_GCMCTXSx(2U);
|
||||
cau_context->gcmctxs[3U] = CAU_GCMCTXSx(3U);
|
||||
cau_context->gcmctxs[4U] = CAU_GCMCTXSx(4U);
|
||||
cau_context->gcmctxs[5U] = CAU_GCMCTXSx(5U);
|
||||
cau_context->gcmctxs[6U] = CAU_GCMCTXSx(6U);
|
||||
cau_context->gcmctxs[7U] = CAU_GCMCTXSx(7U);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief restore context after context switching
|
||||
\param[in] cau_context:
|
||||
ctl_config: current configuration
|
||||
iv_0_high: init vector 0 high
|
||||
iv_0_low: init vector 0 low
|
||||
iv_1_high: init vector 1 high
|
||||
iv_1_low: init vector 1 low
|
||||
key_0_high: key 0 high
|
||||
key_0_low: key 0 low
|
||||
key_1_high: key 1 high
|
||||
key_1_low: key 1 low
|
||||
key_2_high: key 2 high
|
||||
key_2_low: key 2 low
|
||||
key_3_high: key 3 high
|
||||
key_3_low: key 3 low
|
||||
gcmccmctxs[8]: GCM or CCM mode context switch
|
||||
gcmctxs[8]: GCM mode context switch
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cau_context_restore(cau_context_parameter_struct *cau_context)
|
||||
{
|
||||
uint32_t algm_reg, aes_decrypt;
|
||||
|
||||
/* configure the processor with the saved configuration */
|
||||
CAU_CTL = cau_context->ctl_config;
|
||||
|
||||
algm_reg = CAU_CTL & CAU_CTL_ALGM;
|
||||
|
||||
/* restore the key value */
|
||||
CAU_KEY0H = cau_context->key_0_high;
|
||||
CAU_KEY0L = cau_context->key_0_low;
|
||||
CAU_KEY1H = cau_context->key_1_high;
|
||||
CAU_KEY1L = cau_context->key_1_low;
|
||||
CAU_KEY2H = cau_context->key_2_high;
|
||||
CAU_KEY2L = cau_context->key_2_low;
|
||||
CAU_KEY3H = cau_context->key_3_high;
|
||||
CAU_KEY3L = cau_context->key_3_low;
|
||||
|
||||
if((CAU_MODE_TDES_ECB != algm_reg) && (CAU_MODE_DES_ECB != algm_reg) && (CAU_MODE_AES_ECB != algm_reg)) {
|
||||
/* restore the initialization vectors */
|
||||
CAU_IV0H = cau_context->iv_0_high;
|
||||
CAU_IV0L = cau_context->iv_0_low;
|
||||
CAU_IV1H = cau_context->iv_1_high;
|
||||
CAU_IV1L = cau_context->iv_1_low;
|
||||
}
|
||||
|
||||
/* if in GCM/CCM mode, restore the context switch registers */
|
||||
if((CAU_MODE_AES_GCM == algm_reg) || (CAU_MODE_AES_CCM == algm_reg)) {
|
||||
CAU_GCMCCMCTXSx(0U) = cau_context->gcmccmctxs[0U];
|
||||
CAU_GCMCCMCTXSx(1U) = cau_context->gcmccmctxs[1U];
|
||||
CAU_GCMCCMCTXSx(2U) = cau_context->gcmccmctxs[2U];
|
||||
CAU_GCMCCMCTXSx(3U) = cau_context->gcmccmctxs[3U];
|
||||
CAU_GCMCCMCTXSx(4U) = cau_context->gcmccmctxs[4U];
|
||||
CAU_GCMCCMCTXSx(5U) = cau_context->gcmccmctxs[5U];
|
||||
CAU_GCMCCMCTXSx(6U) = cau_context->gcmccmctxs[6U];
|
||||
CAU_GCMCCMCTXSx(7U) = cau_context->gcmccmctxs[7U];
|
||||
}
|
||||
|
||||
/* if in GCM mode, restore the context switch registers */
|
||||
if(CAU_MODE_AES_GCM == algm_reg) {
|
||||
CAU_GCMCTXSx(0U) = cau_context->gcmctxs[0U];
|
||||
CAU_GCMCTXSx(1U) = cau_context->gcmctxs[1U];
|
||||
CAU_GCMCTXSx(2U) = cau_context->gcmctxs[2U];
|
||||
CAU_GCMCTXSx(3U) = cau_context->gcmctxs[3U];
|
||||
CAU_GCMCTXSx(4U) = cau_context->gcmctxs[4U];
|
||||
CAU_GCMCTXSx(5U) = cau_context->gcmctxs[5U];
|
||||
CAU_GCMCTXSx(6U) = cau_context->gcmctxs[6U];
|
||||
CAU_GCMCTXSx(7U) = cau_context->gcmctxs[7U];
|
||||
}
|
||||
|
||||
/* if it is AES ECB/CBC decryption, then first prepare key */
|
||||
aes_decrypt = CAU_CTL & (CAU_CTL_ALGM | CAU_CTL_CAUDIR);
|
||||
if(((CAU_MODE_AES_ECB | CAU_DECRYPT) == aes_decrypt) || ((CAU_MODE_AES_CBC | CAU_DECRYPT) == aes_decrypt)) {
|
||||
uint32_t alg_dir, algo_mode, swapping;
|
||||
|
||||
/* flush IN/OUT FIFOs */
|
||||
cau_fifo_flush();
|
||||
/* parameters for key preparation for AES decryption */
|
||||
alg_dir = CAU_DECRYPT;
|
||||
algo_mode = CAU_MODE_AES_KEY;
|
||||
swapping = CAU_SWAPPING_32BIT;
|
||||
cau_init(alg_dir, algo_mode, swapping);
|
||||
|
||||
/* enable CAU */
|
||||
cau_enable();
|
||||
|
||||
/* wait until BUSY=0 */
|
||||
while((uint32_t)0U != cau_flag_get(CAU_FLAG_BUSY)) {
|
||||
}
|
||||
|
||||
/* parameters for decryption */
|
||||
CAU_CTL = cau_context->ctl_config;
|
||||
}
|
||||
|
||||
/* enable CAU */
|
||||
cau_enable();
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the CAU flag status
|
||||
\param[in] flag: CAU flag status
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CAU_FLAG_INFIFO_EMPTY: input FIFO empty
|
||||
\arg CAU_FLAG_INFIFO_NO_FULL: input FIFO is not full
|
||||
\arg CAU_FLAG_OUTFIFO_NO_EMPTY: output FIFO not empty
|
||||
\arg CAU_FLAG_OUTFIFO_FULL: output FIFO is full
|
||||
\arg CAU_FLAG_BUSY: the CAU core is busy
|
||||
\arg CAU_FLAG_INFIFO: input FIFO flag status
|
||||
\arg CAU_FLAG_OUTFIFO: output FIFO flag status
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus cau_flag_get(uint32_t flag)
|
||||
{
|
||||
uint32_t reg = 0U;
|
||||
FlagStatus ret_flag = RESET;
|
||||
|
||||
/* check if the flag is in CAU_STAT1 register */
|
||||
if(1U == (flag >> 31U)) {
|
||||
reg = CAU_STAT1;
|
||||
} else {
|
||||
/* the flag is in CAU_STAT0 register */
|
||||
reg = CAU_STAT0;
|
||||
}
|
||||
|
||||
/* check the status of the specified CAU flag */
|
||||
if(0U != (reg & flag)) {
|
||||
ret_flag = SET;
|
||||
}
|
||||
|
||||
return ret_flag;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the CAU interrupts
|
||||
\param[in] interrupt: specify the CAU interrupt source to be enabled
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg CAU_INT_INFIFO: input FIFO interrupt
|
||||
\arg CAU_INT_OUTFIFO: output FIFO interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cau_interrupt_enable(uint32_t interrupt)
|
||||
{
|
||||
/* enable the selected CAU interrupt */
|
||||
CAU_INTEN |= interrupt;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the CAU interrupts
|
||||
\param[in] interrupt: specify the CAU interrupt source to be disabled
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg CAU_INT_INFIFO: input FIFO interrupt
|
||||
\arg CAU_INT_OUTFIFO: output FIFO interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cau_interrupt_disable(uint32_t interrupt)
|
||||
{
|
||||
/* disable the selected CAU interrupt */
|
||||
CAU_INTEN &= ~(interrupt);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the interrupt flag
|
||||
\param[in] int_flag: CAU interrupt flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CAU_INT_FLAG_INFIFO: input FIFO interrupt
|
||||
\arg CAU_INT_FLAG_OUTFIFO: output FIFO interrupt
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus cau_interrupt_flag_get(uint32_t int_flag)
|
||||
{
|
||||
FlagStatus flag = RESET;
|
||||
|
||||
/* check the status of the specified CAU interrupt */
|
||||
if(RESET != (CAU_INTF & int_flag)) {
|
||||
flag = SET;
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
@@ -0,0 +1,917 @@
|
||||
/*!
|
||||
\file gd32h7xx_cau_aes.c
|
||||
\brief CAU AES driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_cau.h"
|
||||
#include <string.h>
|
||||
|
||||
#define AESBSY_TIMEOUT ((uint32_t)0x00010000U)
|
||||
#define BLOCK_B0_MASK ((uint8_t)0x07U)
|
||||
#define BLOCK_DATA_SIZE ((uint32_t)0x00000010U)
|
||||
#define MIN_CCM_IV_SIZE ((uint32_t)0x00000007U)
|
||||
#define MAX_CCM_IV_SIZE ((uint32_t)0x0000000DU)
|
||||
|
||||
/* configure AES key structure parameter */
|
||||
static void cau_aes_key_config(uint8_t *key, uint32_t keysize, cau_key_parameter_struct *cau_key_initpara);
|
||||
/* fill data into data input register */
|
||||
static ErrStatus cau_fill_data(uint8_t *input, uint32_t in_length);
|
||||
/* AES calculate process */
|
||||
static ErrStatus cau_aes_calculate(uint8_t *input, uint32_t in_length, uint8_t *output);
|
||||
|
||||
/*!
|
||||
\brief encrypt and decrypt using AES in ECB mode
|
||||
\param[in] cau_parameter: pointer to the input structure
|
||||
alg_dir: algorithm directory
|
||||
CAU_ENCRYPT, CAU_DECRYPT
|
||||
key: key
|
||||
key_size: key size in bits, must be either 128, 192 or 256
|
||||
input: input data
|
||||
in_length: input data length in bytes, must be a multiple of 16 bytes
|
||||
\param[out] output: pointer to the returned buffer
|
||||
\retval ErrStatus: SUCCESS or ERROR
|
||||
*/
|
||||
ErrStatus cau_aes_ecb(cau_parameter_struct *cau_parameter, uint8_t *output)
|
||||
{
|
||||
ErrStatus ret = ERROR;
|
||||
cau_key_parameter_struct key_initpara;
|
||||
__IO uint32_t counter = 0U;
|
||||
uint32_t busystatus = 0U;
|
||||
|
||||
/* key structure initialization */
|
||||
cau_key_struct_para_init(&key_initpara);
|
||||
/* AES key structure parameter config */
|
||||
cau_aes_key_config(cau_parameter->key, cau_parameter->key_size, &key_initpara);
|
||||
/* key initialization */
|
||||
cau_key_init(&key_initpara);
|
||||
|
||||
/* AES decryption */
|
||||
if(CAU_DECRYPT == cau_parameter->alg_dir) {
|
||||
/* flush the IN and OUT FIFOs */
|
||||
cau_fifo_flush();
|
||||
/* initialize the CAU peripheral */
|
||||
cau_init(CAU_DECRYPT, CAU_MODE_AES_KEY, CAU_SWAPPING_32BIT);
|
||||
|
||||
/* enable the CAU peripheral */
|
||||
cau_enable();
|
||||
|
||||
/* wait until the busy flag is RESET */
|
||||
do {
|
||||
busystatus = cau_flag_get(CAU_FLAG_BUSY);
|
||||
counter++;
|
||||
} while((AESBSY_TIMEOUT != counter) && (RESET != busystatus));
|
||||
|
||||
if(RESET != busystatus) {
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* initialize the CAU peripheral */
|
||||
cau_init(cau_parameter->alg_dir, CAU_MODE_AES_ECB, CAU_SWAPPING_8BIT);
|
||||
|
||||
/* flush the IN and OUT FIFOs */
|
||||
cau_fifo_flush();
|
||||
|
||||
/* enable the CAU peripheral */
|
||||
cau_enable();
|
||||
/* AES calculate process */
|
||||
ret = cau_aes_calculate(cau_parameter->input, cau_parameter->in_length, output);
|
||||
/* disable the CAU peripheral */
|
||||
cau_disable();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief encrypt and decrypt using AES in CBC mode
|
||||
\param[in] cau_parameter: pointer to the input structure
|
||||
alg_dir: algorithm directory
|
||||
CAU_ENCRYPT, CAU_DECRYPT
|
||||
key: key
|
||||
key_size: key size in bits, must be either 128, 192 or 256
|
||||
iv: initialization vector, 16 bytes
|
||||
input: input data
|
||||
in_length: input data length in bytes, must be a multiple of 16 bytes
|
||||
\param[out] output: pointer to the returned buffer
|
||||
\retval ErrStatus: SUCCESS or ERROR
|
||||
*/
|
||||
ErrStatus cau_aes_cbc(cau_parameter_struct *cau_parameter, uint8_t *output)
|
||||
{
|
||||
ErrStatus ret = ERROR;
|
||||
cau_key_parameter_struct key_initpara;
|
||||
cau_iv_parameter_struct iv_initpara;
|
||||
__IO uint32_t counter = 0U;
|
||||
uint32_t busystatus = 0U;
|
||||
|
||||
uint32_t ivaddr = (uint32_t)cau_parameter->iv;
|
||||
|
||||
/* key structure initialization */
|
||||
cau_key_struct_para_init(&key_initpara);
|
||||
/* AES key structure parameter config */
|
||||
cau_aes_key_config(cau_parameter->key, cau_parameter->key_size, &key_initpara);
|
||||
/* key initialization */
|
||||
cau_key_init(&key_initpara);
|
||||
|
||||
/* AES decryption */
|
||||
if(CAU_DECRYPT == cau_parameter->alg_dir) {
|
||||
/* flush the IN and OUT FIFOs */
|
||||
cau_fifo_flush();
|
||||
/* initialize the CAU peripheral */
|
||||
cau_init(CAU_DECRYPT, CAU_MODE_AES_KEY, CAU_SWAPPING_32BIT);
|
||||
|
||||
/* enable the CAU peripheral */
|
||||
cau_enable();
|
||||
|
||||
/* wait until the busy flag is RESET */
|
||||
do {
|
||||
busystatus = cau_flag_get(CAU_FLAG_BUSY);
|
||||
counter++;
|
||||
} while((AESBSY_TIMEOUT != counter) && (RESET != busystatus));
|
||||
|
||||
if(RESET != busystatus) {
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* initialize the CAU peripheral */
|
||||
cau_init(cau_parameter->alg_dir, CAU_MODE_AES_CBC, CAU_SWAPPING_8BIT);
|
||||
|
||||
/* vectors initialization */
|
||||
iv_initpara.iv_0_high = __REV(*(uint32_t *)(ivaddr));
|
||||
ivaddr += 4U;
|
||||
iv_initpara.iv_0_low = __REV(*(uint32_t *)(ivaddr));
|
||||
ivaddr += 4U;
|
||||
iv_initpara.iv_1_high = __REV(*(uint32_t *)(ivaddr));
|
||||
ivaddr += 4U;
|
||||
iv_initpara.iv_1_low = __REV(*(uint32_t *)(ivaddr));
|
||||
cau_iv_init(&iv_initpara);
|
||||
|
||||
/* flush the IN and OUT FIFOs */
|
||||
cau_fifo_flush();
|
||||
|
||||
/* enable the CAU peripheral */
|
||||
cau_enable();
|
||||
/* AES calculate process */
|
||||
ret = cau_aes_calculate(cau_parameter->input, cau_parameter->in_length, output);
|
||||
/* disable the CAU peripheral */
|
||||
cau_disable();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief encrypt and decrypt using AES in CTR mode
|
||||
\param[in] cau_parameter: pointer to the input structure
|
||||
alg_dir: algorithm directory
|
||||
CAU_ENCRYPT, CAU_DECRYPT
|
||||
key: key
|
||||
key_size: key size in bits, must be either 128, 192 or 256
|
||||
iv: initialization vector, 16 bytes
|
||||
input: input data
|
||||
in_length: input data length in bytes, must be a multiple of 16 bytes
|
||||
\param[out] output: pointer to the returned buffer
|
||||
\retval ErrStatus: SUCCESS or ERROR
|
||||
*/
|
||||
ErrStatus cau_aes_ctr(cau_parameter_struct *cau_parameter, uint8_t *output)
|
||||
{
|
||||
ErrStatus ret = ERROR;
|
||||
cau_key_parameter_struct key_initpara;
|
||||
cau_iv_parameter_struct iv_initpara;
|
||||
uint32_t ivaddr = (uint32_t)cau_parameter->iv;
|
||||
|
||||
/* key structure initialization */
|
||||
cau_key_struct_para_init(&key_initpara);
|
||||
/* initialize the CAU peripheral */
|
||||
cau_init(cau_parameter->alg_dir, CAU_MODE_AES_CTR, CAU_SWAPPING_8BIT);
|
||||
|
||||
/* AES key structure parameter config */
|
||||
cau_aes_key_config(cau_parameter->key, cau_parameter->key_size, &key_initpara);
|
||||
/* key initialization */
|
||||
cau_key_init(&key_initpara);
|
||||
|
||||
/* vectors initialization */
|
||||
iv_initpara.iv_0_high = __REV(*(uint32_t *)(ivaddr));
|
||||
ivaddr += 4U;
|
||||
iv_initpara.iv_0_low = __REV(*(uint32_t *)(ivaddr));
|
||||
ivaddr += 4U;
|
||||
iv_initpara.iv_1_high = __REV(*(uint32_t *)(ivaddr));
|
||||
ivaddr += 4U;
|
||||
iv_initpara.iv_1_low = __REV(*(uint32_t *)(ivaddr));
|
||||
cau_iv_init(&iv_initpara);
|
||||
|
||||
/* flush the IN and OUT FIFOs */
|
||||
cau_fifo_flush();
|
||||
|
||||
/* enable the CAU peripheral */
|
||||
cau_enable();
|
||||
/* AES calculate process */
|
||||
ret = cau_aes_calculate(cau_parameter->input, cau_parameter->in_length, output);
|
||||
/* disable the CAU peripheral */
|
||||
cau_disable();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief encrypt and decrypt using AES in CFB mode
|
||||
\param[in] cau_parameter: pointer to the input structure
|
||||
alg_dir: algorithm directory
|
||||
CAU_ENCRYPT, CAU_DECRYPT
|
||||
key: key
|
||||
key_size: key size in bits, must be either 128, 192 or 256
|
||||
iv: initialization vector, 16 bytes
|
||||
input: input data
|
||||
in_length: input data length in bytes, must be a multiple of 16 bytes
|
||||
\param[out] output: pointer to the returned buffer
|
||||
\retval ErrStatus: SUCCESS or ERROR
|
||||
*/
|
||||
ErrStatus cau_aes_cfb(cau_parameter_struct *cau_parameter, uint8_t *output)
|
||||
{
|
||||
ErrStatus ret = ERROR;
|
||||
cau_key_parameter_struct key_initpara;
|
||||
cau_iv_parameter_struct iv_initpara;
|
||||
uint32_t ivaddr = (uint32_t)cau_parameter->iv;
|
||||
|
||||
/* key structure initialization */
|
||||
cau_key_struct_para_init(&key_initpara);
|
||||
/* initialize the CAU peripheral */
|
||||
cau_init(cau_parameter->alg_dir, CAU_MODE_AES_CFB, CAU_SWAPPING_8BIT);
|
||||
|
||||
/* AES key structure parameter config */
|
||||
cau_aes_key_config(cau_parameter->key, cau_parameter->key_size, &key_initpara);
|
||||
/* key initialization */
|
||||
cau_key_init(&key_initpara);
|
||||
|
||||
/* vectors initialization */
|
||||
iv_initpara.iv_0_high = __REV(*(uint32_t *)(ivaddr));
|
||||
ivaddr += 4U;
|
||||
iv_initpara.iv_0_low = __REV(*(uint32_t *)(ivaddr));
|
||||
ivaddr += 4U;
|
||||
iv_initpara.iv_1_high = __REV(*(uint32_t *)(ivaddr));
|
||||
ivaddr += 4U;
|
||||
iv_initpara.iv_1_low = __REV(*(uint32_t *)(ivaddr));
|
||||
cau_iv_init(&iv_initpara);
|
||||
|
||||
/* flush the IN and OUT FIFOs */
|
||||
cau_fifo_flush();
|
||||
/* enable the CAU peripheral */
|
||||
cau_enable();
|
||||
/* AES calculate process */
|
||||
ret = cau_aes_calculate(cau_parameter->input, cau_parameter->in_length, output);
|
||||
/* disable the CAU peripheral */
|
||||
cau_disable();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief encrypt and decrypt using AES in OFB mode
|
||||
\param[in] cau_parameter: pointer to the input structure
|
||||
alg_dir: algorithm directory
|
||||
CAU_ENCRYPT, CAU_DECRYPT
|
||||
key: key
|
||||
key_size: key size in bits, must be either 128, 192 or 256
|
||||
iv: initialization vector, 16 bytes
|
||||
input: input data
|
||||
in_length: input data length in bytes, must be a multiple of 16 bytes
|
||||
\param[out] output: pointer to the returned buffer
|
||||
\retval ErrStatus: SUCCESS or ERROR
|
||||
*/
|
||||
ErrStatus cau_aes_ofb(cau_parameter_struct *cau_parameter, uint8_t *output)
|
||||
{
|
||||
ErrStatus ret = ERROR;
|
||||
cau_key_parameter_struct key_initpara;
|
||||
cau_iv_parameter_struct iv_initpara;
|
||||
uint32_t ivaddr = (uint32_t)cau_parameter->iv;
|
||||
|
||||
/* key structure initialization */
|
||||
cau_key_struct_para_init(&key_initpara);
|
||||
/* initialize the CAU peripheral */
|
||||
cau_init(cau_parameter->alg_dir, CAU_MODE_AES_OFB, CAU_SWAPPING_8BIT);
|
||||
|
||||
/* AES key structure parameter config */
|
||||
cau_aes_key_config(cau_parameter->key, cau_parameter->key_size, &key_initpara);
|
||||
/* key initialization */
|
||||
cau_key_init(&key_initpara);
|
||||
|
||||
/* vectors initialization */
|
||||
iv_initpara.iv_0_high = __REV(*(uint32_t *)(ivaddr));
|
||||
ivaddr += 4U;
|
||||
iv_initpara.iv_0_low = __REV(*(uint32_t *)(ivaddr));
|
||||
ivaddr += 4U;
|
||||
iv_initpara.iv_1_high = __REV(*(uint32_t *)(ivaddr));
|
||||
ivaddr += 4U;
|
||||
iv_initpara.iv_1_low = __REV(*(uint32_t *)(ivaddr));
|
||||
cau_iv_init(&iv_initpara);
|
||||
|
||||
/* flush the IN and OUT FIFOs */
|
||||
cau_fifo_flush();
|
||||
/* enable the CAU peripheral */
|
||||
cau_enable();
|
||||
/* AES calculate process */
|
||||
ret = cau_aes_calculate(cau_parameter->input, cau_parameter->in_length, output);
|
||||
/* disable the CAU peripheral */
|
||||
cau_disable();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief encrypt and decrypt using AES in GCM mode
|
||||
\param[in] cau_parameter: pointer to the input structure
|
||||
alg_dir: algorithm directory
|
||||
CAU_ENCRYPT, CAU_DECRYPT
|
||||
key: key
|
||||
key_size: key size in bits, must be either 128, 192 or 256
|
||||
iv: initialization vector, 16 bytes
|
||||
input: input data
|
||||
in_length: input data length in bytes, must be a multiple of 16 bytes
|
||||
aad: additional authentication data
|
||||
aad_size: aad size in bytes, must be a multiple of 16 bytes
|
||||
\param[out] output: pointer to the returned output data buffer
|
||||
\param[out] tag: pointer to the returned tag buffer
|
||||
\retval ErrStatus: SUCCESS or ERROR
|
||||
*/
|
||||
ErrStatus cau_aes_gcm(cau_parameter_struct *cau_parameter, uint8_t *output, uint8_t *tag)
|
||||
{
|
||||
ErrStatus ret = SUCCESS;
|
||||
cau_key_parameter_struct key_initpara;
|
||||
cau_iv_parameter_struct iv_initpara;
|
||||
uint64_t aadlength = (uint64_t)cau_parameter->aad_size * 8U;
|
||||
uint64_t inputlength = (uint64_t)cau_parameter->in_length * 8U;
|
||||
uint32_t ivaddr = (uint32_t)cau_parameter->iv;
|
||||
uint32_t tagaddr = (uint32_t)tag;
|
||||
|
||||
/* key structure initialization */
|
||||
cau_key_struct_para_init(&key_initpara);
|
||||
/* initialize the CAU peripheral */
|
||||
cau_init(cau_parameter->alg_dir, CAU_MODE_AES_GCM, CAU_SWAPPING_8BIT);
|
||||
|
||||
/* AES key structure parameter config */
|
||||
cau_aes_key_config(cau_parameter->key, cau_parameter->key_size, &key_initpara);
|
||||
/* key initialization */
|
||||
cau_key_init(&key_initpara);
|
||||
|
||||
/* vectors initialization */
|
||||
iv_initpara.iv_0_high = __REV(*(uint32_t *)(ivaddr));
|
||||
ivaddr += 4U;
|
||||
iv_initpara.iv_0_low = __REV(*(uint32_t *)(ivaddr));
|
||||
ivaddr += 4U;
|
||||
iv_initpara.iv_1_high = __REV(*(uint32_t *)(ivaddr));
|
||||
ivaddr += 4U;
|
||||
iv_initpara.iv_1_low = __REV(*(uint32_t *)(ivaddr));
|
||||
cau_iv_init(&iv_initpara);
|
||||
|
||||
/* prepare phase */
|
||||
/* select prepare phase */
|
||||
cau_phase_config(CAU_PREPARE_PHASE);
|
||||
/* enable the CAU peripheral */
|
||||
cau_enable();
|
||||
/* wait for CAUEN bit to be 0 */
|
||||
while(ENABLE == cau_enable_state_get()) {
|
||||
}
|
||||
|
||||
/* aad phase */
|
||||
if((uint32_t)0U != cau_parameter->aad_size) {
|
||||
/* select aad phase */
|
||||
cau_phase_config(CAU_AAD_PHASE);
|
||||
/* flush the IN and OUT FIFOs */
|
||||
cau_fifo_flush();
|
||||
/* enable the CAU peripheral */
|
||||
cau_enable();
|
||||
|
||||
ret = cau_fill_data(cau_parameter->aad, cau_parameter->aad_size);
|
||||
|
||||
if(ERROR == ret) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* encrypt or decrypt phase */
|
||||
if((uint32_t)0U != cau_parameter->in_length) {
|
||||
/* select encrypt or decrypt phase */
|
||||
cau_phase_config(CAU_ENCRYPT_DECRYPT_PHASE);
|
||||
/* flush the IN and OUT FIFOs */
|
||||
cau_fifo_flush();
|
||||
/* enable the CAU peripheral */
|
||||
cau_enable();
|
||||
|
||||
/* AES calculate process */
|
||||
ret = cau_aes_calculate(cau_parameter->input, cau_parameter->in_length, output);
|
||||
|
||||
if(ERROR == ret) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* tag phase */
|
||||
/* select tag phase */
|
||||
cau_phase_config(CAU_TAG_PHASE);
|
||||
/* flush the IN and OUT FIFOs */
|
||||
cau_fifo_flush();
|
||||
/* enable the CAU peripheral */
|
||||
cau_enable();
|
||||
|
||||
if(DISABLE == cau_enable_state_get()) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
cau_data_write(__REV((uint32_t)(aadlength >> 32U)));
|
||||
cau_data_write(__REV((uint32_t)aadlength));
|
||||
cau_data_write(__REV((uint32_t)(inputlength >> 32U)));
|
||||
cau_data_write(__REV((uint32_t)inputlength));
|
||||
|
||||
/* wait until the ONE flag is set */
|
||||
while(RESET == cau_flag_get(CAU_FLAG_OUTFIFO_NO_EMPTY)) {
|
||||
}
|
||||
|
||||
/* read the tag in the OUT FIFO */
|
||||
*(uint32_t *)(tagaddr) = cau_data_read();
|
||||
tagaddr += 4U;
|
||||
*(uint32_t *)(tagaddr) = cau_data_read();
|
||||
tagaddr += 4U;
|
||||
*(uint32_t *)(tagaddr) = cau_data_read();
|
||||
tagaddr += 4U;
|
||||
*(uint32_t *)(tagaddr) = cau_data_read();
|
||||
|
||||
/* disable the CAU peripheral */
|
||||
cau_disable();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief encrypt and decrypt using AES in CCM mode
|
||||
\param[in] cau_parameter: pointer to the input structure
|
||||
alg_dir: algorithm directory
|
||||
CAU_ENCRYPT, CAU_DECRYPT
|
||||
key: key
|
||||
key_size: key size in bytes
|
||||
iv: initialization vector
|
||||
iv_size: iv size in bytes
|
||||
input: input data
|
||||
in_length: input data length in bytes
|
||||
aad: additional authentication data
|
||||
aad_size: aad size
|
||||
\param[in] mac_size: mac size (in bytes)
|
||||
\param[out] output: pointer to the returned output data buffer
|
||||
\param[out] tag: pointer to the returned tag buffer
|
||||
\param[out] aad_buf: pointer to the user buffer used when formatting aad block
|
||||
\retval ErrStatus: SUCCESS or ERROR
|
||||
*/
|
||||
ErrStatus cau_aes_ccm(cau_parameter_struct *cau_parameter, uint8_t *output, uint8_t tag[], uint32_t tag_size, uint8_t aad_buf[])
|
||||
{
|
||||
cau_key_parameter_struct key_initpara;
|
||||
cau_iv_parameter_struct iv_initpara;
|
||||
ErrStatus ret = ERROR;
|
||||
uint32_t inputaddr = (uint32_t)cau_parameter->input;
|
||||
uint32_t inputsize = cau_parameter->in_length;
|
||||
uint32_t aadaddr = (uint32_t)cau_parameter->aad;
|
||||
uint32_t aadsize = cau_parameter->aad_size;
|
||||
uint32_t aad_block_size = 0U;
|
||||
uint32_t ivaddr = (uint32_t)cau_parameter->iv;
|
||||
uint32_t ivsize = cau_parameter->iv_size;
|
||||
uint32_t outputaddr = (uint32_t)output;
|
||||
uint32_t i = 0U, plen = 0U;
|
||||
uint32_t head_index = 0U;
|
||||
uint8_t blockb0[16U] = {0U};
|
||||
uint8_t counter[16U] = {0U};
|
||||
uint32_t ctraddr = (uint32_t)counter;
|
||||
uint32_t b0addr = (uint32_t)blockb0;
|
||||
uint32_t temp_tag[4U];
|
||||
|
||||
/* formatting the aad block */
|
||||
if((uint32_t)0U != aadsize) {
|
||||
/* check that the aad length is lower than 2^16 - 2^8 = 65536 - 256 = 65280 */
|
||||
if(aadsize < 65280U) {
|
||||
aad_buf[head_index++] = (uint8_t)((aadsize >> 8U) & 0xFFU);
|
||||
aad_buf[head_index++] = (uint8_t)((aadsize) & 0xFFU);
|
||||
aad_block_size = aadsize + 2U;
|
||||
} else {
|
||||
/* aad is encoded as 0xFF || 0xFE || [aadsize]32, i.e., six octets */
|
||||
aad_buf[head_index++] = 0xFFU;
|
||||
aad_buf[head_index++] = 0xFEU;
|
||||
aad_buf[head_index++] = (uint8_t)((aadsize & 0xFF000000U) >> 24U);
|
||||
aad_buf[head_index++] = (uint8_t)((aadsize & 0x00FF0000U) >> 16U);
|
||||
aad_buf[head_index++] = (uint8_t)((aadsize & 0x0000FF00U) >> 8U);
|
||||
aad_buf[head_index++] = (uint8_t)(aadsize & 0x000000FFU);
|
||||
aad_block_size = aadsize + 6U;
|
||||
}
|
||||
/* copy the aad buffer in internal buffer "HBuffer" */
|
||||
for(i = 0U; i < aadsize; i++) {
|
||||
aad_buf[head_index++] = *(uint8_t *)((uint32_t)(aadaddr + i));
|
||||
}
|
||||
/* check if the aad block size is modulo 16 */
|
||||
if(0U != (aad_block_size % 16U)) {
|
||||
/* Pad the aad buffer with 0s till the HBuffer length is modulo 16 */
|
||||
for(i = aad_block_size; i <= ((aad_block_size / 16U) + 1U) * 16U; i++) {
|
||||
aad_buf[i] = 0U;
|
||||
}
|
||||
/* set the aad size to modulo 16 */
|
||||
aad_block_size = ((aad_block_size / 16U) + 1U) * 16U;
|
||||
}
|
||||
/* set the pointer aadaddr to HBuffer */
|
||||
aadaddr = (uint32_t)aad_buf;
|
||||
}
|
||||
|
||||
/* formatting the block B0 */
|
||||
if(0U != aadsize) {
|
||||
blockb0[0] = 0x40U;
|
||||
}
|
||||
/* flags byte */
|
||||
blockb0[0] |= (0U | (((((uint8_t) tag_size - 2U) / 2U) & 0x07U) << 3U) | (((uint8_t)(15U - ivsize) - 1U) & 0x07U));
|
||||
|
||||
if((MIN_CCM_IV_SIZE > ivsize) || (MAX_CCM_IV_SIZE < ivsize)) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
for(i = 0U; i < ivsize; i++) {
|
||||
blockb0[i + 1U] = *(uint8_t *)((uint32_t)(ivaddr + i));
|
||||
}
|
||||
|
||||
/* the byte length for payload length expressing, which plus the ivsize must equal to 15 bytes */
|
||||
plen = 15U - ivsize;
|
||||
/* if the byte length for payload length expressing is more than 4 bytes */
|
||||
if(plen > 4U) {
|
||||
/* pad the blockb0 after vectors, and before the last 4 bytes */
|
||||
for(; i < 11U; i++) {
|
||||
blockb0[i + 1U] = 0U;
|
||||
}
|
||||
blockb0[12U] = (uint8_t)((inputsize >> 24U) & 0xFFU);
|
||||
blockb0[13U] = (uint8_t)((inputsize >> 16U) & 0xFFU);
|
||||
blockb0[14U] = (uint8_t)((inputsize >> 8U) & 0xFFU);
|
||||
blockb0[15U] = (uint8_t)(inputsize & 0xFFU);
|
||||
} else {
|
||||
/* the payload length is expressed in plen bytes */
|
||||
for(; i < 15U; i++) {
|
||||
blockb0[i + 1U] = (uint8_t)((inputsize >> ((uint8_t)((plen - 1U) * 8U))) & 0xFFU);
|
||||
plen--;
|
||||
}
|
||||
}
|
||||
|
||||
/* formatting the initial counter */
|
||||
/* byte 0: bits 0-2 contain the same encoding of q as in B0 */
|
||||
counter[0] = blockb0[0] & BLOCK_B0_MASK;
|
||||
for(i = 1U; i < ivsize + 1U; i++) {
|
||||
counter[i] = blockb0[i];
|
||||
}
|
||||
/* set the LSB to 1 */
|
||||
counter[15] |= 0x01U;
|
||||
|
||||
/* prepare phase */
|
||||
/* flush the IN and OUT FIFOs */
|
||||
cau_fifo_flush();
|
||||
/* clear CAUEN bit to ensure CAU is disable */
|
||||
cau_disable();
|
||||
|
||||
/* key structure initialization */
|
||||
cau_key_struct_para_init(&key_initpara);
|
||||
/* initialize the CAU peripheral */
|
||||
cau_init(cau_parameter->alg_dir, CAU_MODE_AES_CCM, CAU_SWAPPING_8BIT);
|
||||
/* select init phase */
|
||||
cau_phase_config(CAU_PREPARE_PHASE);
|
||||
|
||||
/* AES key structure parameter config */
|
||||
cau_aes_key_config(cau_parameter->key, cau_parameter->key_size, &key_initpara);
|
||||
/* key initialization */
|
||||
cau_key_init(&key_initpara);
|
||||
|
||||
/* vectors initialization */
|
||||
iv_initpara.iv_0_high = __REV(*(uint32_t *)(ctraddr));
|
||||
ctraddr += 4U;
|
||||
iv_initpara.iv_0_low = __REV(*(uint32_t *)(ctraddr));
|
||||
ctraddr += 4U;
|
||||
iv_initpara.iv_1_high = __REV(*(uint32_t *)(ctraddr));
|
||||
ctraddr += 4U;
|
||||
iv_initpara.iv_1_low = __REV(*(uint32_t *)(ctraddr));
|
||||
cau_iv_init(&iv_initpara);
|
||||
|
||||
/* enable the CAU peripheral */
|
||||
cau_enable();
|
||||
|
||||
/* write block B0 in the In FIFO */
|
||||
cau_data_write(*(uint32_t *)(b0addr));
|
||||
b0addr += 4U;
|
||||
cau_data_write(*(uint32_t *)(b0addr));
|
||||
b0addr += 4U;
|
||||
cau_data_write(*(uint32_t *)(b0addr));
|
||||
b0addr += 4U;
|
||||
cau_data_write(*(uint32_t *)(b0addr));
|
||||
|
||||
/* wait for CAUEN bit to be 0 */
|
||||
while(ENABLE == cau_enable_state_get()) {
|
||||
}
|
||||
|
||||
/* aad phase */
|
||||
if((uint32_t)0U != aadsize) {
|
||||
/* select aad phase */
|
||||
cau_phase_config(CAU_AAD_PHASE);
|
||||
/* enable the CAU peripheral */
|
||||
cau_enable();
|
||||
|
||||
ret = cau_fill_data((uint8_t *)aadaddr, aad_block_size);
|
||||
|
||||
if(ERROR == ret) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* encrypt or decrypt phase */
|
||||
inputsize = cau_parameter->in_length;
|
||||
|
||||
if((uint32_t)0U != inputsize) {
|
||||
/* select encrypt or decrypt phase */
|
||||
cau_phase_config(CAU_ENCRYPT_DECRYPT_PHASE);
|
||||
/* enable the CAU peripheral */
|
||||
cau_enable();
|
||||
|
||||
/* AES calculate process */
|
||||
ret = cau_aes_calculate((uint8_t *)inputaddr, inputsize, (uint8_t *)outputaddr);
|
||||
|
||||
if(ERROR == ret) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* tag phase */
|
||||
/* select final phase */
|
||||
cau_phase_config(CAU_TAG_PHASE);
|
||||
/* enable the CAU peripheral */
|
||||
cau_enable();
|
||||
|
||||
if(DISABLE == cau_enable_state_get()) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
ctraddr = (uint32_t)counter;
|
||||
|
||||
cau_data_write(*(uint32_t *)(ctraddr));
|
||||
ctraddr += 4U;
|
||||
cau_data_write(*(uint32_t *)(ctraddr));
|
||||
ctraddr += 4U;
|
||||
cau_data_write(*(uint32_t *)(ctraddr));
|
||||
ctraddr += 4U;
|
||||
/* reset bit 0 (after 8-bit swap) is equivalent to reset bit 24 (before 8-bit swap) */
|
||||
cau_data_write(*(uint32_t *)(ctraddr) & 0xFEFFFFFFU);
|
||||
|
||||
/* wait until the ONE flag is set */
|
||||
while(RESET == cau_flag_get(CAU_FLAG_OUTFIFO_NO_EMPTY)) {
|
||||
}
|
||||
|
||||
/* read the tag in the OUT FIFO */
|
||||
temp_tag[0] = cau_data_read();
|
||||
temp_tag[1] = cau_data_read();
|
||||
temp_tag[2] = cau_data_read();
|
||||
temp_tag[3] = cau_data_read();
|
||||
|
||||
/* disable the CAU peripheral */
|
||||
cau_disable();
|
||||
|
||||
/* Copy temporary authentication TAG in user TAG buffer */
|
||||
for(i = 0U; i < tag_size; i++) {
|
||||
tag[i] = (uint8_t)(temp_tag[i / 4U] >> (8U * (i % 4U)));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
/*!
|
||||
\brief AES key structure parameter config
|
||||
\param[in] key: key used for AES algorithm
|
||||
\param[in] keysize: length of the key in bits, must be either 128, 192 or 256
|
||||
\param[out] cau_key_initpara: key init parameter struct
|
||||
key_0_high: key 0 high
|
||||
key_0_low: key 0 low
|
||||
key_1_high: key 1 high
|
||||
key_1_low: key 1 low
|
||||
key_2_high: key 2 high
|
||||
key_2_low: key 2 low
|
||||
key_3_high: key 3 high
|
||||
key_3_low: key 3 low
|
||||
\retval none
|
||||
*/
|
||||
static void cau_aes_key_config(uint8_t *key, uint32_t keysize, cau_key_parameter_struct *cau_key_initpara)
|
||||
{
|
||||
uint32_t keyaddr = (uint32_t)key;
|
||||
|
||||
switch(keysize) {
|
||||
/* 128-bit key initialization */
|
||||
case 128:
|
||||
cau_aes_keysize_config(CAU_KEYSIZE_128BIT);
|
||||
cau_key_initpara->key_2_high = __REV(*(uint32_t *)(keyaddr));
|
||||
keyaddr += 4U;
|
||||
cau_key_initpara->key_2_low = __REV(*(uint32_t *)(keyaddr));
|
||||
keyaddr += 4U;
|
||||
cau_key_initpara->key_3_high = __REV(*(uint32_t *)(keyaddr));
|
||||
keyaddr += 4U;
|
||||
cau_key_initpara->key_3_low = __REV(*(uint32_t *)(keyaddr));
|
||||
break;
|
||||
/* 192-bit key initialization */
|
||||
case 192:
|
||||
cau_aes_keysize_config(CAU_KEYSIZE_192BIT);
|
||||
cau_key_initpara->key_1_high = __REV(*(uint32_t *)(keyaddr));
|
||||
keyaddr += 4U;
|
||||
cau_key_initpara->key_1_low = __REV(*(uint32_t *)(keyaddr));
|
||||
keyaddr += 4U;
|
||||
cau_key_initpara->key_2_high = __REV(*(uint32_t *)(keyaddr));
|
||||
keyaddr += 4U;
|
||||
cau_key_initpara->key_2_low = __REV(*(uint32_t *)(keyaddr));
|
||||
keyaddr += 4U;
|
||||
cau_key_initpara->key_3_high = __REV(*(uint32_t *)(keyaddr));
|
||||
keyaddr += 4U;
|
||||
cau_key_initpara->key_3_low = __REV(*(uint32_t *)(keyaddr));
|
||||
break;
|
||||
/* 256-bit key initialization */
|
||||
case 256:
|
||||
cau_aes_keysize_config(CAU_KEYSIZE_256BIT);
|
||||
cau_key_initpara->key_0_high = __REV(*(uint32_t *)(keyaddr));
|
||||
keyaddr += 4U;
|
||||
cau_key_initpara->key_0_low = __REV(*(uint32_t *)(keyaddr));
|
||||
keyaddr += 4U;
|
||||
cau_key_initpara->key_1_high = __REV(*(uint32_t *)(keyaddr));
|
||||
keyaddr += 4U;
|
||||
cau_key_initpara->key_1_low = __REV(*(uint32_t *)(keyaddr));
|
||||
keyaddr += 4U;
|
||||
cau_key_initpara->key_2_high = __REV(*(uint32_t *)(keyaddr));
|
||||
keyaddr += 4U;
|
||||
cau_key_initpara->key_2_low = __REV(*(uint32_t *)(keyaddr));
|
||||
keyaddr += 4U;
|
||||
cau_key_initpara->key_3_high = __REV(*(uint32_t *)(keyaddr));
|
||||
keyaddr += 4U;
|
||||
cau_key_initpara->key_3_low = __REV(*(uint32_t *)(keyaddr));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief fill data into data input register
|
||||
\param[in] input: pointer to the input buffer
|
||||
\param[in] in_length: length of the input buffer in bytes, must be a multiple of 16 bytes
|
||||
\retval ErrStatus: SUCCESS or ERROR
|
||||
*/
|
||||
static ErrStatus cau_fill_data(uint8_t *input, uint32_t in_length)
|
||||
{
|
||||
uint32_t inputaddr = (uint32_t)input;
|
||||
uint32_t i = 0U;
|
||||
__IO uint32_t counter = 0U;
|
||||
uint32_t busystatus = 0U;
|
||||
|
||||
if(DISABLE == cau_enable_state_get()) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
for(i = 0U; i < in_length; i += BLOCK_DATA_SIZE) {
|
||||
/* wait until the IEM flag is set */
|
||||
while(RESET == cau_flag_get(CAU_FLAG_INFIFO_EMPTY)) {
|
||||
}
|
||||
|
||||
if(i + BLOCK_DATA_SIZE > in_length) {
|
||||
/* the last block data number is less than 128bit */
|
||||
uint32_t block_data_temp[4] = {0U};
|
||||
|
||||
/* fill the remaining bits with zero */
|
||||
memcpy(block_data_temp, (uint32_t *)inputaddr, in_length - i);
|
||||
inputaddr = (uint32_t)block_data_temp;
|
||||
|
||||
/* if GCM encryption or CCM decryption, then configurate NBPILB bits in CTL register */
|
||||
if((CAU_CTL & CAU_CTL_GCM_CCMPH) == CAU_ENCRYPT_DECRYPT_PHASE) {
|
||||
if((CAU_CTL & (CAU_CTL_ALGM | CAU_CTL_CAUDIR)) == (CAU_MODE_AES_GCM | CAU_ENCRYPT)) {
|
||||
CAU_CTL |= CAU_PADDING_BYTES(i + BLOCK_DATA_SIZE - in_length);
|
||||
} else if((CAU_CTL & (CAU_CTL_ALGM | CAU_CTL_CAUDIR)) == (CAU_MODE_AES_CCM | CAU_DECRYPT)) {
|
||||
CAU_CTL |= CAU_PADDING_BYTES(i + BLOCK_DATA_SIZE - in_length);
|
||||
} else {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* write data to the IN FIFO */
|
||||
cau_data_write(*(uint32_t *)(inputaddr));
|
||||
inputaddr += 4U;
|
||||
cau_data_write(*(uint32_t *)(inputaddr));
|
||||
inputaddr += 4U;
|
||||
cau_data_write(*(uint32_t *)(inputaddr));
|
||||
inputaddr += 4U;
|
||||
cau_data_write(*(uint32_t *)(inputaddr));
|
||||
inputaddr += 4U;
|
||||
}
|
||||
/* wait until the complete message has been processed */
|
||||
counter = 0U;
|
||||
do {
|
||||
busystatus = cau_flag_get(CAU_FLAG_BUSY);
|
||||
counter++;
|
||||
} while((AESBSY_TIMEOUT != counter) && (RESET != busystatus));
|
||||
|
||||
if(RESET != busystatus) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief AES calculate process
|
||||
\param[in] input: pointer to the input buffer
|
||||
\param[in] in_length: length of the input buffer in bytes, must be a multiple of 16 bytes
|
||||
\param[out] output: pointer to the returned buffer
|
||||
\retval ErrStatus: SUCCESS or ERROR
|
||||
*/
|
||||
static ErrStatus cau_aes_calculate(uint8_t *input, uint32_t in_length, uint8_t *output)
|
||||
{
|
||||
uint32_t inputaddr = (uint32_t)input;
|
||||
uint32_t outputaddr = (uint32_t)output;
|
||||
uint32_t i = 0U;
|
||||
__IO uint32_t counter = 0U;
|
||||
uint32_t busystatus = 0U;
|
||||
|
||||
/* the clock is not enabled or there is no embedded CAU peripheral */
|
||||
if(DISABLE == cau_enable_state_get()) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
for(i = 0U; i < in_length; i += BLOCK_DATA_SIZE) {
|
||||
/* wait until the IEM flag is set */
|
||||
while(RESET == cau_flag_get(CAU_FLAG_INFIFO_EMPTY)) {
|
||||
}
|
||||
|
||||
/* check if the last input data block */
|
||||
if(i + BLOCK_DATA_SIZE > in_length) {
|
||||
/* the last block data number is less than 128bit */
|
||||
uint32_t block_data_temp[4] = {0};
|
||||
|
||||
/* fill the remaining bits with zero */
|
||||
memcpy(block_data_temp, (uint32_t *)inputaddr, in_length - i);
|
||||
inputaddr = (uint32_t)block_data_temp;
|
||||
|
||||
/* if GCM encryption or CCM decryption, then configurate NBPILB bits in CTL register */
|
||||
if((CAU_CTL & (CAU_CTL_ALGM | CAU_CTL_CAUDIR)) == (CAU_MODE_AES_GCM | CAU_ENCRYPT)) {
|
||||
CAU_CTL |= CAU_PADDING_BYTES(i + BLOCK_DATA_SIZE - in_length);
|
||||
} else if((CAU_CTL & (CAU_CTL_ALGM | CAU_CTL_CAUDIR)) == (CAU_MODE_AES_CCM | CAU_DECRYPT)) {
|
||||
CAU_CTL |= CAU_PADDING_BYTES(i + BLOCK_DATA_SIZE - in_length);
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
/* write data to the IN FIFO */
|
||||
cau_data_write(*(uint32_t *)(inputaddr));
|
||||
inputaddr += 4U;
|
||||
cau_data_write(*(uint32_t *)(inputaddr));
|
||||
inputaddr += 4U;
|
||||
cau_data_write(*(uint32_t *)(inputaddr));
|
||||
inputaddr += 4U;
|
||||
cau_data_write(*(uint32_t *)(inputaddr));
|
||||
inputaddr += 4U;
|
||||
|
||||
/* wait until the complete message has been processed */
|
||||
counter = 0U;
|
||||
do {
|
||||
busystatus = cau_flag_get(CAU_FLAG_BUSY);
|
||||
counter++;
|
||||
} while((AESBSY_TIMEOUT != counter) && (RESET != busystatus));
|
||||
|
||||
if(RESET != busystatus) {
|
||||
return ERROR;
|
||||
} else {
|
||||
/* read the output block from the output FIFO */
|
||||
*(uint32_t *)(outputaddr) = cau_data_read();
|
||||
outputaddr += 4U;
|
||||
*(uint32_t *)(outputaddr) = cau_data_read();
|
||||
outputaddr += 4U;
|
||||
*(uint32_t *)(outputaddr) = cau_data_read();
|
||||
outputaddr += 4U;
|
||||
*(uint32_t *)(outputaddr) = cau_data_read();
|
||||
outputaddr += 4U;
|
||||
}
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
/*!
|
||||
\file gd32h7xx_cau_des.c
|
||||
\brief CAU DES driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_cau.h"
|
||||
|
||||
#define DESBUSY_TIMEOUT ((uint32_t)0x00010000U)
|
||||
|
||||
/* DES calculate process */
|
||||
static ErrStatus cau_des_calculate(uint8_t *input, uint32_t in_length, uint8_t *output);
|
||||
|
||||
/*!
|
||||
\brief encrypt and decrypt using DES in ECB mode
|
||||
\param[in] cau_parameter: pointer to the input structure
|
||||
alg_dir: algorithm directory
|
||||
CAU_ENCRYPT, CAU_DECRYPT
|
||||
key: key, 8 bytes
|
||||
input: input data
|
||||
in_length: input data length in bytes, must be a multiple of 8 bytes
|
||||
\param[out] output: pointer to the output buffer
|
||||
\retval ErrStatus: SUCCESS or ERROR
|
||||
*/
|
||||
ErrStatus cau_des_ecb(cau_parameter_struct *cau_parameter, uint8_t *output)
|
||||
{
|
||||
ErrStatus ret = ERROR;
|
||||
cau_key_parameter_struct key_initpara;
|
||||
uint32_t keyaddr = (uint32_t)(cau_parameter->key);
|
||||
uint32_t inputaddr = (uint32_t)(cau_parameter->input);
|
||||
uint32_t outputaddr = (uint32_t)output;
|
||||
|
||||
/* key structure initialization */
|
||||
cau_key_struct_para_init(&key_initpara);
|
||||
/* initialize the CAU peripheral */
|
||||
cau_init(cau_parameter->alg_dir, CAU_MODE_DES_ECB, CAU_SWAPPING_8BIT);
|
||||
|
||||
/* key initialisation */
|
||||
key_initpara.key_1_high = __REV(*(uint32_t *)(keyaddr));
|
||||
keyaddr += 4U;
|
||||
key_initpara.key_1_low = __REV(*(uint32_t *)(keyaddr));
|
||||
cau_key_init(&key_initpara);
|
||||
|
||||
/* flush the IN and OUT FIFOs */
|
||||
cau_fifo_flush();
|
||||
/* enable the CAU peripheral */
|
||||
cau_enable();
|
||||
/* DES calculate process */
|
||||
ret = cau_des_calculate((uint8_t *)inputaddr, cau_parameter->in_length, (uint8_t *)outputaddr);
|
||||
/* disable the CAU peripheral */
|
||||
cau_disable();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief encrypt and decrypt using DES in CBC mode
|
||||
\param[in] cau_parameter: pointer to the input structure
|
||||
alg_dir: algorithm directory
|
||||
CAU_ENCRYPT, CAU_DECRYPT
|
||||
key: key, 8 bytes
|
||||
iv: initialization vector, 8 bytes
|
||||
input: input data
|
||||
in_length: input data length in bytes, must be a multiple of 8 bytes
|
||||
\param[out] output: pointer to the output structure
|
||||
\retval ErrStatus: SUCCESS or ERROR
|
||||
*/
|
||||
ErrStatus cau_des_cbc(cau_parameter_struct *cau_parameter, uint8_t *output)
|
||||
{
|
||||
ErrStatus ret = ERROR;
|
||||
cau_key_parameter_struct key_initpara;
|
||||
cau_iv_parameter_struct iv_initpara;
|
||||
uint32_t keyaddr = (uint32_t)(cau_parameter->key);
|
||||
uint32_t inputaddr = (uint32_t)(cau_parameter->input);
|
||||
uint32_t outputaddr = (uint32_t)output;
|
||||
uint32_t ivaddr = (uint32_t)(cau_parameter->iv);
|
||||
|
||||
/* key structure initialization */
|
||||
cau_key_struct_para_init(&key_initpara);
|
||||
/* initialize the CAU peripheral */
|
||||
cau_init(cau_parameter->alg_dir, CAU_MODE_DES_CBC, CAU_SWAPPING_8BIT);
|
||||
|
||||
/* key initialisation */
|
||||
key_initpara.key_1_high = __REV(*(uint32_t *)(keyaddr));
|
||||
keyaddr += 4U;
|
||||
key_initpara.key_1_low = __REV(*(uint32_t *)(keyaddr));
|
||||
cau_key_init(&key_initpara);
|
||||
|
||||
/* vectors initialization */
|
||||
iv_initpara.iv_0_high = __REV(*(uint32_t *)(ivaddr));
|
||||
ivaddr += 4U;
|
||||
iv_initpara.iv_0_low = __REV(*(uint32_t *)(ivaddr));
|
||||
cau_iv_init(&iv_initpara);
|
||||
|
||||
/* flush the IN and OUT FIFOs */
|
||||
cau_fifo_flush();
|
||||
|
||||
/* enable the CAU peripheral */
|
||||
cau_enable();
|
||||
/* DES calculate process */
|
||||
ret = cau_des_calculate((uint8_t *)inputaddr, cau_parameter->in_length, (uint8_t *)outputaddr);
|
||||
/* disable the CAU peripheral */
|
||||
cau_disable();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief DES calculate process
|
||||
\param[in] input: pointer to the input buffer
|
||||
\param[in] in_length: length of the input buffer in bytes, must be a multiple of 8 bytes
|
||||
\param[in] output: pointer to the returned buffer
|
||||
\param[out] none
|
||||
\retval ErrStatus: SUCCESS or ERROR
|
||||
*/
|
||||
static ErrStatus cau_des_calculate(uint8_t *input, uint32_t in_length, uint8_t *output)
|
||||
{
|
||||
uint32_t inputaddr = (uint32_t)input;
|
||||
uint32_t outputaddr = (uint32_t)output;
|
||||
uint32_t i = 0U;
|
||||
__IO uint32_t counter = 0U;
|
||||
uint32_t busystatus = 0U;
|
||||
|
||||
/* the clock is not enabled or there is no embedded CAU peripheral */
|
||||
if(DISABLE == cau_enable_state_get()) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
for(i = 0U; i < in_length; i += 8U) {
|
||||
/* write data to the IN FIFO */
|
||||
cau_data_write(*(uint32_t *)(inputaddr));
|
||||
inputaddr += 4U;
|
||||
cau_data_write(*(uint32_t *)(inputaddr));
|
||||
inputaddr += 4U;
|
||||
|
||||
/* wait until the complete message has been processed */
|
||||
counter = 0U;
|
||||
do {
|
||||
busystatus = cau_flag_get(CAU_FLAG_BUSY);
|
||||
counter++;
|
||||
} while((DESBUSY_TIMEOUT != counter) && (RESET != busystatus));
|
||||
|
||||
if(RESET != busystatus) {
|
||||
return ERROR;
|
||||
} else {
|
||||
/* read the output block from the output FIFO */
|
||||
*(uint32_t *)(outputaddr) = cau_data_read();
|
||||
outputaddr += 4U;
|
||||
*(uint32_t *)(outputaddr) = cau_data_read();
|
||||
outputaddr += 4U;
|
||||
}
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
/*!
|
||||
\file gd32h7xx_cau_tdes.c
|
||||
\brief CAU TDES driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_cau.h"
|
||||
|
||||
#define TDESBSY_TIMEOUT ((uint32_t)0x00010000U)
|
||||
|
||||
/* TDES calculate process */
|
||||
static ErrStatus cau_tdes_calculate(uint8_t *input, uint32_t in_length, uint8_t *output);
|
||||
|
||||
/*!
|
||||
\brief encrypt and decrypt using TDES in ECB mode
|
||||
\param[in] cau_parameter: pointer to the input structure
|
||||
alg_dir: algorithm directory
|
||||
CAU_ENCRYPT, CAU_DECRYPT
|
||||
key: key, 24 bytes
|
||||
input: input data
|
||||
in_length: input data length in bytes, must be a multiple of 8 bytes
|
||||
\param[out] output: pointer to the output structure
|
||||
\retval ErrStatus: SUCCESS or ERROR
|
||||
*/
|
||||
ErrStatus cau_tdes_ecb(cau_parameter_struct *cau_parameter, uint8_t *output)
|
||||
{
|
||||
ErrStatus ret = ERROR;
|
||||
cau_key_parameter_struct key_initpara;
|
||||
uint32_t keyaddr = (uint32_t)(cau_parameter->key);
|
||||
uint32_t inputaddr = (uint32_t)(cau_parameter->input);
|
||||
uint32_t outputaddr = (uint32_t)output;
|
||||
|
||||
/* key structure initialization */
|
||||
cau_key_struct_para_init(&key_initpara);
|
||||
/* initialize the CAU peripheral */
|
||||
cau_init(cau_parameter->alg_dir, CAU_MODE_TDES_ECB, CAU_SWAPPING_8BIT);
|
||||
|
||||
/* key initialization */
|
||||
key_initpara.key_1_high = __REV(*(uint32_t *)(keyaddr));
|
||||
keyaddr += 4U;
|
||||
key_initpara.key_1_low = __REV(*(uint32_t *)(keyaddr));
|
||||
keyaddr += 4U;
|
||||
key_initpara.key_2_high = __REV(*(uint32_t *)(keyaddr));
|
||||
keyaddr += 4U;
|
||||
key_initpara.key_2_low = __REV(*(uint32_t *)(keyaddr));
|
||||
keyaddr += 4U;
|
||||
key_initpara.key_3_high = __REV(*(uint32_t *)(keyaddr));
|
||||
keyaddr += 4U;
|
||||
key_initpara.key_3_low = __REV(*(uint32_t *)(keyaddr));
|
||||
cau_key_init(&key_initpara);
|
||||
|
||||
/* flush the IN and OUT FIFOs */
|
||||
cau_fifo_flush();
|
||||
|
||||
/* enable the CAU peripheral */
|
||||
cau_enable();
|
||||
/* TDES calculate process */
|
||||
ret = cau_tdes_calculate((uint8_t *)inputaddr, cau_parameter->in_length, (uint8_t *)outputaddr);
|
||||
/* disable the CAU peripheral */
|
||||
cau_disable();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief encrypt and decrypt using TDES in CBC mode
|
||||
\param[in] cau_parameter: pointer to the input structure
|
||||
alg_dir: algorithm directory
|
||||
CAU_ENCRYPT, CAU_DECRYPT
|
||||
key: key, 24 bytes
|
||||
iv: initialization vector, 8 bytes
|
||||
input: input data
|
||||
in_length: input data length in bytes, must be a multiple of 8 bytes
|
||||
\param[out] output: pointer to the output structure
|
||||
\retval ErrStatus: SUCCESS or ERROR
|
||||
*/
|
||||
ErrStatus cau_tdes_cbc(cau_parameter_struct *cau_parameter, uint8_t *output)
|
||||
{
|
||||
ErrStatus ret = ERROR;
|
||||
cau_key_parameter_struct key_initpara;
|
||||
cau_iv_parameter_struct iv_initpara;
|
||||
uint32_t keyaddr = (uint32_t)(cau_parameter->key);
|
||||
uint32_t inputaddr = (uint32_t)(cau_parameter->input);
|
||||
uint32_t outputaddr = (uint32_t)output;
|
||||
uint32_t ivaddr = (uint32_t)(cau_parameter->iv);
|
||||
|
||||
/* key structure initialization */
|
||||
cau_key_struct_para_init(&key_initpara);
|
||||
/* initialize the CAU peripheral */
|
||||
cau_init(cau_parameter->alg_dir, CAU_MODE_TDES_CBC, CAU_SWAPPING_8BIT);
|
||||
|
||||
/* key initialization */
|
||||
key_initpara.key_1_high = __REV(*(uint32_t *)(keyaddr));
|
||||
keyaddr += 4U;
|
||||
key_initpara.key_1_low = __REV(*(uint32_t *)(keyaddr));
|
||||
keyaddr += 4U;
|
||||
key_initpara.key_2_high = __REV(*(uint32_t *)(keyaddr));
|
||||
keyaddr += 4U;
|
||||
key_initpara.key_2_low = __REV(*(uint32_t *)(keyaddr));
|
||||
keyaddr += 4U;
|
||||
key_initpara.key_3_high = __REV(*(uint32_t *)(keyaddr));
|
||||
keyaddr += 4U;
|
||||
key_initpara.key_3_low = __REV(*(uint32_t *)(keyaddr));
|
||||
cau_key_init(&key_initpara);
|
||||
|
||||
/* vectors initialization */
|
||||
iv_initpara.iv_0_high = __REV(*(uint32_t *)(ivaddr));
|
||||
ivaddr += 4U;
|
||||
iv_initpara.iv_0_low = __REV(*(uint32_t *)(ivaddr));
|
||||
cau_iv_init(&iv_initpara);
|
||||
|
||||
/* flush the IN and OUT FIFOs */
|
||||
cau_fifo_flush();
|
||||
/* enable the CAU peripheral */
|
||||
cau_enable();
|
||||
/* TDES calculate process */
|
||||
ret = cau_tdes_calculate((uint8_t *)inputaddr, cau_parameter->in_length, (uint8_t *)outputaddr);
|
||||
/* disable the CAU peripheral */
|
||||
cau_disable();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief TDES calculate process
|
||||
\param[in] input: pointer to the input buffer
|
||||
\param[in] in_length: length of the input buffer in bytes, must be a multiple of 8 bytes
|
||||
\param[out] output: pointer to the returned buffer
|
||||
\retval ErrStatus: SUCCESS or ERROR
|
||||
*/
|
||||
static ErrStatus cau_tdes_calculate(uint8_t *input, uint32_t in_length, uint8_t *output)
|
||||
{
|
||||
uint32_t inputaddr = (uint32_t)input;
|
||||
uint32_t outputaddr = (uint32_t)output;
|
||||
uint32_t i = 0U;
|
||||
__IO uint32_t counter = 0U;
|
||||
uint32_t busystatus = 0U;
|
||||
|
||||
/* the clock is not enabled or there is no embedded CAU peripheral */
|
||||
if(DISABLE == cau_enable_state_get()) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
for(i = 0U; i < in_length; i += 8U) {
|
||||
/* write data to the IN FIFO */
|
||||
cau_data_write(*(uint32_t *)(inputaddr));
|
||||
inputaddr += 4U;
|
||||
cau_data_write(*(uint32_t *)(inputaddr));
|
||||
inputaddr += 4U;
|
||||
|
||||
/* wait until the complete message has been processed */
|
||||
counter = 0U;
|
||||
do {
|
||||
busystatus = cau_flag_get(CAU_FLAG_BUSY);
|
||||
counter++;
|
||||
} while((TDESBSY_TIMEOUT != counter) && (RESET != busystatus));
|
||||
|
||||
if(RESET != busystatus) {
|
||||
return ERROR;
|
||||
} else {
|
||||
/* read the output block from the output FIFO */
|
||||
*(uint32_t *)(outputaddr) = cau_data_read();
|
||||
outputaddr += 4U;
|
||||
*(uint32_t *)(outputaddr) = cau_data_read();
|
||||
outputaddr += 4U;
|
||||
}
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,577 @@
|
||||
/*!
|
||||
\file gd32h7xx_cmp.c
|
||||
\brief CMP driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_cmp.h"
|
||||
|
||||
/*!
|
||||
\brief CMP deinit
|
||||
\param[in] cmp_periph
|
||||
\arg CMP0: comparator 0
|
||||
\arg CMP1: comparator 1
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cmp_deinit(cmp_enum cmp_periph)
|
||||
{
|
||||
if(CMP0 == cmp_periph){
|
||||
CMP0_CS &= ((uint32_t)0x00000000U);
|
||||
CMP_IFC &= ((uint32_t)0xFFFEFFFFU);
|
||||
CMP_STAT &= ((uint32_t)0xFFFEFFFEU);
|
||||
CMP_SR &= ((uint32_t)0x00000000U);
|
||||
}else if(CMP1 == cmp_periph){
|
||||
CMP1_CS &= ((uint32_t)0x00000000U);
|
||||
CMP_IFC &= ((uint32_t)0xFFFDFFFFU);
|
||||
CMP_STAT &= ((uint32_t)0xFFFDFFFDU);
|
||||
CMP_SR &= ((uint32_t)0x00000000U);
|
||||
}else{
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief CMP mode init
|
||||
\param[in] cmp_periph
|
||||
\arg CMP0: comparator 0
|
||||
\arg CMP1: comparator 1
|
||||
\param[in] operating_mode
|
||||
\arg CMP_MODE_HIGHSPEED: high speed mode
|
||||
\arg CMP_MODE_MIDDLESPEED: medium speed mode
|
||||
\arg CMP_MODE_VERYLOWSPEED: very-low speed mode
|
||||
\param[in] inverting_input
|
||||
\arg CMP_INVERTING_INPUT_1_4VREFINT: VREFINT *1/4 input
|
||||
\arg CMP_INVERTING_INPUT_1_2VREFINT: VREFINT *1/2 input
|
||||
\arg CMP_INVERTING_INPUT_3_4VREFINT: VREFINT *3/4 input
|
||||
\arg CMP_INVERTING_INPUT_VREFINT: VREFINT input
|
||||
\arg CMP_INVERTING_INPUT_DAC0_OUT0: CMP inverting input DAC0_OUT0
|
||||
\arg CMP_INVERTING_INPUT_DAC0_OUT1: CMP inverting input DAC0_OUT1
|
||||
\arg CMP_INVERTING_INPUT_PB1_PE10: PB1 for CMP0 or PE10 for CMP1 as inverting input
|
||||
\arg CMP_INVERTING_INPUT_PC4_PE7: PC4 for CMP0 or PE7 for CMP1 as inverting input
|
||||
\param[in] hysteresis
|
||||
\arg CMP_HYSTERESIS_NO: output no hysteresis
|
||||
\arg CMP_HYSTERESIS_LOW: output low hysteresis
|
||||
\arg CMP_HYSTERESIS_MIDDLE: output middle hysteresis
|
||||
\arg CMP_HYSTERESIS_HIGH: output high hysteresis
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cmp_mode_init(cmp_enum cmp_periph, uint32_t operating_mode, uint32_t inverting_input, uint32_t output_hysteresis)
|
||||
{
|
||||
uint32_t temp = 0U;
|
||||
|
||||
if(CMP0 == cmp_periph){
|
||||
/* initialize comparator 0 mode */
|
||||
temp = CMP0_CS;
|
||||
temp &= ~(uint32_t)(CMP_CS_CMPXM | CMP_CS_CMPXMISEL | CMP_CS_CMPXHST);
|
||||
temp |= (uint32_t)(operating_mode | inverting_input | output_hysteresis);
|
||||
CMP0_CS = temp;
|
||||
}else if(CMP1 == cmp_periph){
|
||||
/* initialize comparator 1 mode */
|
||||
temp = CMP1_CS;
|
||||
temp &= ~(uint32_t)(CMP_CS_CMPXM | CMP_CS_CMPXMISEL | CMP_CS_CMPXHST);
|
||||
temp |= (uint32_t)(operating_mode | inverting_input | output_hysteresis);
|
||||
CMP1_CS = temp;
|
||||
}else{
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief CMP noninverting input select
|
||||
\param[in] cmp_periph
|
||||
\arg CMP0: comparator 0
|
||||
\arg CMP1: comparator 1
|
||||
\param[in] noninverting_input
|
||||
\arg CMP_NONINVERTING_INPUT_PB0_PE9: CMP noninverting input PB0 for CMP0 or PE9 for CMP1
|
||||
\arg CMP_NONINVERTING_INPUT_PB2_PE12: CMP noninverting input PB2 for CMP0 or PE12 for CMP1
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cmp_noninverting_input_select(cmp_enum cmp_periph, uint32_t noninverting_input)
|
||||
{
|
||||
uint32_t temp = 0U;
|
||||
|
||||
if(CMP0 == cmp_periph){
|
||||
temp = CMP0_CS;
|
||||
temp &= ~(uint32_t)CMP_CS_CMPXPSEL;
|
||||
temp |= (uint32_t)noninverting_input;
|
||||
CMP0_CS = temp;
|
||||
}else if(CMP1 == cmp_periph){
|
||||
temp = CMP1_CS;
|
||||
temp &= ~(uint32_t)CMP_CS_CMPXPSEL;
|
||||
temp |= (uint32_t)noninverting_input;
|
||||
CMP1_CS = temp;
|
||||
}else{
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief CMP output init
|
||||
\param[in] cmp_periph
|
||||
\arg CMP0: comparator 0
|
||||
\arg CMP1: comparator 1
|
||||
\param[in] output_polarity
|
||||
\arg CMP_OUTPUT_POLARITY_INVERTED: output is inverted
|
||||
\arg CMP_OUTPUT_POLARITY_NONINVERTED: output is not inverted
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cmp_output_init(cmp_enum cmp_periph, uint32_t output_polarity)
|
||||
{
|
||||
uint32_t temp = 0U;
|
||||
|
||||
if(CMP0 == cmp_periph){
|
||||
/* initialize comparator 0 output */
|
||||
temp = CMP0_CS;
|
||||
/* output polarity */
|
||||
if(CMP_OUTPUT_POLARITY_INVERTED == output_polarity){
|
||||
temp |= (uint32_t)CMP_CS_CMPXPL;
|
||||
}else{
|
||||
temp &= ~(uint32_t)CMP_CS_CMPXPL;
|
||||
}
|
||||
CMP0_CS = temp;
|
||||
}else if(CMP1 == cmp_periph){
|
||||
/* initialize comparator 1 output */
|
||||
temp = CMP1_CS;
|
||||
/* output polarity */
|
||||
if(CMP_OUTPUT_POLARITY_INVERTED == output_polarity){
|
||||
temp |= (uint32_t)CMP_CS_CMPXPL;
|
||||
}else{
|
||||
temp &= ~(uint32_t)CMP_CS_CMPXPL;
|
||||
}
|
||||
CMP1_CS = temp;
|
||||
}else{
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief config comparator output port
|
||||
\param[in] cmp_periph
|
||||
\arg CMP0: comparator 0
|
||||
\arg CMP1: comparator 1
|
||||
\param[in] cmp_output_sel
|
||||
\arg CMP_AFSE_GPIO_PA6: CMP alternate GPIO PA6
|
||||
\arg CMP_AFSE_GPIO_PA8: CMP alternate GPIO PA8
|
||||
\arg CMP_AFSE_GPIO_PB12: CMP alternate GPIO PB12
|
||||
\arg CMP_AFSE_GPIO_PE6: CMP alternate GPIO PE6
|
||||
\arg CMP_AFSE_GPIO_PE15: CMP alternate GPIO PE15
|
||||
\arg CMP_AFSE_GPIO_PG2: CMP alternate GPIO PG2
|
||||
\arg CMP_AFSE_GPIO_PG3: CMP alternate GPIO PG3
|
||||
\arg CMP_AFSE_GPIO_PG4: CMP alternate GPIO PG4
|
||||
\arg CMP_AFSE_GPIO_PK0: CMP alternate GPIO PK0
|
||||
\arg CMP_AFSE_GPIO_PK1: CMP alternate GPIO PK1
|
||||
\arg CMP_AFSE_GPIO_PK2: CMP alternate GPIO PK2
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cmp_output_mux_config(cmp_enum cmp_periph, uint32_t cmp_output_sel)
|
||||
{
|
||||
if(CMP0 == cmp_periph){
|
||||
CMP_SR &= ~(uint32_t)cmp_output_sel;
|
||||
}else if(CMP1 == cmp_periph){
|
||||
CMP_SR |= cmp_output_sel;
|
||||
}else{
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief CMP output blanking function init
|
||||
\param[in] cmp_periph
|
||||
\arg CMP0: comparator 0
|
||||
\arg CMP1: comparator 1
|
||||
\param[in] blanking_source_selection
|
||||
\arg CMP_BLANKING_NONE: CMP no blanking source
|
||||
\arg CMP_BLANKING_TIMER0_OC0: CMP TIMER0_CH0 output compare signal selected as blanking source
|
||||
\arg CMP_BLANKING_TIMER1_OC2: CMP TIMER1_CH2 output compare signal selected as blanking source
|
||||
\arg CMP_BLANKING_TIMER2_OC2: CMP TIMER2_CH2 output compare signal selected as blanking source
|
||||
\arg CMP_BLANKING_TIMER2_OC3: CMP TIMER2_CH3 output compare signal selected as blanking source
|
||||
\arg CMP_BLANKING_TIMER7_OC0: CMP TIMER7_CH0 output compare signal selected as blanking source
|
||||
\arg CMP_BLANKING_TIMER14_OC0: CMP TIMER14_CH0 output compare signal selected as blanking source
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cmp_blanking_init(cmp_enum cmp_periph, uint32_t blanking_source_selection)
|
||||
{
|
||||
uint32_t temp = 0U;
|
||||
|
||||
if(CMP0 == cmp_periph){
|
||||
temp = CMP0_CS;
|
||||
temp &= ~(uint32_t)CMP_CS_CMPXBLK;
|
||||
temp |= (uint32_t)blanking_source_selection;
|
||||
CMP0_CS = temp;
|
||||
}else if(CMP1 == cmp_periph){
|
||||
temp = CMP1_CS;
|
||||
temp &= ~(uint32_t)CMP_CS_CMPXBLK;
|
||||
temp |= (uint32_t)blanking_source_selection;
|
||||
CMP1_CS = temp;
|
||||
}else{
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable CMP
|
||||
\param[in] cmp_periph
|
||||
\arg CMP0: comparator 0
|
||||
\arg CMP1: comparator 1
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cmp_enable(cmp_enum cmp_periph)
|
||||
{
|
||||
if(CMP0 == cmp_periph){
|
||||
CMP0_CS |= (uint32_t)CMP_CS_CMPXEN;
|
||||
}else if(CMP1 == cmp_periph){
|
||||
CMP1_CS |= (uint32_t)CMP_CS_CMPXEN;
|
||||
}else{
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable CMP
|
||||
\param[in] cmp_periph
|
||||
\arg CMP0: comparator 0
|
||||
\arg CMP1: comparator 1
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cmp_disable(cmp_enum cmp_periph)
|
||||
{
|
||||
if(CMP0 == cmp_periph){
|
||||
CMP0_CS &= ~(uint32_t)CMP_CS_CMPXEN;
|
||||
}else if(CMP1 == cmp_periph){
|
||||
CMP1_CS &= ~(uint32_t)CMP_CS_CMPXEN;
|
||||
}else{
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the window mode
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cmp_window_enable(void)
|
||||
{
|
||||
CMP1_CS |= (uint32_t)CMP_CS_WNDEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the window mode
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cmp_window_disable(void)
|
||||
{
|
||||
CMP1_CS &= ~(uint32_t)CMP_CS_WNDEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief lock the comparator
|
||||
\param[in] cmp_periph
|
||||
\arg CMP0: comparator 0
|
||||
\arg CMP1: comparator 1
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cmp_lock_enable(cmp_enum cmp_periph)
|
||||
{
|
||||
if(CMP0 == cmp_periph){
|
||||
/* lock CMP0 */
|
||||
CMP0_CS |= (uint32_t)CMP_CS_CMPXLK;
|
||||
}else if(CMP1 == cmp_periph){
|
||||
/* lock CMP1 */
|
||||
CMP1_CS |= (uint32_t)CMP_CS_CMPXLK;
|
||||
}else{
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the voltage scaler
|
||||
\param[in] cmp_periph
|
||||
\arg CMP0: comparator 0
|
||||
\arg CMP1: comparator 1
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cmp_voltage_scaler_enable(cmp_enum cmp_periph)
|
||||
{
|
||||
if(CMP0 == cmp_periph){
|
||||
CMP0_CS |= (uint32_t)CMP_CS_CMPXSEN;
|
||||
}else if(CMP1 == cmp_periph){
|
||||
CMP1_CS |= (uint32_t)CMP_CS_CMPXSEN;
|
||||
}else{
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the voltage scaler
|
||||
\param[in] cmp_periph
|
||||
\arg CMP0: comparator 0
|
||||
\arg CMP1: comparator 1
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cmp_voltage_scaler_disable(cmp_enum cmp_periph)
|
||||
{
|
||||
if(CMP0 == cmp_periph){
|
||||
CMP0_CS &= ~(uint32_t)CMP_CS_CMPXSEN;
|
||||
}else if(CMP1 == cmp_periph){
|
||||
CMP1_CS &= ~(uint32_t)CMP_CS_CMPXSEN;
|
||||
}else{
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the scaler bridge
|
||||
\param[in] cmp_periph
|
||||
\arg CMP0: comparator 0
|
||||
\arg CMP1: comparator 1
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cmp_scaler_bridge_enable(cmp_enum cmp_periph)
|
||||
{
|
||||
if(CMP0 == cmp_periph){
|
||||
CMP0_CS |= (uint32_t)CMP_CS_CMPXBEN;
|
||||
}else if(CMP1 == cmp_periph){
|
||||
CMP1_CS |= (uint32_t)CMP_CS_CMPXBEN;
|
||||
}else{
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the scaler bridge
|
||||
\param[in] cmp_periph
|
||||
\arg CMP0: comparator 0
|
||||
\arg CMP1: comparator 1
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cmp_scaler_bridge_disable(cmp_enum cmp_periph)
|
||||
{
|
||||
if(CMP0 == cmp_periph){
|
||||
CMP0_CS &= ~(uint32_t)CMP_CS_CMPXBEN;
|
||||
}else if(CMP1 == cmp_periph){
|
||||
CMP1_CS &= ~(uint32_t)CMP_CS_CMPXBEN;
|
||||
}else{
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get output level
|
||||
\param[in] cmp_periph
|
||||
\arg CMP0: comparator 0
|
||||
\arg CMP1: comparator 1
|
||||
\param[out] none
|
||||
\retval the output level
|
||||
*/
|
||||
uint32_t cmp_output_level_get(cmp_enum cmp_periph)
|
||||
{
|
||||
if(CMP0 == cmp_periph){
|
||||
/* get output level of CMP0 */
|
||||
if((uint32_t)RESET != (CMP_STAT & CMP_STAT_CMP0O)) {
|
||||
return CMP_OUTPUTLEVEL_HIGH;
|
||||
}else{
|
||||
return CMP_OUTPUTLEVEL_LOW;
|
||||
}
|
||||
}else{
|
||||
/* get output level of CMP1 */
|
||||
if((uint32_t)RESET != (CMP_STAT & CMP_STAT_CMP1O)) {
|
||||
return CMP_OUTPUTLEVEL_HIGH;
|
||||
}else{
|
||||
return CMP_OUTPUTLEVEL_LOW;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get CMP flag
|
||||
\param[in] cmp_periph
|
||||
\arg CMP0: comparator 0
|
||||
\arg CMP1: comparator 1
|
||||
\param[in] flag: CMP flags
|
||||
\arg CMP_FLAG_COMPARE: CMP compare flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus cmp_flag_get(cmp_enum cmp_periph, uint32_t flag)
|
||||
{
|
||||
FlagStatus reval = RESET;
|
||||
|
||||
if(CMP0 == cmp_periph){
|
||||
if(CMP_FLAG_COMPARE == flag){
|
||||
if(0U != (CMP_STAT & CMP_STAT_CMP0IF)){
|
||||
reval = SET;
|
||||
}
|
||||
}
|
||||
}else if(CMP1 == cmp_periph){
|
||||
if(CMP_FLAG_COMPARE == flag){
|
||||
if(0U != (CMP_STAT & CMP_STAT_CMP1IF)){
|
||||
reval = SET;
|
||||
}
|
||||
}
|
||||
}
|
||||
return reval;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear CMP flag
|
||||
\param[in] cmp_periph
|
||||
\arg CMP0: comparator 0
|
||||
\arg CMP1: comparator 1
|
||||
\param[in] flag: CMP flags
|
||||
\arg CMP_FLAG_COMPARE: CMP compare flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cmp_flag_clear(cmp_enum cmp_periph, uint32_t flag)
|
||||
{
|
||||
if(CMP0 == cmp_periph){
|
||||
if(CMP_FLAG_COMPARE == flag){
|
||||
CMP_IFC |= (uint32_t)CMP_IFC_CMP0IC;
|
||||
}
|
||||
}else if(CMP1 == cmp_periph){
|
||||
if(CMP_FLAG_COMPARE == flag){
|
||||
CMP_IFC |= (uint32_t)CMP_IFC_CMP1IC;
|
||||
}
|
||||
}else{
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable CMP interrupt
|
||||
\param[in] cmp_periph
|
||||
\arg CMP0: comparator 0
|
||||
\arg CMP1: comparator 1
|
||||
\param[in] interrupt: CMP interrupt enable source
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CMP_INT_COMPARE: CMP compare interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cmp_interrupt_enable(cmp_enum cmp_periph, uint32_t interrupt)
|
||||
{
|
||||
if(CMP0 == cmp_periph){
|
||||
/* enable CMP0 interrupt */
|
||||
CMP0_CS |= (uint32_t)interrupt;
|
||||
}else if(CMP1 == cmp_periph){
|
||||
/* enable CMP1 interrupt */
|
||||
CMP1_CS |= (uint32_t)interrupt;
|
||||
}else{
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable CMP interrupt
|
||||
\param[in] cmp_periph
|
||||
\arg CMP0: comparator 0
|
||||
\arg CMP1: comparator 1
|
||||
\param[in] interrupt: CMP interrupt enable source
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CMP_INT_COMPARE: CMP compare interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cmp_interrupt_disable(cmp_enum cmp_periph, uint32_t interrupt)
|
||||
{
|
||||
if(CMP0 == cmp_periph){
|
||||
/* disable CMP0 interrupt */
|
||||
CMP0_CS &= ~(uint32_t)interrupt;
|
||||
}else if(CMP1 == cmp_periph){
|
||||
/* disable CMP1 interrupt */
|
||||
CMP1_CS &= ~(uint32_t)interrupt;
|
||||
}else{
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get CMP interrupt flag
|
||||
\param[in] cmp_periph
|
||||
\arg CMP0: comparator 0
|
||||
\arg CMP1: comparator 1
|
||||
\param[in] flag: CMP interrupt flags
|
||||
\arg CMP_INT_FLAG_COMPARE: CMP compare interrupt flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
FlagStatus cmp_interrupt_flag_get(cmp_enum cmp_periph, uint32_t flag)
|
||||
{
|
||||
uint32_t intstatus = 0U, flagstatus = 0U;
|
||||
|
||||
if(CMP0 == cmp_periph){
|
||||
if(CMP_INT_FLAG_COMPARE == flag){
|
||||
/* get the corresponding flag bit status */
|
||||
flagstatus = CMP_STAT & CMP_STAT_CMP0IF;
|
||||
/* get the interrupt enable bit status */
|
||||
intstatus = CMP0_CS & CMP_CS_CMPXINTEN;
|
||||
}
|
||||
}else if(CMP1 == cmp_periph){
|
||||
if(CMP_INT_FLAG_COMPARE == flag){
|
||||
/* get the corresponding flag bit status */
|
||||
flagstatus = CMP_STAT & CMP_STAT_CMP1IF;
|
||||
/* get the interrupt enable bit status */
|
||||
intstatus = CMP1_CS & CMP_CS_CMPXINTEN;
|
||||
}
|
||||
}else{
|
||||
}
|
||||
|
||||
if((0U != flagstatus) && (0U != intstatus)){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear CMP interrupt flag
|
||||
\param[in] cmp_periph
|
||||
\arg CMP0: comparator 0
|
||||
\arg CMP1: comparator 1
|
||||
\param[in] flag: CMP interrupt flags
|
||||
\arg CMP_INT_FLAG_COMPARE: CMP compare interrupt flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cmp_interrupt_flag_clear(cmp_enum cmp_periph, uint32_t flag)
|
||||
{
|
||||
/* clear CMP interrupt flag */
|
||||
if(CMP0 == cmp_periph){
|
||||
if(CMP_INT_FLAG_COMPARE == flag){
|
||||
CMP_IFC |= (uint32_t)CMP_IFC_CMP0IC;
|
||||
}
|
||||
}else if(CMP1 == cmp_periph){
|
||||
if(CMP_INT_FLAG_COMPARE == flag){
|
||||
CMP_IFC |= (uint32_t)CMP_IFC_CMP1IC;
|
||||
}
|
||||
}else{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,276 @@
|
||||
/*!
|
||||
\file gd32h7xx_cpdm.c
|
||||
\brief CPDM driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_cpdm.h"
|
||||
|
||||
#define CPDM_CPSEL_MASK ((uint32_t)0xFFFFFFF0U) /*!< CPDM output clock phase seclection mask */
|
||||
#define CPDM_DLSTCNT_MASK ((uint32_t)0xFFFF80FFU) /*!< CPDM delay step count for a uint delay UINT mask */
|
||||
#define CPDM_DLLENF_MASK ((uint32_t)0x80000000U) /*!< CPDM delay line length valid flag mask */
|
||||
#define CPDM_DLLEN_MASK ((uint32_t)0x0FFF0000U) /*!< CPDM delay line length mask */
|
||||
|
||||
#define CPDM_DLLEN_OFFSET ((uint32_t)16U) /*!< CPDM delay line length offset */
|
||||
#define CPDM_DLSTCNT_OFFSET ((uint32_t)8U) /*!< CPDM delay step count for a uint delay UINT offset */
|
||||
#define CPDM_DLLEN_11 ((uint32_t)0x04000000U) /*!< CPDM delay line length bit 11 */
|
||||
#define CPDM_DLLEN_10 ((uint32_t)0x08000000U) /*!< CPDM delay line length bit 10 */
|
||||
#define CPDM_DLLEN_10_0_MASK ((uint32_t)0x7FFU) /*!< CPDM delay line length bit 10 to bit 0 mask */
|
||||
|
||||
#define CPDM_MAX_TIMEOUT ((uint32_t)0x0000FFFFU) /*!< count to judge of CPDM timeout */
|
||||
|
||||
/*!
|
||||
\brief enable CPDM
|
||||
\param[in] cpdm_periph: the clock phase delay module of SDIO
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CPDM_SDIO0: clock phase delay module of SDIO0
|
||||
\arg CPDM_SDIO1: clock phase delay module of SDIO1
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cpdm_enable(uint32_t cpdm_periph)
|
||||
{
|
||||
/* enable CPDM */
|
||||
CPDM_CTL(cpdm_periph) |= (uint32_t)CPDM_CTL_CPDMEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable CPDM
|
||||
\param[in] cpdm_periph: the clock phase delay module of SDIO
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CPDM_SDIO0: clock phase delay module of SDIO0
|
||||
\arg CPDM_SDIO1: clock phase delay module of SDIO1
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cpdm_disable(uint32_t cpdm_periph)
|
||||
{
|
||||
/* disable CPDM */
|
||||
CPDM_CTL(cpdm_periph) &= ~(uint32_t)CPDM_CTL_CPDMEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable CPDM delay line sample module
|
||||
\param[in] cpdm_periph: the clock phase delay module of SDIO
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CPDM_SDIO0: clock phase delay module of SDIO0
|
||||
\arg CPDM_SDIO1: clock phase delay module of SDIO1
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cpdm_delayline_sample_enable(uint32_t cpdm_periph)
|
||||
{
|
||||
/* enable CPDM delay line sample module */
|
||||
CPDM_CTL(cpdm_periph) |= (uint32_t)CPDM_CTL_DLSEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable CPDM delay line sample module
|
||||
\param[in] cpdm_periph: the clock phase delay module of SDIO
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CPDM_SDIO0: clock phase delay module of SDIO0
|
||||
\arg CPDM_SDIO1: clock phase delay module of SDIO1
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cpdm_delayline_sample_disable(uint32_t cpdm_periph)
|
||||
{
|
||||
/* disable CPDM delay line sample module */
|
||||
CPDM_CTL(cpdm_periph) &= ~(uint32_t)CPDM_CTL_DLSEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief select CPDM output clock phase
|
||||
\param[in] cpdm_periph: the clock phase delay module of SDIO
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CPDM_SDIO0: clock phase delay module of SDIO0
|
||||
\arg CPDM_SDIO1: clock phase delay module of SDIO1
|
||||
\param[in] output_clock_phase: the output clock phase, refer to cpdm_output_phase_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CPDM_OUTPUT_PHASE_SELECTION_0: output clock phase = input clock
|
||||
\arg CPDM_OUTPUT_PHASE_SELECTION_1: output clock phase = input clock + 1 * UNIT delay
|
||||
\arg CPDM_OUTPUT_PHASE_SELECTION_2: output clock phase = input clock + 2 * UNIT delay
|
||||
\arg CPDM_OUTPUT_PHASE_SELECTION_3: output clock phase = input clock + 3 * UNIT delay
|
||||
\arg CPDM_OUTPUT_PHASE_SELECTION_4: output clock phase = input clock + 4 * UNIT delay
|
||||
\arg CPDM_OUTPUT_PHASE_SELECTION_5: output clock phase = input clock + 5 * UNIT delay
|
||||
\arg CPDM_OUTPUT_PHASE_SELECTION_6: output clock phase = input clock + 6 * UNIT delay
|
||||
\arg CPDM_OUTPUT_PHASE_SELECTION_7: output clock phase = input clock + 7 * UNIT delay
|
||||
\arg CPDM_OUTPUT_PHASE_SELECTION_8: output clock phase = input clock + 8 * UNIT delay
|
||||
\arg CPDM_OUTPUT_PHASE_SELECTION_9: output clock phase = input clock + 9 * UNIT delay
|
||||
\arg CPDM_OUTPUT_PHASE_SELECTION_10: output clock phase = input clock + 10 * UNIT delay
|
||||
\arg CPDM_OUTPUT_PHASE_SELECTION_11: output clock phase = input clock + 11 * UNIT delay
|
||||
\arg CPDM_OUTPUT_PHASE_SELECTION_12: output clock phase = input clock + 12 * UNIT delay
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cpdm_output_clock_phase_select(uint32_t cpdm_periph, cpdm_output_phase_enum output_clock_phase)
|
||||
{
|
||||
uint32_t reg = 0U;
|
||||
|
||||
reg = CPDM_CFG(cpdm_periph);
|
||||
reg &= CPDM_CPSEL_MASK;
|
||||
/* select CPDM output clock phase */
|
||||
reg |= output_clock_phase;
|
||||
CPDM_CFG(cpdm_periph) = (uint32_t)reg;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure CPDM delay step
|
||||
\param[in] cpdm_periph: the clock phase delay module of SDIO
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CPDM_SDIO0: clock phase delay module of SDIO0
|
||||
\arg CPDM_SDIO1: clock phase delay module of SDIO1
|
||||
\param[in] delay_step: 0 ~ 127
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cpdm_delay_step_config(uint32_t cpdm_periph, uint8_t delay_step)
|
||||
{
|
||||
uint32_t reg = 0U;
|
||||
|
||||
reg = CPDM_CFG(cpdm_periph);
|
||||
reg &= CPDM_DLSTCNT_MASK;
|
||||
/* configure delay step */
|
||||
reg |= ((uint32_t)delay_step << CPDM_DLSTCNT_OFFSET);
|
||||
CPDM_CFG(cpdm_periph) = (uint32_t)reg;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get delay line length valid flag
|
||||
\param[in] cpdm_periph: the clock phase delay module of SDIO
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CPDM_SDIO0: clock phase delay module of SDIO0
|
||||
\arg CPDM_SDIO1: clock phase delay module of SDIO1
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus cpdm_delayline_length_valid_flag_get(uint32_t cpdm_periph)
|
||||
{
|
||||
uint32_t reg = 0U;
|
||||
|
||||
reg = CPDM_CFG(cpdm_periph);
|
||||
if(reg & CPDM_DLLENF_MASK) {
|
||||
return SET;
|
||||
} else {
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get delay line length
|
||||
\param[in] cpdm_periph: the clock phase delay module of SDIO
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CPDM_SDIO0: clock phase delay module of SDIO0
|
||||
\arg CPDM_SDIO1: clock phase delay module of SDIO1
|
||||
\param[out] none
|
||||
\retval the value of delay line length, 0x00~0xFFF
|
||||
*/
|
||||
uint16_t cpdm_delayline_length_get(uint32_t cpdm_periph)
|
||||
{
|
||||
return (uint16_t)((CPDM_CFG(cpdm_periph) & CPDM_DLLEN_MASK) >> CPDM_DLLEN_OFFSET);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure CPDM clock output
|
||||
\param[in] cpdm_periph: the clock phase delay module of SDIO
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CPDM_SDIO0: clock phase delay module of SDIO0
|
||||
\arg CPDM_SDIO1: clock phase delay module of SDIO1
|
||||
\param[in] output_clock_phase: the output clock phase, refer to cpdm_output_phase_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CPDM_OUTPUT_PHASE_SELECTION_0: output clock phase = input clock
|
||||
\arg CPDM_OUTPUT_PHASE_SELECTION_1: output clock phase = input clock + 1 * UNIT delay
|
||||
\arg CPDM_OUTPUT_PHASE_SELECTION_2: output clock phase = input clock + 2 * UNIT delay
|
||||
\arg CPDM_OUTPUT_PHASE_SELECTION_3: output clock phase = input clock + 3 * UNIT delay
|
||||
\arg CPDM_OUTPUT_PHASE_SELECTION_4: output clock phase = input clock + 4 * UNIT delay
|
||||
\arg CPDM_OUTPUT_PHASE_SELECTION_5: output clock phase = input clock + 5 * UNIT delay
|
||||
\arg CPDM_OUTPUT_PHASE_SELECTION_6: output clock phase = input clock + 6 * UNIT delay
|
||||
\arg CPDM_OUTPUT_PHASE_SELECTION_7: output clock phase = input clock + 7 * UNIT delay
|
||||
\arg CPDM_OUTPUT_PHASE_SELECTION_8: output clock phase = input clock + 8 * UNIT delay
|
||||
\arg CPDM_OUTPUT_PHASE_SELECTION_9: output clock phase = input clock + 9 * UNIT delay
|
||||
\arg CPDM_OUTPUT_PHASE_SELECTION_10: output clock phase = input clock + 10 * UNIT delay
|
||||
\arg CPDM_OUTPUT_PHASE_SELECTION_11: output clock phase = input clock + 11 * UNIT delay
|
||||
\arg CPDM_OUTPUT_PHASE_SELECTION_12: output clock phase = input clock + 12 * UNIT delay
|
||||
\param[out] none
|
||||
\retval ErrStatus: SUCCESS or ERROR
|
||||
*/
|
||||
ErrStatus cpdm_clock_output(uint32_t cpdm_periph, cpdm_output_phase_enum output_clock_phase)
|
||||
{
|
||||
uint32_t reg = 0U;
|
||||
uint32_t reg_cfg = 0U;
|
||||
uint32_t delay_count = 0U;
|
||||
uint32_t timeout = 0U;
|
||||
|
||||
/* enable CPDM and delay line sample module */
|
||||
CPDM_CTL(cpdm_periph) = 0U;
|
||||
CPDM_CTL(cpdm_periph) = CPDM_CTL_CPDMEN | CPDM_CTL_DLSEN;
|
||||
/* configure CPDM output clock phase to the max value (12) */
|
||||
reg = CPDM_CFG(cpdm_periph);
|
||||
reg &= CPDM_CPSEL_MASK;
|
||||
reg |= CPDM_MAX_PHASE;
|
||||
CPDM_CFG(cpdm_periph) = (uint32_t)reg;
|
||||
|
||||
for(delay_count = 0U; delay_count <= CPDM_MAX_DELAY_STEP_COUNT; delay_count++) {
|
||||
reg = CPDM_CFG(cpdm_periph);
|
||||
reg &= CPDM_DLSTCNT_MASK;
|
||||
/* configure delay line step count */
|
||||
reg |= delay_count << CPDM_DLSTCNT_OFFSET;
|
||||
CPDM_CFG(cpdm_periph) = (uint32_t)reg;
|
||||
|
||||
while(RESET == (CPDM_CFG(cpdm_periph) & CPDM_CFG_DLLENF)) {
|
||||
timeout++;
|
||||
|
||||
if(timeout > CPDM_MAX_TIMEOUT)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
reg_cfg = CPDM_CFG(cpdm_periph);
|
||||
if((((reg_cfg >> CPDM_DLLEN_OFFSET) & CPDM_DLLEN_10_0_MASK) > 0U) &&
|
||||
((RESET == (reg_cfg & CPDM_DLLEN_11)) || (RESET == (reg_cfg & CPDM_DLLEN_10)))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* enable CPDM and delay line sample module */
|
||||
CPDM_CTL(cpdm_periph) = 0U;
|
||||
CPDM_CTL(cpdm_periph) = CPDM_CTL_CPDMEN | CPDM_CTL_DLSEN;
|
||||
/* select the output clock phase */
|
||||
reg = CPDM_CFG(cpdm_periph);
|
||||
reg &= CPDM_CPSEL_MASK;
|
||||
reg |= output_clock_phase;
|
||||
CPDM_CFG(cpdm_periph) = (uint32_t)reg;
|
||||
/* disable delay line sample module */
|
||||
CPDM_CTL(cpdm_periph) = CPDM_CTL_CPDMEN;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,247 @@
|
||||
/*!
|
||||
\file gd32h7xx_crc.c
|
||||
\brief CRC driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_crc.h"
|
||||
|
||||
#define CRC_IDATA_RESET_VALUE ((uint32_t)0xFFFFFFFFU)
|
||||
#define CRC_DATA_RESET_VALUE ((uint32_t)0xFFFFFFFFU)
|
||||
#define CRC_FDATA_RESET_VALUE ((uint32_t)0x00000000U)
|
||||
#define CRC_POLY_RESET_VALUE ((uint32_t)0x04C11DB7U)
|
||||
|
||||
/*!
|
||||
\brief deinit CRC calculation unit
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void crc_deinit(void)
|
||||
{
|
||||
CRC_IDATA = CRC_IDATA_RESET_VALUE;
|
||||
CRC_DATA = CRC_DATA_RESET_VALUE;
|
||||
CRC_FDATA = CRC_FDATA_RESET_VALUE;
|
||||
CRC_POLY = CRC_POLY_RESET_VALUE;
|
||||
CRC_CTL = (uint32_t)CRC_CTL_RST;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the reverse operation of output data
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void crc_reverse_output_data_enable(void)
|
||||
{
|
||||
CRC_CTL &= (uint32_t)(~CRC_CTL_REV_O);
|
||||
CRC_CTL |= (uint32_t)CRC_CTL_REV_O;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the reverse operation of output data
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void crc_reverse_output_data_disable(void)
|
||||
{
|
||||
CRC_CTL &= (uint32_t)(~CRC_CTL_REV_O);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief reset data register to the value of initialization data register
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void crc_data_register_reset(void)
|
||||
{
|
||||
CRC_CTL |= (uint32_t)CRC_CTL_RST;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief read the data register
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval 32-bit value of the data register
|
||||
*/
|
||||
uint32_t crc_data_register_read(void)
|
||||
{
|
||||
uint32_t data;
|
||||
data = CRC_DATA;
|
||||
return (data);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief read the free data register
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval 8-bit value of the free data register
|
||||
*/
|
||||
uint8_t crc_free_data_register_read(void)
|
||||
{
|
||||
uint8_t fdata;
|
||||
fdata = (uint8_t)CRC_FDATA;
|
||||
return (fdata);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief write the free data register
|
||||
\param[in] free_data: specify 8-bit data
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void crc_free_data_register_write(uint8_t free_data)
|
||||
{
|
||||
CRC_FDATA = (uint32_t)free_data;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief write the initialization data register
|
||||
\param[in] init_data:specify 32-bit data
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void crc_init_data_register_write(uint32_t init_data)
|
||||
{
|
||||
CRC_IDATA = init_data;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the CRC input data function
|
||||
\param[in] data_reverse: specify input data reverse function
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CRC_INPUT_DATA_NOT: input data is not reversed
|
||||
\arg CRC_INPUT_DATA_BYTE: input data is reversed on 8 bits
|
||||
\arg CRC_INPUT_DATA_HALFWORD: input data is reversed on 16 bits
|
||||
\arg CRC_INPUT_DATA_WORD: input data is reversed on 32 bits
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void crc_input_data_reverse_config(uint32_t data_reverse)
|
||||
{
|
||||
CRC_CTL &= (uint32_t)(~CRC_CTL_REV_I);
|
||||
CRC_CTL |= (uint32_t)data_reverse;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the CRC size of polynomial function
|
||||
\param[in] poly_size: size of polynomial
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CRC_CTL_PS_32: 32-bit polynomial for CRC calculation
|
||||
\arg CRC_CTL_PS_16: 16-bit polynomial for CRC calculation
|
||||
\arg CRC_CTL_PS_8: 8-bit polynomial for CRC calculation
|
||||
\arg CRC_CTL_PS_7: 7-bit polynomial for CRC calculation
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void crc_polynomial_size_set(uint32_t poly_size)
|
||||
{
|
||||
CRC_CTL &= (uint32_t)(~CRC_CTL_PS);
|
||||
CRC_CTL |= (uint32_t)poly_size;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the CRC polynomial value function
|
||||
\param[in] poly: configurable polynomial value
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void crc_polynomial_set(uint32_t poly)
|
||||
{
|
||||
CRC_POLY &= (uint32_t)(~CRC_POLY_POLY);
|
||||
CRC_POLY = poly;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief CRC calculate single data
|
||||
\param[in] sdata: specify input data
|
||||
\param[in] data_format: input data format
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg INPUT_FORMAT_WORD: input data in word format
|
||||
\arg INPUT_FORMAT_HALFWORD: input data in half-word format
|
||||
\arg INPUT_FORMAT_BYTE: input data in byte format
|
||||
\param[out] none
|
||||
\retval CRC calculate value
|
||||
*/
|
||||
uint32_t crc_single_data_calculate(uint32_t sdata, uint8_t data_format)
|
||||
{
|
||||
if(INPUT_FORMAT_WORD == data_format) {
|
||||
REG32(CRC) = sdata;
|
||||
} else if(INPUT_FORMAT_HALFWORD == data_format) {
|
||||
REG16(CRC) = (uint16_t)sdata;
|
||||
} else if(INPUT_FORMAT_BYTE == data_format) {
|
||||
REG8(CRC) = (uint8_t)sdata;
|
||||
} else {
|
||||
}
|
||||
|
||||
return(CRC_DATA);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief CRC calculate a data array
|
||||
\param[in] array: pointer to the input data array
|
||||
\param[in] size: size of the array
|
||||
\param[in] data_format: input data format
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg INPUT_FORMAT_WORD: input data in word format
|
||||
\arg INPUT_FORMAT_HALFWORD: input data in half-word format
|
||||
\arg INPUT_FORMAT_BYTE: input data in byte format
|
||||
\param[out] none
|
||||
\retval CRC calculate value
|
||||
*/
|
||||
uint32_t crc_block_data_calculate(void *array, uint32_t size, uint8_t data_format)
|
||||
{
|
||||
uint8_t *data8;
|
||||
uint16_t *data16;
|
||||
uint32_t *data32;
|
||||
uint32_t index;
|
||||
|
||||
if(INPUT_FORMAT_WORD == data_format) {
|
||||
data32 = (uint32_t *)array;
|
||||
for(index = 0U; index < size; index++) {
|
||||
REG32(CRC) = data32[index];
|
||||
}
|
||||
} else if(INPUT_FORMAT_HALFWORD == data_format) {
|
||||
data16 = (uint16_t *)array;
|
||||
for(index = 0U; index < size; index++) {
|
||||
REG16(CRC) = data16[index];
|
||||
}
|
||||
} else {
|
||||
data8 = (uint8_t *)array;
|
||||
for(index = 0U; index < size; index++) {
|
||||
REG8(CRC) = data8[index];
|
||||
}
|
||||
}
|
||||
|
||||
return (CRC_DATA);
|
||||
}
|
||||
@@ -0,0 +1,390 @@
|
||||
/*!
|
||||
\file gd32h7xx_ctc.c
|
||||
\brief CTC driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_ctc.h"
|
||||
|
||||
#define CTC_FLAG_MASK ((uint32_t)0x00000700U)
|
||||
|
||||
/* CTC register bit offset */
|
||||
#define CTC_TRIMVALUE_OFFSET ((uint32_t)8U)
|
||||
#define CTC_TRIM_VALUE_OFFSET ((uint32_t)8U)
|
||||
#define CTC_REFCAP_OFFSET ((uint32_t)16U)
|
||||
#define CTC_LIMIT_VALUE_OFFSET ((uint32_t)16U)
|
||||
|
||||
/*!
|
||||
\brief reset CTC clock trim controller
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ctc_deinit(void)
|
||||
{
|
||||
/* reset CTC */
|
||||
rcu_periph_reset_enable(RCU_CTCRST);
|
||||
rcu_periph_reset_disable(RCU_CTCRST);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable CTC trim counter
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ctc_counter_enable(void)
|
||||
{
|
||||
CTC_CTL0 |= (uint32_t)CTC_CTL0_CNTEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable CTC trim counter
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ctc_counter_disable(void)
|
||||
{
|
||||
CTC_CTL0 &= (uint32_t)(~CTC_CTL0_CNTEN);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the IRC48M trim value
|
||||
\param[in] trim_value: 8-bit IRC48M trim value
|
||||
\arg 0x00 - 0x3F
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ctc_irc48m_trim_value_config(uint8_t trim_value)
|
||||
{
|
||||
/* clear TRIMVALUE bits */
|
||||
CTC_CTL0 &= (~(uint32_t)CTC_CTL0_TRIMVALUE);
|
||||
/* set TRIMVALUE bits */
|
||||
CTC_CTL0 |= ((uint32_t)trim_value << CTC_TRIM_VALUE_OFFSET);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief generate software reference source sync pulse
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ctc_software_refsource_pulse_generate(void)
|
||||
{
|
||||
CTC_CTL0 |= (uint32_t)CTC_CTL0_SWREFPUL;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure hardware automatically trim mode
|
||||
\param[in] hardmode:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CTC_HARDWARE_TRIM_MODE_ENABLE: hardware automatically trim mode enable
|
||||
\arg CTC_HARDWARE_TRIM_MODE_DISABLE: hardware automatically trim mode disable
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ctc_hardware_trim_mode_config(uint32_t hardmode)
|
||||
{
|
||||
CTC_CTL0 &= (uint32_t)(~CTC_CTL0_AUTOTRIM);
|
||||
CTC_CTL0 |= (uint32_t)hardmode;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure reference signal source polarity
|
||||
\param[in] polarity: reference signal source edge
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CTC_REFSOURCE_POLARITY_FALLING: reference signal source polarity is falling edge
|
||||
\arg CTC_REFSOURCE_POLARITY_RISING: reference signal source polarity is rising edge
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ctc_refsource_polarity_config(uint32_t polarity)
|
||||
{
|
||||
CTC_CTL1 &= (uint32_t)(~CTC_CTL1_REFPOL);
|
||||
CTC_CTL1 |= (uint32_t)polarity;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief select reference signal source
|
||||
\param[in] refs: reference signal source
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CTC_REFSOURCE_GPIO: GPIO is selected
|
||||
\arg CTC_REFSOURCE_LXTAL: LXTAL is selected
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ctc_refsource_signal_select(uint32_t refs)
|
||||
{
|
||||
CTC_CTL1 &= (uint32_t)(~CTC_CTL1_REFSEL);
|
||||
CTC_CTL1 |= (uint32_t)refs;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure reference signal source prescaler
|
||||
\param[in] prescaler: reference signal source prescaler
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CTC_REFSOURCE_PSC_OFF: reference signal not divided
|
||||
\arg CTC_REFSOURCE_PSC_DIV2: reference signal divided by 2
|
||||
\arg CTC_REFSOURCE_PSC_DIV4: reference signal divided by 4
|
||||
\arg CTC_REFSOURCE_PSC_DIV8: reference signal divided by 8
|
||||
\arg CTC_REFSOURCE_PSC_DIV16: reference signal divided by 16
|
||||
\arg CTC_REFSOURCE_PSC_DIV32: reference signal divided by 32
|
||||
\arg CTC_REFSOURCE_PSC_DIV64: reference signal divided by 64
|
||||
\arg CTC_REFSOURCE_PSC_DIV128: reference signal divided by 128
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ctc_refsource_prescaler_config(uint32_t prescaler)
|
||||
{
|
||||
CTC_CTL1 &= (uint32_t)(~CTC_CTL1_REFPSC);
|
||||
CTC_CTL1 |= (uint32_t)prescaler;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure clock trim base limit value
|
||||
\param[in] limit_value: 8-bit clock trim base limit value
|
||||
\arg 0x00 - 0xFF
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ctc_clock_limit_value_config(uint8_t limit_value)
|
||||
{
|
||||
CTC_CTL1 &= (uint32_t)(~CTC_CTL1_CKLIM);
|
||||
CTC_CTL1 |= (uint32_t)((uint32_t)limit_value << CTC_LIMIT_VALUE_OFFSET);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure CTC counter reload value
|
||||
\param[in] reload_value: 16-bit CTC counter reload value
|
||||
\arg 0x0000 - 0xFFFF
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ctc_counter_reload_value_config(uint16_t reload_value)
|
||||
{
|
||||
CTC_CTL1 &= (uint32_t)(~CTC_CTL1_RLVALUE);
|
||||
CTC_CTL1 |= (uint32_t)reload_value;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief read CTC counter capture value when reference sync pulse occurred
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval the 16-bit CTC counter capture value
|
||||
*/
|
||||
uint16_t ctc_counter_capture_value_read(void)
|
||||
{
|
||||
uint16_t capture_value = 0U;
|
||||
capture_value = (uint16_t)((CTC_STAT & CTC_STAT_REFCAP)>> CTC_REFCAP_OFFSET);
|
||||
return (capture_value);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief read CTC trim counter direction when reference sync pulse occurred
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
\arg SET: CTC trim counter direction is down-counting
|
||||
\arg RESET: CTC trim counter direction is up-counting
|
||||
*/
|
||||
FlagStatus ctc_counter_direction_read(void)
|
||||
{
|
||||
if(RESET != (CTC_STAT & CTC_STAT_REFDIR)){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief read CTC counter reload value
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval the 16-bit CTC counter reload value
|
||||
*/
|
||||
uint16_t ctc_counter_reload_value_read(void)
|
||||
{
|
||||
uint16_t reload_value = 0U;
|
||||
reload_value = (uint16_t)(CTC_CTL1 & CTC_CTL1_RLVALUE);
|
||||
return (reload_value);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief read the IRC48M trim value
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval the 8-bit IRC48M trim value
|
||||
*/
|
||||
uint8_t ctc_irc48m_trim_value_read(void)
|
||||
{
|
||||
uint8_t trim_value = 0U;
|
||||
trim_value = (uint8_t)((CTC_CTL0 & CTC_CTL0_TRIMVALUE) >> CTC_TRIMVALUE_OFFSET);
|
||||
return (trim_value);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get CTC flag
|
||||
\param[in] flag: the CTC flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CTC_FLAG_CKOK: clock trim OK flag
|
||||
\arg CTC_FLAG_CKWARN: clock trim warning flag
|
||||
\arg CTC_FLAG_ERR: error flag
|
||||
\arg CTC_FLAG_EREF: expect reference flag
|
||||
\arg CTC_FLAG_CKERR: clock trim error flag
|
||||
\arg CTC_FLAG_REFMISS: reference sync pulse miss flag
|
||||
\arg CTC_FLAG_TRIMERR: trim value error flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus ctc_flag_get(uint32_t flag)
|
||||
{
|
||||
if(RESET != (CTC_STAT & flag)){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear CTC flag
|
||||
\param[in] flag: the CTC flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CTC_FLAG_CKOK: clock trim OK flag
|
||||
\arg CTC_FLAG_CKWARN: clock trim warning flag
|
||||
\arg CTC_FLAG_ERR: error flag
|
||||
\arg CTC_FLAG_EREF: expect reference flag
|
||||
\arg CTC_FLAG_CKERR: clock trim error flag
|
||||
\arg CTC_FLAG_REFMISS: reference sync pulse miss flag
|
||||
\arg CTC_FLAG_TRIMERR: trim value error flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ctc_flag_clear(uint32_t flag)
|
||||
{
|
||||
if(RESET != (flag & CTC_FLAG_MASK)){
|
||||
CTC_INTC |= CTC_INTC_ERRIC;
|
||||
}else{
|
||||
CTC_INTC |= flag;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the CTC interrupt
|
||||
\param[in] interrupt: CTC interrupt enable source
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg CTC_INT_CKOK: clock trim OK interrupt
|
||||
\arg CTC_INT_CKWARN: clock trim warning interrupt
|
||||
\arg CTC_INT_ERR: error interrupt
|
||||
\arg CTC_INT_EREF: expect reference interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ctc_interrupt_enable(uint32_t interrupt)
|
||||
{
|
||||
CTC_CTL0 |= (uint32_t)interrupt;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the CTC interrupt
|
||||
\param[in] interrupt: CTC interrupt disable source
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg CTC_INT_CKOK: clock trim OK interrupt
|
||||
\arg CTC_INT_CKWARN: clock trim warning interrupt
|
||||
\arg CTC_INT_ERR: error interrupt
|
||||
\arg CTC_INT_EREF: expect reference interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ctc_interrupt_disable(uint32_t interrupt)
|
||||
{
|
||||
CTC_CTL0 &= (uint32_t)(~interrupt);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get CTC interrupt flag
|
||||
\param[in] int_flag: the CTC interrupt flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CTC_INT_FLAG_CKOK: clock trim OK interrupt flag
|
||||
\arg CTC_INT_FLAG_CKWARN: clock trim warning interrupt flag
|
||||
\arg CTC_INT_FLAG_ERR: error interrupt flag
|
||||
\arg CTC_INT_FLAG_EREF: expect reference interrupt flag
|
||||
\arg CTC_INT_FLAG_CKERR: clock trim error bit interrupt flag
|
||||
\arg CTC_INT_FLAG_REFMISS: reference sync pulse miss interrupt flag
|
||||
\arg CTC_INT_FLAG_TRIMERR: trim value error interrupt flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus ctc_interrupt_flag_get(uint32_t int_flag)
|
||||
{
|
||||
uint32_t interrupt_flag = 0U, intenable = 0U;
|
||||
|
||||
/* check whether the interrupt is enabled */
|
||||
if(RESET != (int_flag & CTC_FLAG_MASK)){
|
||||
intenable = CTC_CTL0 & CTC_CTL0_ERRIE;
|
||||
}else{
|
||||
intenable = CTC_CTL0 & int_flag;
|
||||
}
|
||||
|
||||
/* get interrupt flag status */
|
||||
interrupt_flag = CTC_STAT & int_flag;
|
||||
|
||||
if(interrupt_flag && intenable){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear CTC interrupt flag
|
||||
\param[in] int_flag: the CTC interrupt flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CTC_INT_FLAG_CKOK: clock trim OK interrupt flag
|
||||
\arg CTC_INT_FLAG_CKWARN: clock trim warning interrupt flag
|
||||
\arg CTC_INT_FLAG_ERR: error interrupt flag
|
||||
\arg CTC_INT_FLAG_EREF: expect reference interrupt flag
|
||||
\arg CTC_INT_FLAG_CKERR: clock trim error bit interrupt flag
|
||||
\arg CTC_INT_FLAG_REFMISS: reference sync pulse miss interrupt flag
|
||||
\arg CTC_INT_FLAG_TRIMERR: trim value error interrupt flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ctc_interrupt_flag_clear(uint32_t int_flag)
|
||||
{
|
||||
if(RESET != (int_flag & CTC_FLAG_MASK)){
|
||||
CTC_INTC |= CTC_INTC_ERRIC;
|
||||
}else{
|
||||
CTC_INTC |= int_flag;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,754 @@
|
||||
/*!
|
||||
\file gd32h7xx_dac.c
|
||||
\brief DAC driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_dac.h"
|
||||
|
||||
/* DAC register bit offset */
|
||||
#define OUT1_REG_OFFSET ((uint32_t)0x00000010U)
|
||||
#define DH_12BIT_OFFSET ((uint32_t)0x00000010U)
|
||||
#define DH_8BIT_OFFSET ((uint32_t)0x00000008U)
|
||||
|
||||
#define DAC_STAT_FLAG_MASK0 (DAC_FLAG_DDUDR0 | DAC_FLAG_DDUDR1 | DAC_FLAG_CALF0 | DAC_FLAG_CALF1 | DAC_FLAG_BWT0 | DAC_FLAG_BWT1)
|
||||
#define DAC_INT_EN_MASK0 (DAC_INT_DDUDR0 | DAC_INT_DDUDR1)
|
||||
#define DAC_INT_FLAG_MASK0 (DAC_INT_FLAG_DDUDR0 | DAC_INT_FLAG_DDUDR1)
|
||||
|
||||
/*!
|
||||
\brief deinitialize DAC
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_deinit(uint32_t dac_periph)
|
||||
{
|
||||
switch(dac_periph){
|
||||
case DAC0:
|
||||
/* reset DAC0 */
|
||||
rcu_periph_reset_enable(RCU_DACRST);
|
||||
rcu_periph_reset_disable(RCU_DACRST);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DAC
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[in] dac_out: DAC_OUTx(x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_enable(uint32_t dac_periph, uint8_t dac_out)
|
||||
{
|
||||
if(DAC_OUT0 == dac_out){
|
||||
DAC_CTL0(dac_periph) |= (uint32_t)DAC_CTL0_DEN0;
|
||||
}else if(DAC_OUT1 == dac_out){
|
||||
DAC_CTL0(dac_periph) |= (uint32_t)DAC_CTL0_DEN1;
|
||||
}else{
|
||||
/* illegal parameters */
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DAC
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[in] dac_out: DAC_OUTx(x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_disable(uint32_t dac_periph, uint8_t dac_out)
|
||||
{
|
||||
if(DAC_OUT0 == dac_out){
|
||||
DAC_CTL0(dac_periph) &= (uint32_t)(~DAC_CTL0_DEN0);
|
||||
}else if(DAC_OUT1 == dac_out){
|
||||
DAC_CTL0(dac_periph) &= (uint32_t)(~DAC_CTL0_DEN1);
|
||||
}else{
|
||||
/* illegal parameters */
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DAC DMA function
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[in] dac_out: DAC_OUTx(x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_dma_enable(uint32_t dac_periph, uint8_t dac_out)
|
||||
{
|
||||
if(DAC_OUT0 == dac_out){
|
||||
DAC_CTL0(dac_periph) |= (uint32_t)DAC_CTL0_DDMAEN0;
|
||||
}else if(DAC_OUT1 == dac_out){
|
||||
DAC_CTL0(dac_periph) |= (uint32_t)DAC_CTL0_DDMAEN1;
|
||||
}else{
|
||||
/* illegal parameters */
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DAC DMA function
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[in] dac_out: DAC_OUTx(x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_dma_disable(uint32_t dac_periph, uint8_t dac_out)
|
||||
{
|
||||
if(DAC_OUT0 == dac_out){
|
||||
DAC_CTL0(dac_periph) &= (uint32_t)(~DAC_CTL0_DDMAEN0);
|
||||
}else if(DAC_OUT1 == dac_out){
|
||||
DAC_CTL0(dac_periph) &= (uint32_t)(~DAC_CTL0_DDMAEN1);
|
||||
}else{
|
||||
/* illegal parameters */
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure DAC mode
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[in] dac_out: DAC_OUTx(x=0,1)
|
||||
\param[in] mode: DAC working mode
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg NORMAL_PIN_BUFFON: DAC_OUT_x work in normal mode and connect to external pin with buffer enable
|
||||
\arg NORMAL_PIN_PERIPHERAL_BUFFON: DAC_OUT_x work in normal mode and connect to external pin and on chip peripherals with buffer enable
|
||||
\arg NORMAL_PIN_BUFFOFF: DAC_OUT_x work in normal mode and connect to external pin with buffer disable
|
||||
\arg NORMAL_PIN_PERIPHERAL_BUFFOFF: DAC_OUT_x work in normal mode and connect to on chip peripherals with buffer disable
|
||||
\arg SAMPLEKEEP_PIN_BUFFON: DAC_OUT_x work in sample and keep mode and connect to external pin with buffer enable
|
||||
\arg SAMPLEKEEP_PIN_PERIPHERAL_BUFFON: DAC_OUT_x work in sample and keep mode and connect to external pin and on chip peripherals with buffer enable
|
||||
\arg SAMPLEKEEP_PIN_BUFFOFF: DAC_OUT_x work in sample and keep mode and connect to external pin and on chip peripherals with buffer enable
|
||||
\arg SAMPLEKEEP_PIN_PERIPHERAL_BUFFOFF: DAC_OUT_x work in sample and keep mode and connect to on chip peripherals with buffer disable
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_mode_config(uint32_t dac_periph, uint32_t dac_out, uint32_t mode)
|
||||
{
|
||||
if(DAC_OUT0 == dac_out){
|
||||
/* configure DAC0 mode */
|
||||
DAC_MDCR(dac_periph) &= ~(uint32_t)DAC_MDCR_MODE0;
|
||||
DAC_MDCR(dac_periph) |= mode;
|
||||
}else if(DAC_OUT1 == dac_out){
|
||||
/* configure DAC1 mode */
|
||||
DAC_MDCR(dac_periph) &= ~(uint32_t)DAC_MDCR_MODE1;
|
||||
DAC_MDCR(dac_periph) |= (mode << OUT1_REG_OFFSET);
|
||||
}else{
|
||||
/* illegal parameters */
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the DACx trimming value
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[in] dac_out: DAC_OUTx(x=0,1)
|
||||
\param[out] none
|
||||
\retval DACx trimming value
|
||||
*/
|
||||
uint32_t dac_trimming_value_get(uint32_t dac_periph, uint32_t dac_out)
|
||||
{
|
||||
uint32_t tmp = 0U;
|
||||
if(DAC_OUT0 == dac_out) {
|
||||
/* get the DAC_OUT_0 trimming value */
|
||||
tmp = DAC_CALR(dac_periph) & DAC_CALR_OTV0;
|
||||
} else if(DAC_OUT1 == dac_out) {
|
||||
/* get the DAC_OUT_1 trimming value */
|
||||
tmp = (DAC_CALR(dac_periph) & DAC_CALR_OTV1) >> OUT1_REG_OFFSET;
|
||||
} else {
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set the DACx trimming value
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[in] dac_out: DAC_OUTx(x=0,1)
|
||||
\param[in] trim_value: set new DAC trimming value
|
||||
\param[out] none
|
||||
*/
|
||||
void dac_trimming_value_set(uint32_t dac_periph, uint32_t dac_out, uint32_t trim_value)
|
||||
{
|
||||
uint32_t tmp = 0U;
|
||||
|
||||
/* get the trimming value */
|
||||
tmp = DAC_CALR(dac_periph);
|
||||
|
||||
if(DAC_OUT0 == dac_out) {
|
||||
/* set the DACx_OUT0 trimming value */
|
||||
tmp &= ~(uint32_t)DAC_CALR_OTV0;
|
||||
tmp |= (trim_value & DAC_CALR_OTV0);
|
||||
DAC_CALR(dac_periph) = tmp;
|
||||
}else if(DAC_OUT1 == dac_out){
|
||||
/* set the DACx_OUT1 trimming value */
|
||||
tmp &= ~(uint32_t)DAC_CALR_OTV1;
|
||||
tmp |= ((trim_value << OUT1_REG_OFFSET) & DAC_CALR_OTV1);
|
||||
DAC_CALR(dac_periph) = tmp;
|
||||
}else{
|
||||
/* illegal parameters */
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the DACx trimming
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[in] dac_out: DAC_OUTx(x=0,1)
|
||||
\param[out] none
|
||||
*/
|
||||
void dac_trimming_enable(uint32_t dac_periph, uint32_t dac_out)
|
||||
{
|
||||
if(DAC_OUT0 == dac_out){
|
||||
/* enable the DACx_OUT0 trimming */
|
||||
DAC_CTL0(dac_periph) |= DAC_CTL0_CALEN0;
|
||||
}else if(DAC_OUT1 == dac_out){
|
||||
/* enable the DACx_OUT1 trimming */
|
||||
DAC_CTL0(dac_periph) |= DAC_CTL0_CALEN1;
|
||||
}else{
|
||||
/* illegal parameters */
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get DAC output value
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[in] dac_out: DAC_OUTx(x=0,1)
|
||||
\param[out] none
|
||||
\retval DAC output data: 0~4095
|
||||
*/
|
||||
uint16_t dac_output_value_get(uint32_t dac_periph, uint8_t dac_out)
|
||||
{
|
||||
uint16_t data = 0U;
|
||||
|
||||
if(DAC_OUT0 == dac_out){
|
||||
/* store the DACx_OUT0 output value */
|
||||
data = (uint16_t)DAC_OUT0_DO(dac_periph);
|
||||
}else if(DAC_OUT1 == dac_out){
|
||||
/* store the DACx_OUT1 output value */
|
||||
data = (uint16_t)DAC_OUT1_DO(dac_periph);
|
||||
}else{
|
||||
/* illegal parameters */
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set DAC data holding register value
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[in] dac_out: DAC_OUTx(x=0,1)
|
||||
\param[in] dac_align: DAC data alignment mode
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DAC_ALIGN_12B_R: 12-bit right-aligned data
|
||||
\arg DAC_ALIGN_12B_L: 12-bit left-aligned data
|
||||
\arg DAC_ALIGN_8B_R: 8-bit right-aligned data
|
||||
\param[in] data: data to be loaded(0~4095)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_data_set(uint32_t dac_periph, uint8_t dac_out, uint32_t dac_align, uint16_t data)
|
||||
{
|
||||
/* DAC_OUT0 data alignment */
|
||||
if(DAC_OUT0 == dac_out){
|
||||
switch(dac_align){
|
||||
/* 12-bit right-aligned data */
|
||||
case DAC_ALIGN_12B_R:
|
||||
DAC_OUT0_R12DH(dac_periph) = data;
|
||||
break;
|
||||
/* 12-bit left-aligned data */
|
||||
case DAC_ALIGN_12B_L:
|
||||
DAC_OUT0_L12DH(dac_periph) = data;
|
||||
break;
|
||||
/* 8-bit right-aligned data */
|
||||
case DAC_ALIGN_8B_R:
|
||||
DAC_OUT0_R8DH(dac_periph) = data;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}else if(DAC_OUT1 == dac_out){
|
||||
/* DAC_OUT1 data alignment */
|
||||
switch(dac_align){
|
||||
/* 12-bit right-aligned data */
|
||||
case DAC_ALIGN_12B_R:
|
||||
DAC_OUT1_R12DH(dac_periph) = data;
|
||||
break;
|
||||
/* 12-bit left-aligned data */
|
||||
case DAC_ALIGN_12B_L:
|
||||
DAC_OUT1_L12DH(dac_periph) = data;
|
||||
break;
|
||||
/* 8-bit right-aligned data */
|
||||
case DAC_ALIGN_8B_R:
|
||||
DAC_OUT1_R8DH(dac_periph) = data;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
/* illegal parameters */
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DAC trigger
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[in] dac_out: DAC_OUTx(x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_trigger_enable(uint32_t dac_periph, uint8_t dac_out)
|
||||
{
|
||||
if(DAC_OUT0 == dac_out){
|
||||
DAC_CTL0(dac_periph) |= (uint32_t)DAC_CTL0_DTEN0;
|
||||
}else if(DAC_OUT1 == dac_out){
|
||||
DAC_CTL0(dac_periph) |= (uint32_t)DAC_CTL0_DTEN1;
|
||||
}else{
|
||||
/* illegal parameters */
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DAC trigger
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[in] dac_out: DAC_OUTx(x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_trigger_disable(uint32_t dac_periph, uint8_t dac_out)
|
||||
{
|
||||
if(DAC_OUT0 == dac_out){
|
||||
DAC_CTL0(dac_periph) &= (uint32_t)(~DAC_CTL0_DTEN0);
|
||||
}else if(DAC_OUT1 == dac_out){
|
||||
DAC_CTL0(dac_periph) &= (uint32_t)(~DAC_CTL0_DTEN1);
|
||||
}else{
|
||||
/* illegal parameters */
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure DAC trigger source
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[in] dac_out: DAC_OUTx(x=0,1)
|
||||
\param[in] triggersource: external trigger of DAC
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DAC_TRIGGER_EXTERNAL: external trigger selected by TRIGSEL
|
||||
\arg DAC_TRIGGER_SOFTWARE: software trigger
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_trigger_source_config(uint32_t dac_periph, uint8_t dac_out, uint32_t triggersource)
|
||||
{
|
||||
if(DAC_OUT0 == dac_out){
|
||||
/* configure DACx_OUT0 trigger source */
|
||||
DAC_CTL0(dac_periph) &= (uint32_t)(~DAC_CTL0_DTSEL0);
|
||||
DAC_CTL0(dac_periph) |= triggersource;
|
||||
}else if(DAC_OUT1 == dac_out){
|
||||
/* configure DACx_OUT1 trigger source */
|
||||
DAC_CTL0(dac_periph) &= (uint32_t)(~DAC_CTL0_DTSEL1);
|
||||
DAC_CTL0(dac_periph) |= (triggersource << OUT1_REG_OFFSET);
|
||||
}else{
|
||||
/* illegal parameters */
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DAC software trigger
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[in] dac_out: DAC_OUTx(x=0,1)
|
||||
\retval none
|
||||
*/
|
||||
void dac_software_trigger_enable(uint32_t dac_periph, uint8_t dac_out)
|
||||
{
|
||||
if(DAC_OUT0 == dac_out){
|
||||
DAC_SWT(dac_periph) |= (uint32_t)DAC_SWT_SWTR0;
|
||||
}else if(DAC_OUT1 == dac_out){
|
||||
DAC_SWT(dac_periph) |= (uint32_t)DAC_SWT_SWTR1;
|
||||
}else{
|
||||
/* illegal parameters */
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure DAC wave mode
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[in] dac_out: DAC_OUTx(x=0,1)
|
||||
\param[in] wave_mode: DAC wave mode
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DAC_WAVE_DISABLE: wave mode disable
|
||||
\arg DAC_WAVE_MODE_LFSR: LFSR noise mode
|
||||
\arg DAC_WAVE_MODE_TRIANGLE: triangle noise mode
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_wave_mode_config(uint32_t dac_periph, uint8_t dac_out, uint32_t wave_mode)
|
||||
{
|
||||
if(DAC_OUT0 == dac_out){
|
||||
/* configure DACx_OUT0 wave mode */
|
||||
DAC_CTL0(dac_periph) &= (uint32_t)(~DAC_CTL0_DWM0);
|
||||
DAC_CTL0(dac_periph) |= wave_mode;
|
||||
}else if(DAC_OUT1 == dac_out){
|
||||
/* configure DACx_OUT1 wave mode */
|
||||
DAC_CTL0(dac_periph) &= (uint32_t)(~DAC_CTL0_DWM1);
|
||||
DAC_CTL0(dac_periph) |= (wave_mode << OUT1_REG_OFFSET);
|
||||
}else{
|
||||
/* illegal parameters */
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure DAC LFSR noise mode
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[in] dac_out: DAC_OUTx(x=0,1)
|
||||
\param[in] unmask_bits: LFSR noise unmask bits
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DAC_LFSR_BIT0: unmask the LFSR bit0
|
||||
\arg DAC_LFSR_BITS1_0: unmask the LFSR bits[1:0]
|
||||
\arg DAC_LFSR_BITS2_0: unmask the LFSR bits[2:0]
|
||||
\arg DAC_LFSR_BITS3_0: unmask the LFSR bits[3:0]
|
||||
\arg DAC_LFSR_BITS4_0: unmask the LFSR bits[4:0]
|
||||
\arg DAC_LFSR_BITS5_0: unmask the LFSR bits[5:0]
|
||||
\arg DAC_LFSR_BITS6_0: unmask the LFSR bits[6:0]
|
||||
\arg DAC_LFSR_BITS7_0: unmask the LFSR bits[7:0]
|
||||
\arg DAC_LFSR_BITS8_0: unmask the LFSR bits[8:0]
|
||||
\arg DAC_LFSR_BITS9_0: unmask the LFSR bits[9:0]
|
||||
\arg DAC_LFSR_BITS10_0: unmask the LFSR bits[10:0]
|
||||
\arg DAC_LFSR_BITS11_0: unmask the LFSR bits[11:0]
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_lfsr_noise_config(uint32_t dac_periph, uint8_t dac_out, uint32_t unmask_bits)
|
||||
{
|
||||
if(DAC_OUT0 == dac_out){
|
||||
/* configure DACx_OUT0 LFSR noise mode */
|
||||
DAC_CTL0(dac_periph) &= (uint32_t)(~DAC_CTL0_DWBW0);
|
||||
DAC_CTL0(dac_periph) |= unmask_bits;
|
||||
}else if(DAC_OUT1 == dac_out){
|
||||
/* configure DACx_OUT1 LFSR noise mode */
|
||||
DAC_CTL0(dac_periph) &= (uint32_t)(~DAC_CTL0_DWBW1);
|
||||
DAC_CTL0(dac_periph) |= (unmask_bits << OUT1_REG_OFFSET);
|
||||
}else{
|
||||
/* illegal parameters */
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure DAC triangle noise mode
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[in] dac_out: DAC_OUTx(x=0,1)
|
||||
\param[in] amplitude: the amplitude of the triangle
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DAC_TRIANGLE_AMPLITUDE_1: triangle amplitude is 1
|
||||
\arg DAC_TRIANGLE_AMPLITUDE_3: triangle amplitude is 3
|
||||
\arg DAC_TRIANGLE_AMPLITUDE_7: triangle amplitude is 7
|
||||
\arg DAC_TRIANGLE_AMPLITUDE_15: triangle amplitude is 15
|
||||
\arg DAC_TRIANGLE_AMPLITUDE_31: triangle amplitude is 31
|
||||
\arg DAC_TRIANGLE_AMPLITUDE_63: triangle amplitude is 63
|
||||
\arg DAC_TRIANGLE_AMPLITUDE_127: triangle amplitude is 127
|
||||
\arg DAC_TRIANGLE_AMPLITUDE_255: triangle amplitude is 255
|
||||
\arg DAC_TRIANGLE_AMPLITUDE_511: triangle amplitude is 511
|
||||
\arg DAC_TRIANGLE_AMPLITUDE_1023: triangle amplitude is 1023
|
||||
\arg DAC_TRIANGLE_AMPLITUDE_2047: triangle amplitude is 2047
|
||||
\arg DAC_TRIANGLE_AMPLITUDE_4095: triangle amplitude is 4095
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_triangle_noise_config(uint32_t dac_periph, uint8_t dac_out, uint32_t amplitude)
|
||||
{
|
||||
if(DAC_OUT0 == dac_out){
|
||||
/* configure DACx_OUT0 triangle noise mode */
|
||||
DAC_CTL0(dac_periph) &= (uint32_t)(~DAC_CTL0_DWBW0);
|
||||
DAC_CTL0(dac_periph) |= amplitude;
|
||||
}else if(DAC_OUT1 == dac_out){
|
||||
/* configure DACx_OUT1 triangle noise mode */
|
||||
DAC_CTL0(dac_periph) &= (uint32_t)(~DAC_CTL0_DWBW1);
|
||||
DAC_CTL0(dac_periph) |= (amplitude << OUT1_REG_OFFSET);
|
||||
}else{
|
||||
/* illegal parameters */
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DAC concurrent mode
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_concurrent_enable(uint32_t dac_periph)
|
||||
{
|
||||
uint32_t ctl = 0U;
|
||||
|
||||
ctl = (uint32_t)(DAC_CTL0_DEN0 | DAC_CTL0_DEN1);
|
||||
DAC_CTL0(dac_periph) |= (uint32_t)ctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DAC concurrent mode
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_concurrent_disable(uint32_t dac_periph)
|
||||
{
|
||||
uint32_t ctl = 0U;
|
||||
|
||||
ctl = (uint32_t)(DAC_CTL0_DEN0 | DAC_CTL0_DEN1);
|
||||
DAC_CTL0(dac_periph) &= (uint32_t)(~ctl);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DAC concurrent software trigger
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_concurrent_software_trigger_enable(uint32_t dac_periph)
|
||||
{
|
||||
uint32_t swt = 0U;
|
||||
|
||||
swt = (uint32_t)(DAC_SWT_SWTR0 | DAC_SWT_SWTR1);
|
||||
DAC_SWT(dac_periph) |= (uint32_t)swt;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set DAC concurrent mode data holding register value
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[in] dac_align: DAC data alignment mode
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DAC_ALIGN_12B_R: 12-bit right-aligned data
|
||||
\arg DAC_ALIGN_12B_L: 12-bit left-aligned data
|
||||
\arg DAC_ALIGN_8B_R: 8-bit right-aligned data
|
||||
\param[in] data0: data to be loaded(0~4095)
|
||||
\param[in] data1: data to be loaded(0~4095)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_concurrent_data_set(uint32_t dac_periph, uint32_t dac_align, uint16_t data0, uint16_t data1)
|
||||
{
|
||||
uint32_t data = 0U;
|
||||
|
||||
switch(dac_align){
|
||||
/* 12-bit right-aligned data */
|
||||
case DAC_ALIGN_12B_R:
|
||||
data = (uint32_t)(((uint32_t)data1 << DH_12BIT_OFFSET) | data0);
|
||||
DACC_R12DH(dac_periph) = (uint32_t)data;
|
||||
break;
|
||||
/* 12-bit left-aligned data */
|
||||
case DAC_ALIGN_12B_L:
|
||||
data = (uint32_t)(((uint32_t)data1 << DH_12BIT_OFFSET) | data0);
|
||||
DACC_L12DH(dac_periph) = (uint32_t)data;
|
||||
break;
|
||||
/* 8-bit right-aligned data */
|
||||
case DAC_ALIGN_8B_R:
|
||||
data = (uint32_t)(((uint32_t)data1 << DH_8BIT_OFFSET) | data0);
|
||||
DACC_R8DH(dac_periph) = (uint32_t)data;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set DAC sample and keep time value
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[in] dac_out: DAC_OUTx(x=0,1)
|
||||
\param[in] sample_time: DAC sample time
|
||||
\param[in] keep_time: DAC keep time
|
||||
\param[in] refresh_time: DAC refresh time
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_sample_keep_mode_config(uint32_t dac_periph, uint32_t dac_out, uint32_t sample_time, uint32_t keep_time, uint32_t refresh_time)
|
||||
{
|
||||
uint32_t tmp = 0U;
|
||||
|
||||
if(DAC_OUT0 == dac_out){
|
||||
/* configure DACx_OUT0 Sample & Keep mode */
|
||||
DAC_SKSTR0(dac_periph) |= (sample_time & DAC_SKSTR0_TSAMP0);
|
||||
|
||||
tmp = (DAC_SKKTR(dac_periph) & ~(uint32_t)DAC_SKKTR_TKEEP0);
|
||||
DAC_SKKTR(dac_periph) = tmp | (keep_time & DAC_SKKTR_TKEEP0);
|
||||
|
||||
tmp = (DAC_SKRTR(dac_periph) & ~(uint32_t)DAC_SKRTR_TREF0);
|
||||
DAC_SKRTR(dac_periph) = tmp | (refresh_time & DAC_SKRTR_TREF0);
|
||||
}else if(DAC_OUT1 == dac_out){
|
||||
/* configure DACx_OUT1 Sample & Keep mode */
|
||||
DAC_SKSTR1(dac_periph) |= (sample_time & DAC_SKSTR1_TSAMP1);
|
||||
|
||||
tmp = (DAC_SKKTR(dac_periph) & ~(uint32_t)DAC_SKKTR_TKEEP1);
|
||||
DAC_SKKTR(dac_periph) = tmp | ((keep_time << 16) & DAC_SKKTR_TKEEP1);
|
||||
|
||||
tmp = (DAC_SKRTR(dac_periph) & ~(uint32_t)DAC_SKRTR_TREF1);
|
||||
DAC_SKRTR(dac_periph) = tmp | ((refresh_time << 16) & DAC_SKRTR_TREF1);
|
||||
}else{
|
||||
/* illegal parameters */
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get DAC flag
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[in] flag: the DAC status flags, only one parameter can be selected which is shown
|
||||
as below:
|
||||
\arg DAC_FLAG_DDUDR0: DACx_OUT0 DMA underrun flag
|
||||
\arg DAC_FLAG_CALF0: DACx_OUT0 calibration offset flag
|
||||
\arg DAC_FLAG_BWT0: DACx_OUT0 sample and keep wtire enable flag
|
||||
\arg DAC_FLAG_DDUDR1: DACx_OUT1 DMA underrun flag
|
||||
\arg DAC_FLAG_CALF1: DACx_OUT1 calibration offset flag
|
||||
\arg DAC_FLAG_BWT1: DACx_OUT1 sample and keep wtire enable flag
|
||||
\param[out] none
|
||||
\retval the state of DAC bit(SET or RESET)
|
||||
*/
|
||||
FlagStatus dac_flag_get(uint32_t dac_periph, uint32_t flag)
|
||||
{
|
||||
if(flag & DAC_STAT_FLAG_MASK0){
|
||||
/* check DAC_STAT0 flag */
|
||||
if(RESET != (DAC_STAT0(dac_periph) & flag)){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}else{
|
||||
/* illegal parameters */
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear DAC flag
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[in] flag: DAC flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DAC_FLAG_DDUDR0: DACx_OUT0 DMA underrun flag
|
||||
\arg DAC_FLAG_CALF0: DACx_OUT0 calibration offset flag
|
||||
\arg DAC_FLAG_BWT0: DACx_OUT0 sample and keep wtire enable flag
|
||||
\arg DAC_FLAG_DDUDR1: DACx_OUT1 DMA underrun flag
|
||||
\arg DAC_FLAG_CALF1: DACx_OUT1 calibration offset flag
|
||||
\arg DAC_FLAG_BWT1: DACx_OUT1 sample and keep wtire enable flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_flag_clear(uint32_t dac_periph, uint32_t flag)
|
||||
{
|
||||
if(flag & DAC_STAT_FLAG_MASK0){
|
||||
/* check DAC_STAT0 flag */
|
||||
DAC_STAT0(dac_periph) = (uint32_t)(flag & DAC_STAT_FLAG_MASK0);
|
||||
}else{
|
||||
/* illegal parameters */
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DAC interrupt
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[in] interrupt: the DAC interrupt
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DAC_INT_DDUDR0: DACx_OUT0 DMA underrun interrupt
|
||||
\arg DAC_INT_DDUDR1: DACx_OUT1 DMA underrun interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_interrupt_enable(uint32_t dac_periph, uint32_t interrupt)
|
||||
{
|
||||
if(interrupt & DAC_INT_EN_MASK0){
|
||||
/* enable underrun interrupt */
|
||||
DAC_CTL0(dac_periph) |= (uint32_t)(interrupt & DAC_INT_EN_MASK0);
|
||||
}else{
|
||||
/* illegal parameters */
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DAC interrupt
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[in] interrupt: the DAC interrupt
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DAC_INT_DDUDR0: DACx_OUT0 DMA underrun interrupt
|
||||
\arg DAC_INT_DDUDR1: DACx_OUT1 DMA underrun interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_interrupt_disable(uint32_t dac_periph, uint32_t interrupt)
|
||||
{
|
||||
if(interrupt & DAC_INT_EN_MASK0){
|
||||
/* disable underrun interrupt */
|
||||
DAC_CTL0(dac_periph) &= (uint32_t)(~(interrupt & DAC_INT_EN_MASK0));
|
||||
}else{
|
||||
/* illegal parameters */
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get DAC interrupt flag
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[in] int_flag: DAC interrupt flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DAC_INT_FLAG_DDUDR0: DACx_OUT0 DMA underrun interrupt flag
|
||||
\arg DAC_INT_FLAG_DDUDR1: DACx_OUT1 DMA underrun interrupt flag
|
||||
\param[out] none
|
||||
\retval the state of DAC interrupt flag(SET or RESET)
|
||||
*/
|
||||
FlagStatus dac_interrupt_flag_get(uint32_t dac_periph, uint32_t int_flag)
|
||||
{
|
||||
uint32_t reg1 = 0U, reg2 = 0U;
|
||||
|
||||
if(int_flag & DAC_INT_FLAG_MASK0){
|
||||
/* check underrun interrupt int_flag */
|
||||
reg1 = DAC_STAT0(dac_periph) & int_flag;
|
||||
reg2 = DAC_CTL0(dac_periph) & int_flag;
|
||||
}else{
|
||||
/* illegal parameters */
|
||||
}
|
||||
|
||||
/*get DAC interrupt flag status */
|
||||
if((RESET != reg1) && (RESET != reg2)){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear DAC interrupt flag
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[in] int_flag: DAC interrupt flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DAC_INT_FLAG_DDUDR0: DACx_OUT0 DMA underrun interrupt flag
|
||||
\arg DAC_INT_FLAG_DDUDR1: DACx_OUT1 DMA underrun interrupt flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_interrupt_flag_clear(uint32_t dac_periph, uint32_t int_flag)
|
||||
{
|
||||
/* clear underrun interrupt int_flag */
|
||||
if(int_flag & DAC_INT_FLAG_MASK0)
|
||||
{
|
||||
DAC_STAT0(dac_periph) = (uint32_t)int_flag;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
/*!
|
||||
\file gd32h7xx_dbg.c
|
||||
\brief DBG driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_dbg.h"
|
||||
|
||||
#define DBG_RESET_VAL ((uint32_t)0x00000000U) /*!< DBG reset value */
|
||||
|
||||
/*!
|
||||
\brief deinitialize the DBG
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dbg_deinit(void)
|
||||
{
|
||||
DBG_CTL0 = DBG_RESET_VAL;
|
||||
DBG_CTL1 = DBG_RESET_VAL;
|
||||
DBG_CTL2 = DBG_RESET_VAL;
|
||||
DBG_CTL3 = DBG_RESET_VAL;
|
||||
DBG_CTL4 = DBG_RESET_VAL;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief read DBG_ID code register
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval DBG_ID code
|
||||
*/
|
||||
uint32_t dbg_id_get(void)
|
||||
{
|
||||
return DBG_ID;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable low power behavior when the mcu is in debug mode
|
||||
\param[in] dbg_low_power:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DBG_LOW_POWER_SLEEP: keep debugger connection during sleep mode
|
||||
\arg DBG_LOW_POWER_DEEPSLEEP: keep debugger connection during deepsleep mode
|
||||
\arg DBG_LOW_POWER_STANDBY: keep debugger connection during standby mode
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dbg_low_power_enable(uint32_t dbg_low_power)
|
||||
{
|
||||
DBG_CTL0 |= dbg_low_power;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable low power behavior when the mcu is in debug mode
|
||||
\param[in] dbg_low_power:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DBG_LOW_POWER_SLEEP: donot keep debugger connection during sleep mode
|
||||
\arg DBG_LOW_POWER_DEEPSLEEP: donot keep debugger connection during deepsleep mode
|
||||
\arg DBG_LOW_POWER_STANDBY: donot keep debugger connection during standby mode
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dbg_low_power_disable(uint32_t dbg_low_power)
|
||||
{
|
||||
DBG_CTL0 &= ~dbg_low_power;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable trace pin assignment
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dbg_trace_pin_enable(void)
|
||||
{
|
||||
DBG_CTL0 |= DBG_CTL0_TRACECLKEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable trace pin assignment
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dbg_trace_pin_disable(void)
|
||||
{
|
||||
DBG_CTL0 &= ~DBG_CTL0_TRACECLKEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief trace pin mode selection
|
||||
\param[in] trace_mode:
|
||||
\arg TRACE_MODE_ASYNC: trace pin used for async mode
|
||||
\arg TRACE_MODE_SYNC_DATASIZE_1: trace pin used for sync mode and data size is 1
|
||||
\arg TRACE_MODE_SYNC_DATASIZE_2: trace pin used for sync mode and data size is 2
|
||||
\arg TRACE_MODE_SYNC_DATASIZE_4: trace pin used for sync mode and data size is 4
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dbg_trace_pin_mode_set(uint32_t trace_mode)
|
||||
{
|
||||
DBG_CTL0 &= ~DBG_CTL0_TRACE_MODE;
|
||||
DBG_CTL0 |= trace_mode;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief enable peripheral behavior when the mcu is in debug mode
|
||||
\param[in] dbg_periph: refer to dbg_periph_enum
|
||||
only one parameter can be selected which are shown as below:
|
||||
\arg DBG_FWDGT_HOLD: debug FWDGT kept when core is halted
|
||||
\arg DBG_WWDGT_HOLD: debug WWDGT kept when core is halted
|
||||
\arg DBG_TIMERx_HOLD (x=0,1,2,3,4,5,6,7,14,15,16,22,23,30,31,40,41,42,43,44,50,51): hold TIMERx counter when core is halted
|
||||
\arg DBG_I2Cx_HOLD (x=0,1,2,3): hold I2Cx smbus when core is halted
|
||||
\arg DBG_CANx_HOLD (x=0,1,2): hold CANx when core is halted
|
||||
\arg DBG_RTC_HOLD: hold RTC calendar and wakeup counter when core is halted
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dbg_periph_enable(dbg_periph_enum dbg_periph)
|
||||
{
|
||||
DBG_REG_VAL(dbg_periph) |= BIT(DBG_BIT_POS(dbg_periph));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable peripheral behavior when the mcu is in debug mode
|
||||
\param[in] dbg_periph: refer to dbg_periph_enum
|
||||
only one parameter can be selected which are shown as below:
|
||||
\arg DBG_FWDGT_HOLD: debug FWDGT kept when core is halted
|
||||
\arg DBG_WWDGT_HOLD: debug WWDGT kept when core is halted
|
||||
\arg DBG_TIMERx_HOLD (x=0,1,2,3,4,5,6,7,14,15,16,22,23,30,31,40,41,42,43,44,50,51): hold TIMERx counter when core is halted
|
||||
\arg DBG_I2Cx_HOLD (x=0,1,2,3): hold I2Cx smbus when core is halted
|
||||
\arg DBG_CANx_HOLD (x=0,1,2): hold CANx when core is halted
|
||||
\arg DBG_RTC_HOLD: hold RTC calendar and wakeup counter when core is halted
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dbg_periph_disable(dbg_periph_enum dbg_periph)
|
||||
{
|
||||
DBG_REG_VAL(dbg_periph) &= ~BIT(DBG_BIT_POS(dbg_periph));
|
||||
}
|
||||
@@ -0,0 +1,448 @@
|
||||
/*!
|
||||
\file gd32h7xx_dci.c
|
||||
\brief DCI driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_dci.h"
|
||||
|
||||
/*!
|
||||
\brief DCI deinit
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dci_deinit(void)
|
||||
{
|
||||
rcu_periph_reset_enable(RCU_DCIRST);
|
||||
rcu_periph_reset_disable(RCU_DCIRST);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize DCI registers
|
||||
\param[in] dci_struct: DCI parameter initialization structure
|
||||
members of the structure and the member values are shown as below:
|
||||
capture_mode : DCI_CAPTURE_MODE_CONTINUOUS, DCI_CAPTURE_MODE_SNAPSHOT
|
||||
colck_polarity : DCI_CK_POLARITY_FALLING, DCI_CK_POLARITY_RISING
|
||||
hsync_polarity : DCI_HSYNC_POLARITY_LOW, DCI_HSYNC_POLARITY_HIGH
|
||||
vsync_polarity : DCI_VSYNC_POLARITY_LOW, DCI_VSYNC_POLARITY_HIGH
|
||||
frame_rate : DCI_FRAME_RATE_ALL, DCI_FRAME_RATE_1_2, DCI_FRAME_RATE_1_4
|
||||
interface_format: DCI_INTERFACE_FORMAT_8BITS, DCI_INTERFACE_FORMAT_10BITS,
|
||||
DCI_INTERFACE_FORMAT_12BITS, DCI_INTERFACE_FORMAT_14BITS
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dci_init(dci_parameter_struct *dci_struct)
|
||||
{
|
||||
uint32_t reg = 0U;
|
||||
/* disable capture function and DCI */
|
||||
DCI_CTL &= ~(DCI_CTL_CAP | DCI_CTL_DCIEN);
|
||||
/* configure DCI parameter */
|
||||
reg |= dci_struct->capture_mode;
|
||||
reg |= dci_struct->clock_polarity;
|
||||
reg |= dci_struct->hsync_polarity;
|
||||
reg |= dci_struct->vsync_polarity;
|
||||
reg |= dci_struct->frame_rate;
|
||||
reg |= dci_struct->interface_format;
|
||||
|
||||
DCI_CTL = reg;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DCI function
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dci_enable(void)
|
||||
{
|
||||
DCI_CTL |= DCI_CTL_DCIEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DCI function
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dci_disable(void)
|
||||
{
|
||||
DCI_CTL &= ~DCI_CTL_DCIEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DCI capture
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dci_capture_enable(void)
|
||||
{
|
||||
DCI_CTL |= DCI_CTL_CAP;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DCI capture
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dci_capture_disable(void)
|
||||
{
|
||||
DCI_CTL &= ~DCI_CTL_CAP;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DCI external vsync function in CCIR progressive mode
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dci_external_vsync_enable(void)
|
||||
{
|
||||
DCI_CTL |= DCI_CTL_EVSEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DCI external vsync function in CCIR progressive mode
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dci_external_vsync_disable(void)
|
||||
{
|
||||
DCI_CTL &= ~DCI_CTL_EVSEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DCI automatic error correction function in CCIR interlaced mode
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dci_automatic_error_correction_enable(void)
|
||||
{
|
||||
DCI_CTL |= DCI_CTL_AECEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DCI automatic error correction function in CCIR interlaced mode
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dci_automatic_error_correction_disable(void)
|
||||
{
|
||||
DCI_CTL &= ~DCI_CTL_AECEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DCI jpeg mode
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dci_jpeg_enable(void)
|
||||
{
|
||||
DCI_CTL |= DCI_CTL_JM;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DCI jpeg mode
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dci_jpeg_disable(void)
|
||||
{
|
||||
DCI_CTL &= ~DCI_CTL_JM;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable cropping window function
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dci_crop_window_enable(void)
|
||||
{
|
||||
DCI_CTL |= DCI_CTL_WDEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable cropping window function
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dci_crop_window_disable(void)
|
||||
{
|
||||
DCI_CTL &= ~DCI_CTL_WDEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure DCI cropping window
|
||||
\param[in] start_x: window horizontal start position
|
||||
\param[in] start_y: window vertical start position
|
||||
\param[in] size_width: window horizontal size
|
||||
\param[in] size_height: window vertical size
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dci_crop_window_config(uint16_t start_x, uint16_t start_y, uint16_t size_width, uint16_t size_height)
|
||||
{
|
||||
DCI_CWSPOS = ((uint32_t)start_x | ((uint32_t)start_y << 16U));
|
||||
DCI_CWSZ = ((uint32_t)size_width | ((uint32_t)size_height << 16U));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable embedded synchronous mode
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dci_embedded_sync_enable(void)
|
||||
{
|
||||
DCI_CTL |= DCI_CTL_ESM;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disble embedded synchronous mode
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dci_embedded_sync_disable(void)
|
||||
{
|
||||
DCI_CTL &= ~DCI_CTL_ESM;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief CCIR mode enable
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dci_ccir_enable(void)
|
||||
{
|
||||
DCI_CTL |= DCI_CTL_CCEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief CCIR mode disable
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dci_ccir_disable(void)
|
||||
{
|
||||
DCI_CTL &= ~DCI_CTL_CCEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief CCIR mode select
|
||||
\param[in] ccir_mode: specify which mode to select
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CCIR_PROGRESSIVE_MODE: CCIR progressive mode
|
||||
\arg CCIR_INTERLACE_MODE: CCIR interlace mode
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dci_ccir_mode_select(uint32_t ccir_mode)
|
||||
{
|
||||
if(CCIR_INTERLACE_MODE == ccir_mode) {
|
||||
DCI_CTL |= DCI_CTL_CCMOD;
|
||||
} else {
|
||||
DCI_CTL &= ~DCI_CTL_CCMOD;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief config synchronous codes in embedded synchronous mode
|
||||
\param[in] frame_start: frame start code in embedded synchronous mode
|
||||
\param[in] line_start: line start code in embedded synchronous mode
|
||||
\param[in] line_end: line end code in embedded synchronous mode
|
||||
\param[in] frame_end: frame end code in embedded synchronous mode
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dci_sync_codes_config(uint8_t frame_start, uint8_t line_start, uint8_t line_end, uint8_t frame_end)
|
||||
{
|
||||
DCI_SC = ((uint32_t)frame_start | ((uint32_t)line_start << 8U) | \
|
||||
((uint32_t)line_end << 16U) | ((uint32_t)frame_end << 24U));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief config synchronous codes unmask in embedded synchronous mode
|
||||
\param[in] frame_start: frame start code unmask bits in embedded synchronous mode
|
||||
\param[in] line_start: line start code unmask bits in embedded synchronous mode
|
||||
\param[in] line_end: line end code unmask bits in embedded synchronous mode
|
||||
\param[in] frame_end: frame end code unmask bits in embedded synchronous mode
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dci_sync_codes_unmask_config(uint8_t frame_start, uint8_t line_start, uint8_t line_end, uint8_t frame_end)
|
||||
{
|
||||
DCI_SCUMSK = ((uint32_t)frame_start | ((uint32_t)line_start << 8U) | \
|
||||
((uint32_t)line_end << 16U) | ((uint32_t)frame_end << 24U));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief read DCI data register
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval data
|
||||
*/
|
||||
uint32_t dci_data_read(void)
|
||||
{
|
||||
return DCI_DATA;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get specified flag
|
||||
\param[in] flag: specify which flag to get
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DCI_FLAG_HS: HS line status
|
||||
\arg DCI_FLAG_VS: VS line status
|
||||
\arg DCI_FLAG_FV: FIFO valid
|
||||
\arg DCI_FLAG_EF: end of frame flag
|
||||
\arg DCI_FLAG_OVR: FIFO overrun flag
|
||||
\arg DCI_FLAG_ESE: embedded synchronous error flag
|
||||
\arg DCI_FLAG_VSYNC: vsync flag
|
||||
\arg DCI_FLAG_EL: end of line flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus dci_flag_get(uint32_t flag)
|
||||
{
|
||||
uint32_t stat = 0U;
|
||||
|
||||
if(flag >> 31U) {
|
||||
/* get flag status from DCI_STAT1 register */
|
||||
stat = DCI_STAT1;
|
||||
} else {
|
||||
/* get flag status from DCI_STAT0 register */
|
||||
stat = DCI_STAT0;
|
||||
}
|
||||
|
||||
if(flag & stat) {
|
||||
return SET;
|
||||
} else {
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable specified DCI interrupt
|
||||
\param[in] interrupt: specify which interrupt to enable
|
||||
one or more parameter can be selected which is shown as below:
|
||||
\arg DCI_INT_EF: end of frame interrupt
|
||||
\arg DCI_INT_OVR: FIFO overrun interrupt
|
||||
\arg DCI_INT_ESE: embedded synchronous error interrupt
|
||||
\arg DCI_INT_VSYNC: vsync interrupt
|
||||
\arg DCI_INT_EL: end of line interrupt
|
||||
\arg DCI_INT_F0: CCIR field 0 interrupt
|
||||
\arg DCI_INT_F1: CCIR field 1 interrupt
|
||||
\arg DCI_INT_COF: CCIR change of field interrupt
|
||||
\arg DCI_INT_CCE: CCIR error interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dci_interrupt_enable(uint32_t interrupt)
|
||||
{
|
||||
DCI_INTEN |= interrupt;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable specified DCI interrupt
|
||||
\param[in] interrupt: specify which interrupt to disable
|
||||
one or more parameter can be selected which is shown as below:
|
||||
\arg DCI_INT_EF: end of frame interrupt
|
||||
\arg DCI_INT_OVR: FIFO overrun interrupt
|
||||
\arg DCI_INT_ESE: embedded synchronous error interrupt
|
||||
\arg DCI_INT_VSYNC: vsync interrupt
|
||||
\arg DCI_INT_EL: end of line interrupt
|
||||
\arg DCI_INT_F0: CCIR field 0 interrupt
|
||||
\arg DCI_INT_F1: CCIR field 1 interrupt
|
||||
\arg DCI_INT_COF: CCIR change of field interrupt
|
||||
\arg DCI_INT_CCE: CCIR error interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dci_interrupt_disable(uint32_t interrupt)
|
||||
{
|
||||
DCI_INTEN &= ~interrupt;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get specified interrupt flag
|
||||
\param[in] int_flag: specify which flag to get
|
||||
one or more parameter can be selected which is shown as below:
|
||||
\arg DCI_INT_FLAG_EF: end of frame interrupt flag
|
||||
\arg DCI_INT_FLAG_OVR: FIFO overrun interrupt flag
|
||||
\arg DCI_INT_FLAG_ESE: embedded synchronous error interrupt flag
|
||||
\arg DCI_INT_FLAG_VSYNC: vsync interrupt flag
|
||||
\arg DCI_INT_FLAG_EL: end of line interrupt flag
|
||||
\arg DCI_INT_FLAG_F0: CCIR field 0 interrupt flag
|
||||
\arg DCI_INT_FLAG_F1: CCIR field 1 interrupt flag
|
||||
\arg DCI_INT_FLAG_COF: CCIR change of field interrupt flag
|
||||
\arg DCI_INT_FLAG_CCE: CCIR error interrupt flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus dci_interrupt_flag_get(uint32_t int_flag)
|
||||
{
|
||||
if(RESET == (DCI_INTF & int_flag)) {
|
||||
return RESET;
|
||||
} else {
|
||||
return SET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear specified interrupt flag
|
||||
\param[in] int_flag: specify which flag to clear
|
||||
one or more parameter can be selected which is shown as below:
|
||||
\arg DCI_INT_FLAG_EF: end of frame interrupt flag
|
||||
\arg DCI_INT_FLAG_OVR: FIFO overrun interrupt flag
|
||||
\arg DCI_INT_FLAG_ESE: embedded synchronous error interrupt flag
|
||||
\arg DCI_INT_FLAG_VSYNC: vsync interrupt flag
|
||||
\arg DCI_INT_FLAG_EL: end of line interrupt flag
|
||||
\arg DCI_INT_FLAG_COF: CCIR change of field interrupt flag
|
||||
\arg DCI_INT_FLAG_CCE: CCIR error interrupt flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dci_interrupt_flag_clear(uint32_t int_flag)
|
||||
{
|
||||
DCI_INTC |= int_flag;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,207 @@
|
||||
/*!
|
||||
\file gd32h7xx_edout.c
|
||||
\brief EDOUT driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_edout.h"
|
||||
|
||||
/* EDOUT register bit offset */
|
||||
#define LOC_LOCMAX_MIN ((uint32_t)0x0000000FU) /*!< LOCMAX fields minimum value */
|
||||
#define LOC_LOCMAX_STEP ((uint32_t)0x00000004U) /*!< LOCMAX fields step value */
|
||||
#define OCNT_PDC_OFFSET ((uint32_t)0x00000010U) /*!< bit offset of PDC in EDOUT_OCNT */
|
||||
#define ZCR_ZOWH_OFFSET ((uint32_t)0x00000010U) /*!< bit offset of ZOWH in EDOUT_ZCR */
|
||||
|
||||
/*!
|
||||
\brief deinitialize EDOUT
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void edout_deinit(void)
|
||||
{
|
||||
/* reset EDOUT */
|
||||
rcu_periph_reset_enable(RCU_EDOUTRST);
|
||||
rcu_periph_reset_disable(RCU_EDOUTRST);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize EDOUT
|
||||
\param[in] pol: the active polarity of the B-phase output signal selection
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EDOUT_POL_POSITIVE: active polarity is positive
|
||||
\arg EDOUT_POL_NEGATIVE: active polarity is negative
|
||||
\param[in] max_loc: (max_loc+1) must be a multiple of four between 16~65536 (e.g. 0x000F: The maximum location value is 16 (16=4*4))
|
||||
\param[in] cur_loc: current location value, 0~locmax (locmax is the LOCMAX bit fields value of EDOUT_LOC register)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void edout_init(uint32_t pol, uint32_t max_loc, uint32_t cur_loc)
|
||||
{
|
||||
/* reset polarity of the B-phase */
|
||||
EDOUT_CTL &= ~EDOUT_CTL_POL;
|
||||
/* set polarity of the B-phase */
|
||||
EDOUT_CTL = pol;
|
||||
|
||||
/* reset the maximum location value */
|
||||
EDOUT_LOC &= ~EDOUT_LOC_LOCMAX;
|
||||
/* check the maximum location value */
|
||||
if(LOC_LOCMAX_MIN > max_loc) {
|
||||
max_loc = LOC_LOCMAX_MIN;
|
||||
}
|
||||
while(0U != ((max_loc + 1U) % LOC_LOCMAX_STEP)) {
|
||||
max_loc++;
|
||||
}
|
||||
/* set the maximum location value */
|
||||
EDOUT_LOC = max_loc & EDOUT_LOC_LOCMAX;
|
||||
|
||||
/* reset the current location value */
|
||||
EDOUT_LCNT &= ~EDOUT_LCNT_LOCCNT;
|
||||
/* set the current location value */
|
||||
EDOUT_LCNT = cur_loc & EDOUT_LCNT_LOCCNT;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable EDOUT
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void edout_enable(void)
|
||||
{
|
||||
EDOUT_ENABLE |= EDOUT_ENABLE_EDOUTEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable EDOUT
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void edout_disable(void)
|
||||
{
|
||||
EDOUT_ENABLE &= ~EDOUT_ENABLE_EDOUTEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set B-phase active polarity
|
||||
\param[in] pol: the active polarity of the B-phase output signal selection
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EDOUT_POL_POSITIVE: active polarity is positive
|
||||
\arg EDOUT_POL_NEGATIVE: active polarity is negative
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void edout_polarity_config(uint32_t pol)
|
||||
{
|
||||
EDOUT_CTL = pol;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set the maximum location value for one rotation
|
||||
\param[in] max_loc: (max_loc+1) must be a multiple of four between 16~65536, e.g. 0x000F: The maximum location value is 16
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void edout_max_location_value_config(uint32_t max_loc)
|
||||
{
|
||||
EDOUT_LOC = max_loc & EDOUT_LOC_LOCMAX;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief update the output counter, used to set the phase difference and the number of edges for the next update period
|
||||
\param[in] num_edges: edge count, value range is -32768~32767, positive means clockwise rotation, negative means counter-clockwise rotation
|
||||
\param[in] phase_diff: phase difference, value range is 2~65535, in units of PCLK
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void edout_output_counter_update(int16_t num_edges, uint16_t phase_diff)
|
||||
{
|
||||
EDOUT_OCNT = ((uint32_t)num_edges & EDOUT_OCNT_EDGC) | ((uint32_t)phase_diff << OCNT_PDC_OFFSET);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set the current location value
|
||||
\param[in] cur_loc: current location value, 0~locmax (locmax is the LOCMAX bit fields value of EDOUT_LOC register)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void edout_current_location_config(uint32_t cur_loc)
|
||||
{
|
||||
EDOUT_LCNT = cur_loc & EDOUT_LCNT_LOCCNT;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the current location value
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval current location value, 0~locmax (locmax is the LOCMAX bit fields value of EDOUT_LOC register)
|
||||
*/
|
||||
uint16_t edout_current_location_get(void)
|
||||
{
|
||||
return (uint16_t)EDOUT_LCNT;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure Z-phase output mode
|
||||
\param[in] mode: Z-phase output mode
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EDOUT_Z_OUTPUT_MODE0: output according to the current location
|
||||
\arg EDOUT_Z_OUTPUT_MODE1: output according to the number of edges
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void edout_z_output_mode_config(uint32_t mode)
|
||||
{
|
||||
/* reset the Z-phase output mode */
|
||||
EDOUT_ZCR &= ~EDOUT_ZCR_ZOMD;
|
||||
/* set the Z-phase output mode */
|
||||
EDOUT_ZCR |= mode;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure Z-phase output start location and width
|
||||
\param[in] start_loc: Z-phase output start location,
|
||||
when Z-phase output mode select EDOUT_Z_OUTPUT_MODE0: 0~locmax (locmax is the LOCMAX bit fields value of EDOUT_LOC register)
|
||||
when Z-phase output mode select EDOUT_Z_OUTPUT_MODE1: 0~edges (edges is the EDGC bit fields value of EDOUT_OCNT register)
|
||||
\param[in] width: Z-phase output width
|
||||
when Z-phase output mode select EDOUT_Z_OUTPUT_MODE0: 0~(locmax - start_loc) (locmax is the LOCMAX bit fields value of EDOUT_LOC register)
|
||||
when Z-phase output mode select EDOUT_Z_OUTPUT_MODE1: 0~(edges - start_loc) (edges is the EDGC bit fields value of EDOUT_OCNT register)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void edout_z_output_start_loc_and_width_config(uint32_t start_loc, uint32_t width)
|
||||
{
|
||||
/* reset the Z-phase output start location and output width */
|
||||
EDOUT_ZCR &= ~(EDOUT_ZCR_ZOSP | EDOUT_ZCR_ZOWH);
|
||||
/* set the Z-phase output start location and output width */
|
||||
EDOUT_ZCR |= (start_loc & EDOUT_ZCR_ZOSP) | ((width << ZCR_ZOWH_OFFSET) & EDOUT_ZCR_ZOWH);
|
||||
}
|
||||
@@ -0,0 +1,512 @@
|
||||
/*!
|
||||
\file gd32h7xx_efuse.c
|
||||
\brief EFUSE driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_efuse.h"
|
||||
|
||||
/* FMC register bit offset */
|
||||
#define EFUSE_CTL_AES_KEY_CRC_OFFSET ((uint32_t)0x00000018U) /*!< bit offset of AES_KEY_CRC in EFUSE_CTL register*/
|
||||
#define EFUSE_CTL_MPVEN_OFFSET ((uint32_t)0x0000000FU) /*!< bit offset of MPVEN in EFUSE_CTL register*/
|
||||
#define EFUSE_STAT_LDO_RDY_OFFSET ((uint32_t)0x00000004U) /*!< bit offset of LDO_RDY in EFUSE_STAT register*/
|
||||
#define EFUSE_ADDR_EFSIZE_OFFSET ((uint32_t)0x0000000AU) /*!< EFSIZE OFFSET in register EFUSE_ADDR */
|
||||
|
||||
#define EFUSE_TIMEOUT ((uint32_t)0x0000FFFFU) /*!< EFUSE operation timeout value */
|
||||
#define USER_CTL_NDBG0 BIT(8) /*!< debug mode setting bit0 in register EFUSE_USER_CTL */
|
||||
|
||||
static uint32_t para_start_efaddr[EFUSE_PARA_CNT] = {USER_CTL_EFADDR, MCU_RESERVED_EFADDR, DP_EFADDR, AES_KEY_EFADDR, USER_DATA_EFADDR};
|
||||
static uint32_t para_reg_start_addr[EFUSE_PARA_CNT] = {EFUSE_USER_CTL_REG_ADDR, EFUSE_MCU_RSV_REG_ADDR, EFUSE_DP_REG_ADDR, EFUSE_AES_KEY_REG_ADDR, EFUSE_USER_DATA_REG_ADDR};
|
||||
static efuse_state_enum efuse_ready_wait(uint32_t efuse_flag, uint32_t timeout);
|
||||
|
||||
/*!
|
||||
\brief read system parameters from EFUSE macro to registers
|
||||
\param[in] ef_addr: start address of the system parameters to be read
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg USER_CTL_EFADDR: user control parameter start address
|
||||
\arg MCU_RESERVED_EFADDR: MCU reserved parameter start address
|
||||
\arg DP_EFADDR: debug password parameter start address
|
||||
\arg USER_DATA_EFADDR: user data parameter start address
|
||||
\param[in] size: size of the system parameters to be read
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg USER_CTL_SIZE: user control parameter size
|
||||
\arg MCU_RESERVED_SIZE: MCU reserved parameter size
|
||||
\arg DP_SIZE: debug password parameter size
|
||||
\arg USER_DATA_SIZE: user data parameter size
|
||||
\param[out] buf: the buffer for data read from EFUSE macro
|
||||
\retval ErrStatus: ERROR or SUCCESS
|
||||
*/
|
||||
|
||||
ErrStatus efuse_read(uint32_t ef_addr, uint32_t size, uint32_t buf[])
|
||||
{
|
||||
ErrStatus status = SUCCESS;
|
||||
uint32_t timeout = EFUSE_TIMEOUT;
|
||||
efuse_state_enum efuse_state;
|
||||
uint32_t reg_addr = 0U;
|
||||
uint32_t i = 0U;
|
||||
uint32_t number = 0U;
|
||||
switch(ef_addr) {
|
||||
case USER_CTL_EFADDR:
|
||||
status = ERROR;
|
||||
break;
|
||||
case MCU_RESERVED_EFADDR:
|
||||
/* read MCU reserved data */
|
||||
reg_addr = EFUSE_MCU_RSV_REG_ADDR;
|
||||
number = 1U;
|
||||
break;
|
||||
case DP_EFADDR:
|
||||
/* read debug password */
|
||||
if(RESET != (EFUSE_USER_CTL & EFUSE_USER_CTL_DPLK)) {
|
||||
if(RESET != (EFUSE_USER_CTL & EFUSE_USER_CTL_JTAGNSW)) {
|
||||
if((RESET != (EFUSE_USER_CTL & USER_CTL_NDBG0))) {
|
||||
status = ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(SUCCESS == status) {
|
||||
reg_addr = EFUSE_DP_REG_ADDR;
|
||||
number = 2U;
|
||||
}
|
||||
break;
|
||||
case USER_DATA_EFADDR:
|
||||
/* read user data */
|
||||
reg_addr = EFUSE_USER_DATA_REG_ADDR;
|
||||
number = 4U;
|
||||
break;
|
||||
default:
|
||||
status = ERROR;
|
||||
break;
|
||||
}
|
||||
if(ERROR == status) {
|
||||
return status;
|
||||
}
|
||||
/* clear the RDIF bit if it is SET */
|
||||
efuse_flag_clear(EFUSE_FLAG_READ_COMPLETE_CLR);
|
||||
/* reset the EFRW bit in EFUSE_CTL */
|
||||
EFUSE_CTL &= ~EFUSE_CTL_EFRW;
|
||||
/* write the desired efuse address and size to the EFUSE_ADDR register */
|
||||
EFUSE_ADDR = (uint32_t)((size << EFUSE_ADDR_EFSIZE_OFFSET) | ef_addr);
|
||||
/* start array read EFUSE operation */
|
||||
EFUSE_CTL |= EFUSE_CTL_EFSTR;
|
||||
/* wait for the operation to complete */
|
||||
efuse_state = efuse_ready_wait(EFUSE_FLAG_READ_COMPLETE, timeout);
|
||||
if(EFUSE_READY != efuse_state) {
|
||||
status = ERROR;
|
||||
}
|
||||
/* read EFUSE register */
|
||||
for(i = 0U; i < number; i++) {
|
||||
buf[i] = REG32(reg_addr + (4U * i));
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief program register values to EFUSE macro system parameters
|
||||
\param[in] ef_addr: the EFUSE address to be programmed, pgm_addr cannot exceed 384, and must be an integral multiple of 8
|
||||
\param[in] size: byte count to program, (1~16)
|
||||
\param[in] buf: the buffer for data written to EFUSE macro
|
||||
\param[out] none
|
||||
\retval ErrStatus: ERROR or SUCCESS
|
||||
*/
|
||||
ErrStatus efuse_write(uint32_t ef_addr, uint32_t size, uint8_t *buf)
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t reg_addr;
|
||||
uint32_t byte_offset_in_reg;
|
||||
uint32_t cnt;
|
||||
ErrStatus status = SUCCESS;
|
||||
uint32_t para_index;
|
||||
uint32_t tmp_buf_8;
|
||||
uint32_t buf_addr;
|
||||
uint32_t timeout = EFUSE_TIMEOUT;
|
||||
efuse_state_enum efuse_state;
|
||||
if(0U == size) {
|
||||
return ERROR;
|
||||
}
|
||||
/* the address should be on byte address boundary */
|
||||
if(ef_addr % 8U) {
|
||||
return ERROR;
|
||||
}
|
||||
if(MAX_EFADDR < ef_addr) {
|
||||
return ERROR;
|
||||
}
|
||||
for(i = EFUSE_PARA_CNT; i > 0U; i--) {
|
||||
if(ef_addr >= para_start_efaddr[i - 1U]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* get the index of parameter to be programmed */
|
||||
para_index = i - 1U;
|
||||
/* program range should not over parameter boundary */
|
||||
if(para_index == (EFUSE_PARA_CNT - 1U)) {
|
||||
if((ef_addr + size * 8U - 1U) > MAX_EFADDR) {
|
||||
return ERROR;
|
||||
}
|
||||
} else {
|
||||
if((ef_addr + size * 8U - 1U) > para_start_efaddr[para_index + 1U]) {
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
if((AES_KEY_IDX == para_index) && (AES_KEY_SIZE != size)) {
|
||||
/* AES key should be programmed in one time */
|
||||
return ERROR;
|
||||
}
|
||||
reg_addr = (unsigned int)para_reg_start_addr[para_index] + (ef_addr - para_start_efaddr[para_index]) / 32U * 4U;
|
||||
byte_offset_in_reg = ((ef_addr - para_start_efaddr[para_index]) / 8U) % 4U;
|
||||
/* clear the PGIF bit if it is SET */
|
||||
efuse_flag_clear(EFUSE_FLAG_PROGRAM_COMPLETE_CLR);
|
||||
/* set the EFRW bit in EFUSE_CTL */
|
||||
EFUSE_CTL |= EFUSE_CTL_EFRW;
|
||||
/* write the desired efuse address and size to the EFUSE_ADDR register */
|
||||
EFUSE_ADDR = (uint32_t)((size << EFUSE_ADDR_EFSIZE_OFFSET) | ef_addr);
|
||||
buf_addr = (uint32_t)buf;
|
||||
|
||||
while(size) {
|
||||
if((0U != byte_offset_in_reg) || ((0U == byte_offset_in_reg) && (size < 4U))) {
|
||||
cnt = size < (4U - byte_offset_in_reg) ? size : 4U - byte_offset_in_reg;
|
||||
for(i = 0U; i < cnt; i++) {
|
||||
tmp_buf_8 = buf_addr;
|
||||
/* write the data to the corresponding register */
|
||||
tmp_buf_8 += i;
|
||||
REG32(reg_addr) |= (((uint32_t)(*(uint8_t *)(tmp_buf_8))) << ((byte_offset_in_reg + i) * 8U));
|
||||
}
|
||||
size -= cnt;
|
||||
reg_addr += 4U;
|
||||
byte_offset_in_reg = 0U;
|
||||
buf_addr += cnt;
|
||||
} else {
|
||||
cnt = size / 4U;
|
||||
for(i = 0U; i < cnt; i++) {
|
||||
tmp_buf_8 = buf_addr;
|
||||
/* write the data to the corresponding register */
|
||||
tmp_buf_8 += (i * 4U);
|
||||
REG32(reg_addr) = (uint32_t)(*(uint32_t *)(tmp_buf_8));
|
||||
reg_addr += 4U;
|
||||
}
|
||||
size -= cnt * 4U;
|
||||
buf_addr += cnt * 4U;
|
||||
}
|
||||
}
|
||||
/* start EFUSE program operation */
|
||||
EFUSE_CTL |= EFUSE_CTL_EFSTR;
|
||||
/* wait for the operation to complete */
|
||||
efuse_state = efuse_ready_wait(EFUSE_FLAG_PROGRAM_COMPLETE, timeout);
|
||||
if(EFUSE_READY != efuse_state) {
|
||||
status = ERROR;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief program all user control parameters
|
||||
\param[in] buf: the buffer of data written to efuse
|
||||
\param[out] none
|
||||
\retval ErrStatus: ERROR or SUCCESS
|
||||
*/
|
||||
ErrStatus efuse_user_control_write(uint8_t *buf)
|
||||
{
|
||||
return efuse_write(USER_CTL_EFADDR, USER_CTL_SIZE, buf);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief program all MCU reserved parameters
|
||||
\param[in] buf: the buffer of data written to efuse
|
||||
\param[out] none
|
||||
\retval ErrStatus: ERROR or SUCCESS
|
||||
*/
|
||||
ErrStatus efuse_mcu_reserved_write(uint8_t *buf)
|
||||
{
|
||||
return efuse_write(MCU_RESERVED_EFADDR, MCU_RESERVED_SIZE, buf);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief program all debug password parameters
|
||||
\param[in] buf: the buffer of data written to efuse
|
||||
\param[out] none
|
||||
\retval ErrStatus: ERROR or SUCCESS
|
||||
*/
|
||||
ErrStatus efuse_dp_write(uint8_t *buf)
|
||||
{
|
||||
return efuse_write(DP_EFADDR, DP_SIZE, buf);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief program all AES key parameters
|
||||
\param[in] buf: the buffer of data written to efuse
|
||||
\param[out] none
|
||||
\retval ErrStatus: ERROR or SUCCESS
|
||||
*/
|
||||
ErrStatus efuse_aes_key_write(uint8_t *buf)
|
||||
{
|
||||
return efuse_write(AES_KEY_EFADDR, AES_KEY_SIZE, buf);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief program all user data parameters
|
||||
\param[in] buf: the buffer of data written to efuse
|
||||
\param[out] none
|
||||
\retval ErrStatus: ERROR or SUCCESS
|
||||
*/
|
||||
ErrStatus efuse_user_data_write(uint8_t *buf)
|
||||
{
|
||||
return efuse_write(USER_DATA_EFADDR, USER_DATA_SIZE, buf);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get 8-bits CRC calculation result value of AES key
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval 8-bits CRC calculation result value of AES key
|
||||
*/
|
||||
uint8_t efuse_aes_key_crc_get(void)
|
||||
{
|
||||
return (uint8_t)((EFUSE_CTL & EFUSE_CTL_AES_KEY_CRC) >> EFUSE_CTL_AES_KEY_CRC_OFFSET);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable monitor program voltage function
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void efuse_monitor_program_voltage_enable(void)
|
||||
{
|
||||
uint32_t ctl_reg;
|
||||
ctl_reg = EFUSE_CTL;
|
||||
/* enable monitor program voltage function */
|
||||
ctl_reg |= EFUSE_CTL_MPVEN;
|
||||
EFUSE_CTL = ctl_reg;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable monitor program voltage function
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void efuse_monitor_program_voltage_disable(void)
|
||||
{
|
||||
uint32_t ctl_reg;
|
||||
ctl_reg = EFUSE_CTL;
|
||||
/* disable monitor program voltage function */
|
||||
ctl_reg &= ~EFUSE_CTL_MPVEN;
|
||||
EFUSE_CTL = ctl_reg;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get monitor program voltage function
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus efuse_monitor_program_voltage_get(void)
|
||||
{
|
||||
FlagStatus mpven_state = RESET;
|
||||
|
||||
if(EFUSE_CTL_MPVEN == (uint32_t)(EFUSE_CTL & EFUSE_CTL_MPVEN)) {
|
||||
mpven_state = SET;
|
||||
} else {
|
||||
mpven_state = RESET;
|
||||
}
|
||||
return mpven_state;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get ldo ready signal
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus efuse_ldo_ready_get(void)
|
||||
{
|
||||
FlagStatus ldo_ready_state = RESET;
|
||||
|
||||
if(EFUSE_STAT_LDO_RDY == (uint32_t)(EFUSE_STAT & EFUSE_STAT_LDO_RDY)) {
|
||||
ldo_ready_state = SET;
|
||||
} else {
|
||||
ldo_ready_state = RESET;
|
||||
}
|
||||
return ldo_ready_state;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief check EFUSE flag is set or not
|
||||
\param[in] flag: specifies to get a flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EFUSE_FLAG_ILLEGAL_ACCESS_ERR: illegal access error flag
|
||||
\arg EFUSE_FLAG_PROGRAM_COMPLETE: programming operation completion flag
|
||||
\arg EFUSE_FLAG_READ_COMPLETE: read operation completion flag
|
||||
\arg EFUSE_FLAG_PROGRAM_VOLTAGE_ERR: program voltage setting error flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus efuse_flag_get(uint32_t flag)
|
||||
{
|
||||
if(EFUSE_STAT & (uint32_t)flag) {
|
||||
return SET;
|
||||
} else {
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear EFUSE pending flag
|
||||
\param[in] flag: specifies to clear a flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EFUSE_FLAG_ILLEGAL_ACCESS_ERR_CLR: clear illegal access error flag
|
||||
\arg EFUSE_FLAG_PROGRAM_COMPLETE_CLR: clear programming operation completion flag
|
||||
\arg EFUSE_FLAG_READ_COMPLETE_CLR: clear read operation completion flag
|
||||
\arg EFUSE_FLAG_PROGRAM_VOLTAGE_ERR_CLR: clear program voltage setting error interrupt flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void efuse_flag_clear(uint32_t flag)
|
||||
{
|
||||
EFUSE_STATC |= (uint32_t)flag;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable EFUSE interrupt
|
||||
\param[in] interrupt: specifies an interrupt to enbale
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EFUSE_INT_ILLEGAL_ACCESS_ERR: illegal access error interrupt
|
||||
\arg EFUSE_INT_PROGRAM_COMPLETE: programming operation completion interrupt
|
||||
\arg EFUSE_INT_READ_COMPLETE: read operation completion interrupt
|
||||
\arg EFUSE_INT_PROGRAM_VOLTAGE_ERR: program voltage setting error interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void efuse_interrupt_enable(uint32_t interrupt)
|
||||
{
|
||||
EFUSE_CTL = (uint32_t)interrupt;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable EFUSE interrupt
|
||||
\param[in] interrupt: specifies an interrupt to disbale
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EFUSE_INT_ILLEGAL_ACCESS_ERR: illegal access error interrupt
|
||||
\arg EFUSE_INT_PROGRAM_COMPLETE: programming operation completion interrupt
|
||||
\arg EFUSE_INT_READ_COMPLETE: read operation completion interrupt
|
||||
\arg EFUSE_INT_PROGRAM_VOLTAGE_ERR: program voltage setting error interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void efuse_interrupt_disable(uint32_t interrupt)
|
||||
{
|
||||
EFUSE_CTL &= ~(uint32_t)interrupt;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief check EFUSE interrupt flag is set or not
|
||||
\param[in] int_flag: specifies to get a flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EFUSE_INT_FLAG_ILLEGAL_ACCESS_ERR: illegal access error interrupt
|
||||
\arg EFUSE_INT_FLAG_PROGRAM_COMPLETE: programming operation completion interrupt
|
||||
\arg EFUSE_INT_FLAG_READ_COMPLETE: read operation completion interrupt
|
||||
\arg EFUSE_INT_FLAG_PROGRAM_VOLTAGE_ERR: program voltage setting error interrupt
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus efuse_interrupt_flag_get(efuse_interrupt_flag_enum int_flag)
|
||||
{
|
||||
uint32_t intenable = 0U, flagstatus = 0U;
|
||||
/* get the interrupt enable bit status */
|
||||
intenable = (EFUSE_REG_VAL(int_flag) & BIT(EFUSE_BIT_POS(int_flag)));
|
||||
/* get the corresponding flag bit status */
|
||||
flagstatus = (EFUSE_REG_VAL2(int_flag) & BIT(EFUSE_BIT_POS2(int_flag)));
|
||||
|
||||
if(flagstatus && intenable) {
|
||||
return SET;
|
||||
} else {
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear EFUSE pending interrupt flag
|
||||
\param[in] int_flag: specifies to clear a flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EFUSE_INT_FLAG_ILLEGAL_ACCESS_ERR_CLR: clear illegal access error interrupt flag
|
||||
\arg EFUSE_INT_FLAG_PROGRAM_COMPLETE_CLR: clear programming operation completion interrupt flag
|
||||
\arg EFUSE_INT_FLAG_READ_COMPLETE_CLR: clear operation completion interrupt flag
|
||||
\arg EFUSE_INT_FLAG_PROGRAM_VOLTAGE_ERR_CLR: clear program voltage setting error interrupt flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void efuse_interrupt_flag_clear(uint32_t int_flag)
|
||||
{
|
||||
EFUSE_STATC |= (uint32_t)int_flag;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief check whether EFUSE is ready or not
|
||||
\param[in] flag:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EFUSE_FLAG_ILLEGAL_ACCESS_ERR: illegal access error flag
|
||||
\arg EFUSE_FLAG_PROGRAM_COMPLETE: programming operation completion flag
|
||||
\arg EFUSE_FLAG_READ_COMPLETE: read operation completion flag
|
||||
\arg EFUSE_FLAG_PROGRAM_VOLTAGE_ERR: program voltage setting error flag
|
||||
\param[out] none
|
||||
\retval state of EFUSE
|
||||
\arg EFUSE_READY: EFUSE operation has been completed
|
||||
\arg EFUSE_BUSY: EFUSE operation is in progress
|
||||
\arg EFUSE_IAERR: illegal access error
|
||||
\arg EFUSE_PVERR: program voltage setting error
|
||||
\arg EFUSE_TOERR: EFUSE timeout error
|
||||
*/
|
||||
static efuse_state_enum efuse_ready_wait(uint32_t efuse_flag, uint32_t timeout)
|
||||
{
|
||||
efuse_state_enum efuse_state = EFUSE_BUSY;
|
||||
|
||||
/* wait for EFUSE ready */
|
||||
do {
|
||||
/* get EFUSE flag set or not */
|
||||
if(EFUSE_STAT & (uint32_t)efuse_flag) {
|
||||
efuse_state = EFUSE_READY;
|
||||
} else if(EFUSE_STAT & EFUSE_STAT_IAERRIF) {
|
||||
efuse_state = EFUSE_IAERR;
|
||||
} else if(EFUSE_STAT & EFUSE_STAT_PVIF) {
|
||||
efuse_state = EFUSE_PVERR;
|
||||
} else {
|
||||
/* illegal parameters */
|
||||
}
|
||||
timeout--;
|
||||
} while((EFUSE_BUSY == efuse_state) && (0U != timeout));
|
||||
|
||||
if(EFUSE_BUSY == efuse_state) {
|
||||
efuse_state = EFUSE_TOERR;
|
||||
}
|
||||
|
||||
/* return the EFUSE state */
|
||||
return efuse_state;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,942 @@
|
||||
/*!
|
||||
\file gd32h7xx_exmc.c
|
||||
\brief EXMC driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 <stdlib.h>
|
||||
#include "gd32h7xx_exmc.h"
|
||||
|
||||
/* EXMC bank0 register reset value */
|
||||
#define BANK0_SNCTL_RESET ((uint32_t)0x000030DAU) /* SNCTL register reset value */
|
||||
#define BANK0_SNTCFG_RESET ((uint32_t)0x0FFFFFFFU) /* SNTCFG register reset value */
|
||||
#define BANK0_SNWTCFG_RESET ((uint32_t)0x0FFFFFFFU) /* SNWTCFG register reset value */
|
||||
|
||||
/* EXMC bank2 register reset value */
|
||||
#define BANK2_NCTL_RESET ((uint32_t)0x00000008U) /* NCTL register reset value */
|
||||
#define BANK2_NINTEN_RESET ((uint32_t)0x00000042U) /* NINTEN register reset value */
|
||||
#define BANK2_NCTCFG_RESET ((uint32_t)0xFFFFFFFFU) /* NCTCFG register reset value */
|
||||
#define BANK2_NATCFG_RESET ((uint32_t)0xFFFFFFFFU) /* NATCFG register reset value */
|
||||
|
||||
/* EXMC SDRAM device register reset value */
|
||||
#define SDRAM_DEVICE_SDCTL_RESET ((uint32_t)0x000002D0U) /* SDCTL register reset value */
|
||||
#define SDRAM_DEVICE_SDTCFG_RESET ((uint32_t)0x0FFFFFFFU) /* SDTCFG register reset value */
|
||||
#define SDRAM_DEVICE_SDCMD_RESET ((uint32_t)0x00000000U) /* SDCMD register reset value */
|
||||
#define SDRAM_DEVICE_SDARI_RESET ((uint32_t)0x00000000U) /* SDARI register reset value */
|
||||
#define SDRAM_DEVICE_SDSTAT_RESET ((uint32_t)0x00000000U) /* SDSTAT register reset value */
|
||||
#define SDRAM_DEVICE_SDRSCTL_RESET ((uint32_t)0x00000000U) /* SDRSCTL register reset value */
|
||||
|
||||
/* EXMC register bit offset */
|
||||
/* EXMC_SNCTL register bit offset */
|
||||
#define SNCTL_NRMUX_OFFSET ((uint32_t)0x00000001U) /* bit offset of NRMUX */
|
||||
#define SNCTL_NREN_OFFSET ((uint32_t)0x00000006U) /* bit offset of NREN */
|
||||
#define SNCTL_SBRSTEN_OFFSET ((uint32_t)0x00000008U) /* bit offset of SBRSTEN */
|
||||
#define SNCTL_WREN_OFFSET ((uint32_t)0x0000000CU) /* bit offset of WREN */
|
||||
#define SNCTL_NRWTEN_OFFSET ((uint32_t)0x0000000DU) /* bit offset of NRWTEN */
|
||||
#define SNCTL_EXMODEN_OFFSET ((uint32_t)0x0000000EU) /* bit offset of EXMODEN */
|
||||
#define SNCTL_ASYNCWAITEN_OFFSET ((uint32_t)0x0000000FU) /* bit offset of ASYNCWAITEN */
|
||||
#define SNCTL_BKREMAP_OFFSET ((uint32_t)0x00000018U) /* bit offset of BKREMAP */
|
||||
|
||||
/* EXMC_SNTCFG register bit offset */
|
||||
#define SNTCFG_AHLD_OFFSET ((uint32_t)0x00000004U) /* bit offset of AHLD */
|
||||
#define SNTCFG_DSET_OFFSET ((uint32_t)0x00000008U) /* bit offset of DSET */
|
||||
#define SNTCFG_BUSLAT_OFFSET ((uint32_t)0x00000010U) /* bit offset of BUSLAT */
|
||||
|
||||
/* EXMC_NCTL register bit offset */
|
||||
#define NCTL_NDWTEN_OFFSET ((uint32_t)0x00000001U) /* bit offset of NDWTEN */
|
||||
#define NCTL_ECCEN_OFFSET ((uint32_t)0x00000006U) /* bit offset of ECCEN */
|
||||
|
||||
/* EXMC_NCTCFG register bit offset */
|
||||
#define NCTCFG_COMWAIT_OFFSET ((uint32_t)0x00000008U) /* bit offset of COMWAIT */
|
||||
#define NCTCFG_COMHLD_OFFSET ((uint32_t)0x00000010U) /* bit offset of COMHLD */
|
||||
#define NCTCFG_COMHIZ_OFFSET ((uint32_t)0x00000018U) /* bit offset of COMHIZ */
|
||||
|
||||
/* EXMC_NATCFG register bit offset */
|
||||
#define NATCFG_ATTWAIT_OFFSET ((uint32_t)0x00000008U) /* bit offset of ATTWAIT */
|
||||
#define NATCFG_ATTHLD_OFFSET ((uint32_t)0x00000010U) /* bit offset of ATTHLD */
|
||||
#define NATCFG_ATTHIZ_OFFSET ((uint32_t)0x00000018U) /* bit offset of ATTHIZ */
|
||||
|
||||
/* EXMC_SDCTL register bit offset */
|
||||
#define SDCTL_WPEN_OFFSET ((uint32_t)0x00000009U) /* bit offset of WPEN */
|
||||
#define SDCTL_BRSTRD_OFFSET ((uint32_t)0x0000000CU) /* bit offset of BRSTRD */
|
||||
|
||||
/* EXMC_SDTCFG register bit offset */
|
||||
#define SDTCFG_XSRD_OFFSET ((uint32_t)0x00000004U) /* bit offset of XSRD */
|
||||
#define SDTCFG_RASD_OFFSET ((uint32_t)0x00000008U) /* bit offset of RASD */
|
||||
#define SDTCFG_ARFD_OFFSET ((uint32_t)0x0000000CU) /* bit offset of ARFD */
|
||||
#define SDTCFG_WRD_OFFSET ((uint32_t)0x00000010U) /* bit offset of WRD */
|
||||
#define SDTCFG_RPD_OFFSET ((uint32_t)0x00000014U) /* bit offset of RPD */
|
||||
#define SDTCFG_RCD_OFFSET ((uint32_t)0x00000018U) /* bit offset of RCD */
|
||||
|
||||
/* EXMC_SDCMD register bit offset */
|
||||
#define SDCMD_NARF_OFFSET ((uint32_t)0x00000005U) /* bit offset of NARF */
|
||||
#define SDCMD_MRC_OFFSET ((uint32_t)0x00000009U) /* bit offset of MRC */
|
||||
|
||||
/* EXMC_SDCMD register bit offset */
|
||||
#define SDARI_ARINTV_OFFSET ((uint32_t)0x00000001U) /* bit offset of ARINTV */
|
||||
|
||||
/* EXMC_SDRSCTL register bit offset */
|
||||
#define SDRSCTL_SSCR_OFFSET ((uint32_t)0x00000001U) /* bit offset of SSCR */
|
||||
#define SDRSCTL_SDSC_OFFSET ((uint32_t)0x00000004U) /* bit offset of SDSC */
|
||||
|
||||
/* EXMC_SDSTAT register bit offset */
|
||||
#define SDSTAT_STA0_OFFSET ((uint32_t)0x00000001U) /* bit offset of STA0 */
|
||||
#define SDSTAT_STA1_OFFSET ((uint32_t)0x00000003U) /* bit offset of STA1 */
|
||||
|
||||
/* EXMC_NINTEN register interrupt enable bit and interrupt status bit interval */
|
||||
#define NINTEN_INTEN_INTS_INTERVAL ((uint32_t)0x00000003U) /* bit offset of INTEN_INTS */
|
||||
|
||||
/*!
|
||||
\brief deinitialize EXMC NOR/SRAM region
|
||||
\param[in] exmc_norsram_region: select the region of bank0
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXMC_BANK0_NORSRAM_REGIONx(x=0..3): EXMC BANK0 REGIONx
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exmc_norsram_deinit(uint32_t exmc_norsram_region)
|
||||
{
|
||||
/* reset the registers */
|
||||
EXMC_SNCTL(exmc_norsram_region) = BANK0_SNCTL_RESET;
|
||||
EXMC_SNTCFG(exmc_norsram_region) = BANK0_SNTCFG_RESET;
|
||||
EXMC_SNWTCFG(exmc_norsram_region) = BANK0_SNWTCFG_RESET;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize exmc_norsram_parameter_struct with the default values
|
||||
\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 control variables with default values */
|
||||
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->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->cram_page_size = EXMC_CRAM_AUTO_SPLIT;
|
||||
exmc_norsram_init_struct->write_mode = EXMC_ASYN_WRITE;
|
||||
|
||||
/* configure read/write timing */
|
||||
exmc_norsram_init_struct->read_write_timing = NULL;
|
||||
|
||||
/* configure write timing when extended mode is used */
|
||||
exmc_norsram_init_struct->write_timing = NULL;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize EXMC NOR/SRAM region
|
||||
\param[in] exmc_norsram_init_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
|
||||
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
|
||||
cram_page_size: EXMC_CRAM_AUTO_SPLIT, EXMC_CRAM_PAGE_SIZE_128_BYTES, EXMC_CRAM_PAGE_SIZE_256_BYTES,
|
||||
EXMC_CRAM_PAGE_SIZE_512_BYTES, EXMC_CRAM_PAGE_SIZE_1024_BYTES
|
||||
read_write_timing: struct exmc_norsram_timing_parameter_struct set the time
|
||||
asyn_access_mode: EXMC_ACCESS_MODE_A, EXMC_ACCESS_MODE_B, EXMC_ACCESS_MODE_C, EXMC_ACCESS_MODE_D
|
||||
syn_data_latency: EXMC_DATALAT_x_CLK, x=2~17
|
||||
syn_clk_division: EXMC_SYN_CLOCK_RATIO_x_CLK, x=2~16
|
||||
bus_latency: 0x0U~0xFU
|
||||
asyn_data_setuptime: 1~255
|
||||
asyn_address_holdtime: 1~15
|
||||
asyn_address_setuptime: 0~15
|
||||
write_timing: struct exmc_norsram_timing_parameter_struct set the time
|
||||
asyn_access_mode: EXMC_ACCESS_MODE_A, EXMC_ACCESS_MODE_B, EXMC_ACCESS_MODE_C, EXMC_ACCESS_MODE_D
|
||||
syn_data_latency: EXMC_DATALAT_x_CLK, x=2~17
|
||||
syn_clk_division: EXMC_SYN_CLOCK_RATIO_x_CLK, x=2~16
|
||||
bus_latency: 0~15
|
||||
asyn_data_setuptime: 1~255
|
||||
asyn_address_holdtime: 1~15
|
||||
asyn_address_setuptime: 0~15
|
||||
\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 value of register EXMC_SNCTL */
|
||||
snctl = EXMC_SNCTL(exmc_norsram_init_struct->norsram_region);
|
||||
|
||||
/* clear control bits */
|
||||
snctl &= (uint32_t)(~(EXMC_SNCTL_NREN | EXMC_SNCTL_NRTP | EXMC_SNCTL_NRW | EXMC_SNCTL_SBRSTEN |
|
||||
EXMC_SNCTL_NRWTPOL | EXMC_SNCTL_NRWTCFG | EXMC_SNCTL_WEN |
|
||||
EXMC_SNCTL_NRWTEN | EXMC_SNCTL_EXMODEN | EXMC_SNCTL_ASYNCWTEN | EXMC_SNCTL_SYNCWR |
|
||||
EXMC_SNCTL_NRMUX | EXMC_SNCTL_BKREMAP | EXMC_SNCTL_CCK | EXMC_SNCTL_CPS));
|
||||
|
||||
/* configure control bits */
|
||||
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->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_ASYNCWAITEN_OFFSET) |
|
||||
exmc_norsram_init_struct->write_mode |
|
||||
exmc_norsram_init_struct->cram_page_size);
|
||||
|
||||
/* nor flash access enable */
|
||||
if(EXMC_MEMORY_TYPE_NOR == exmc_norsram_init_struct->memory_type) {
|
||||
snctl |= (uint32_t)EXMC_SNCTL_NREN;
|
||||
}
|
||||
|
||||
/* configure timing */
|
||||
sntcfg = (uint32_t)(exmc_norsram_init_struct->read_write_timing->asyn_address_setuptime |
|
||||
(exmc_norsram_init_struct->read_write_timing->asyn_address_holdtime << SNTCFG_AHLD_OFFSET) |
|
||||
(exmc_norsram_init_struct->read_write_timing->asyn_data_setuptime << SNTCFG_DSET_OFFSET) |
|
||||
(exmc_norsram_init_struct->read_write_timing->bus_latency << SNTCFG_BUSLAT_OFFSET) |
|
||||
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);
|
||||
|
||||
if(ENABLE == exmc_norsram_init_struct->extended_mode) {
|
||||
/* for extended mode, configure write timing */
|
||||
snwtcfg = (uint32_t)(exmc_norsram_init_struct->write_timing->asyn_address_setuptime |
|
||||
(exmc_norsram_init_struct->write_timing->asyn_address_holdtime << SNTCFG_AHLD_OFFSET) |
|
||||
(exmc_norsram_init_struct->write_timing->asyn_data_setuptime << SNTCFG_DSET_OFFSET) |
|
||||
(exmc_norsram_init_struct->write_timing->bus_latency << SNTCFG_BUSLAT_OFFSET) |
|
||||
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 enable EXMC NOR/PSRAM bank region
|
||||
\param[in] exmc_norsram_region: specify the region of NOR/PSRAM bank
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXMC_BANK0_NORSRAM_REGIONx(x=0..3): EXMC BANK0 REGIONx
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exmc_norsram_enable(uint32_t exmc_norsram_region)
|
||||
{
|
||||
EXMC_SNCTL(exmc_norsram_region) |= (uint32_t)EXMC_SNCTL_NRBKEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable EXMC NOR/PSRAM bank region
|
||||
\param[in] exmc_norsram_region: specify the region of NOR/PSRAM Bank
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXMC_BANK0_NORSRAM_REGIONx(x=0..3): EXMC BANK0 REGIONx
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exmc_norsram_disable(uint32_t exmc_norsram_region)
|
||||
{
|
||||
EXMC_SNCTL(exmc_norsram_region) &= ~(uint32_t)EXMC_SNCTL_NRBKEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief deinitialize EXMC NAND bank
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exmc_nand_deinit(void)
|
||||
{
|
||||
/* deinitialize EXMC_BANK2_NAND */
|
||||
EXMC_NCTL = BANK2_NCTL_RESET;
|
||||
EXMC_NINTEN = BANK2_NINTEN_RESET;
|
||||
EXMC_NCTCFG = BANK2_NCTCFG_RESET;
|
||||
EXMC_NATCFG = BANK2_NATCFG_RESET;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize exmc_nand_parameter_struct with the default values
|
||||
\param[in] none
|
||||
\param[out] the initialized struct exmc_nand_parameter_struct pointer
|
||||
\retval none
|
||||
*/
|
||||
void exmc_nand_struct_para_init(exmc_nand_parameter_struct *exmc_nand_init_struct)
|
||||
{
|
||||
/* configure the structure with default values */
|
||||
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 = 0x00U;
|
||||
exmc_nand_init_struct->atr_latency = 0x00U;
|
||||
exmc_nand_init_struct->common_space_timing = NULL;
|
||||
exmc_nand_init_struct->attribute_space_timing = NULL;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize EXMC NAND bank
|
||||
\param[in] exmc_nand_init_struct: configure the EXMC NAND parameter
|
||||
ecc_size: EXMC_ECC_SIZE_xBYTES,x=256,512,1024,2048,4096
|
||||
atr_latency: EXMC_ALE_RE_DELAY_x_CK_EXMC,x=1~16
|
||||
ctr_latency: EXMC_CLE_RE_DELAY_x_CK_EXMC,x=1~16
|
||||
ecc_logic: ENABLE or DISABLE
|
||||
databus_width: EXMC_NAND_DATABUS_WIDTH_8B,EXMC_NAND_DATABUS_WIDTH_16B
|
||||
wait_function: ENABLE or DISABLE
|
||||
common_space_timing: struct exmc_nand_timing_parameter_struct set the time
|
||||
databus_hiztime: 1~255
|
||||
holdtime: 1~254
|
||||
waittime: 2~255
|
||||
setuptime: 1~255
|
||||
attribute_space_timing: struct exmc_nand_timing_parameter_struct set the time
|
||||
databus_hiztime: 0~254
|
||||
holdtime: 1~254
|
||||
waittime: 2~255
|
||||
setuptime: 1~255
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exmc_nand_init(exmc_nand_parameter_struct *exmc_nand_init_struct)
|
||||
{
|
||||
uint32_t nctl = 0x00000000U, nctcfg = 0x00000000U, natcfg = 0x00000000U;
|
||||
|
||||
/* configure nctl for EXMC_NCTL */
|
||||
nctl = (uint32_t)((exmc_nand_init_struct->wait_feature << NCTL_NDWTEN_OFFSET) |
|
||||
exmc_nand_init_struct->databus_width |
|
||||
(exmc_nand_init_struct->ecc_logic << NCTL_ECCEN_OFFSET) |
|
||||
exmc_nand_init_struct->ecc_size |
|
||||
exmc_nand_init_struct->ctr_latency |
|
||||
exmc_nand_init_struct->atr_latency);
|
||||
|
||||
/* configure nctcfg for EXMC_NCTCFG */
|
||||
nctcfg = (uint32_t)(((exmc_nand_init_struct->common_space_timing->setuptime - 1U) & EXMC_NCTCFG_COMSET) |
|
||||
(((exmc_nand_init_struct->common_space_timing->waittime - 1U) << NCTCFG_COMWAIT_OFFSET) & EXMC_NCTCFG_COMWAIT) |
|
||||
((exmc_nand_init_struct->common_space_timing->holdtime << NCTCFG_COMHLD_OFFSET) & EXMC_NCTCFG_COMHLD) |
|
||||
(((exmc_nand_init_struct->common_space_timing->databus_hiztime - 1U) << NCTCFG_COMHIZ_OFFSET) & EXMC_NCTCFG_COMHIZ));
|
||||
|
||||
/* configure natcfg for EXMC_NATCFG */
|
||||
natcfg = (uint32_t)(((exmc_nand_init_struct->attribute_space_timing->setuptime - 1U) & EXMC_NATCFG_ATTSET) |
|
||||
(((exmc_nand_init_struct->attribute_space_timing->waittime - 1U) << NATCFG_ATTWAIT_OFFSET) & EXMC_NATCFG_ATTWAIT) |
|
||||
((exmc_nand_init_struct->attribute_space_timing->holdtime << NATCFG_ATTHLD_OFFSET) & EXMC_NATCFG_ATTHLD) |
|
||||
((exmc_nand_init_struct->attribute_space_timing->databus_hiztime << NATCFG_ATTHIZ_OFFSET) & EXMC_NATCFG_ATTHIZ));
|
||||
|
||||
/* initialize EXMC_BANK2_NAND */
|
||||
EXMC_NCTL = nctl;
|
||||
EXMC_NCTCFG = nctcfg;
|
||||
EXMC_NATCFG = natcfg;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable NAND bank
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exmc_nand_enable(void)
|
||||
{
|
||||
EXMC_NCTL |= EXMC_NCTL_NDBKEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable NAND bank
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exmc_nand_disable(void)
|
||||
{
|
||||
EXMC_NCTL &= ~EXMC_NCTL_NDBKEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief deinitialize EXMC SDRAM device
|
||||
\param[in] exmc_sdram_device: select the SRAM device
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXMC_SDRAM_DEVICEx(x=0, 1)
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exmc_sdram_deinit(uint32_t exmc_sdram_device)
|
||||
{
|
||||
/* reset SDRAM registers */
|
||||
EXMC_SDCTL(exmc_sdram_device) = SDRAM_DEVICE_SDCTL_RESET;
|
||||
EXMC_SDTCFG(exmc_sdram_device) = SDRAM_DEVICE_SDTCFG_RESET;
|
||||
EXMC_SDCMD = SDRAM_DEVICE_SDCMD_RESET;
|
||||
EXMC_SDARI = SDRAM_DEVICE_SDARI_RESET;
|
||||
EXMC_SDRSCTL = SDRAM_DEVICE_SDRSCTL_RESET;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize exmc_sdram_parameter_struct with the default values
|
||||
\param[in] none
|
||||
\param[out] the initialized struct exmc_parameter_struct pointer
|
||||
\retval none
|
||||
*/
|
||||
void exmc_sdram_struct_para_init(exmc_sdram_parameter_struct *exmc_sdram_init_struct)
|
||||
{
|
||||
/* configure the structure with default values */
|
||||
exmc_sdram_init_struct->sdram_device = EXMC_SDRAM_DEVICE0;
|
||||
exmc_sdram_init_struct->column_address_width = EXMC_SDRAM_COW_ADDRESS_8;
|
||||
exmc_sdram_init_struct->row_address_width = EXMC_SDRAM_ROW_ADDRESS_11;
|
||||
exmc_sdram_init_struct->data_width = EXMC_SDRAM_DATABUS_WIDTH_16B;
|
||||
exmc_sdram_init_struct->internal_bank_number = EXMC_SDRAM_4_INTER_BANK;
|
||||
exmc_sdram_init_struct->cas_latency = EXMC_CAS_LATENCY_1_SDCLK;
|
||||
exmc_sdram_init_struct->write_protection = ENABLE;
|
||||
exmc_sdram_init_struct->sdclock_config = EXMC_SDCLK_DISABLE;
|
||||
exmc_sdram_init_struct->burst_read_switch = DISABLE;
|
||||
exmc_sdram_init_struct->pipeline_read_delay = EXMC_PIPELINE_DELAY_0_CK_EXMC;
|
||||
|
||||
exmc_sdram_init_struct->timing = NULL;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize EXMC SDRAM device
|
||||
\param[in] exmc_sdram_init_struct: configure the EXMC SDRAM parameter
|
||||
sdram_device: EXMC_SDRAM_DEVICE0,EXMC_SDRAM_DEVICE1
|
||||
pipeline_read_delay: EXMC_PIPELINE_DELAY_x_CK_EXMC,x=0~2
|
||||
burst_read_switch: ENABLE or DISABLE
|
||||
sdclock_config: EXMC_SDCLK_DISABLE,EXMC_SDCLK_PERIODS_2_CK_EXMC,EXMC_SDCLK_PERIODS_3_CK_EXMC,EXMC_SDCLK_PERIODS_4_CK_EXMC,EXMC_SDCLK_PERIODS_5_CK_EXMC
|
||||
write_protection: ENABLE or DISABLE
|
||||
cas_latency: EXMC_CAS_LATENCY_x_SDCLK,x=1~3
|
||||
internal_bank_number: EXMC_SDRAM_2_INTER_BANK,EXMC_SDRAM_4_INTER_BANK
|
||||
data_width: EXMC_SDRAM_DATABUS_WIDTH_8B,EXMC_SDRAM_DATABUS_WIDTH_16B,EXMC_SDRAM_DATABUS_WIDTH_32B
|
||||
row_address_width: EXMC_SDRAM_ROW_ADDRESS_x,x=11~13
|
||||
column_address_width: EXMC_SDRAM_COW_ADDRESS_x,x=8~11
|
||||
timing: exmc_sdram_timing_parameter_struct set the time
|
||||
row_to_column_delay: 1~16
|
||||
row_precharge_delay: 1~16
|
||||
write_recovery_delay: 1~16
|
||||
auto_refresh_delay: 1~16
|
||||
row_address_select_delay: 1~16
|
||||
exit_selfrefresh_delay: 1~16
|
||||
load_mode_register_delay: 1~16
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exmc_sdram_init(exmc_sdram_parameter_struct *exmc_sdram_init_struct)
|
||||
{
|
||||
uint32_t sdctl0, sdctl1, sdtcfg0, sdtcfg1;
|
||||
|
||||
/* configure EXMC_SDCTL0 or EXMC_SDCTL1 */
|
||||
if(EXMC_SDRAM_DEVICE0 == exmc_sdram_init_struct->sdram_device) {
|
||||
/* configure EXMC_SDCTL0 */
|
||||
EXMC_SDCTL(EXMC_SDRAM_DEVICE0) = (uint32_t)(exmc_sdram_init_struct->column_address_width |
|
||||
exmc_sdram_init_struct->row_address_width |
|
||||
exmc_sdram_init_struct->data_width |
|
||||
exmc_sdram_init_struct->internal_bank_number |
|
||||
exmc_sdram_init_struct->cas_latency |
|
||||
(exmc_sdram_init_struct->write_protection << SDCTL_WPEN_OFFSET) |
|
||||
exmc_sdram_init_struct->sdclock_config |
|
||||
(exmc_sdram_init_struct->burst_read_switch << SDCTL_BRSTRD_OFFSET) |
|
||||
exmc_sdram_init_struct->pipeline_read_delay);
|
||||
|
||||
/* configure EXMC_SDTCFG0 */
|
||||
EXMC_SDTCFG(EXMC_SDRAM_DEVICE0) = (uint32_t)((exmc_sdram_init_struct->timing->load_mode_register_delay) - 1U) |
|
||||
(((exmc_sdram_init_struct->timing->exit_selfrefresh_delay) - 1U) << SDTCFG_XSRD_OFFSET) |
|
||||
(((exmc_sdram_init_struct->timing->row_address_select_delay) - 1U) << SDTCFG_RASD_OFFSET) |
|
||||
(((exmc_sdram_init_struct->timing->auto_refresh_delay) - 1U) << SDTCFG_ARFD_OFFSET) |
|
||||
(((exmc_sdram_init_struct->timing->write_recovery_delay) - 1U) << SDTCFG_WRD_OFFSET) |
|
||||
(((exmc_sdram_init_struct->timing->row_precharge_delay) - 1U) << SDTCFG_RPD_OFFSET) |
|
||||
(((exmc_sdram_init_struct->timing->row_to_column_delay) - 1U) << SDTCFG_RCD_OFFSET);
|
||||
} else {
|
||||
/* configure EXMC_SDCTL0 and EXMC_SDCTL1 */
|
||||
/* some bits in the EXMC_SDCTL1 register are reserved */
|
||||
sdctl0 = EXMC_SDCTL(EXMC_SDRAM_DEVICE0) & (~(EXMC_SDCTL_PIPED | EXMC_SDCTL_BRSTRD | EXMC_SDCTL_SDCLK | EXMC_SDCTL_SDCLK_2));
|
||||
|
||||
sdctl0 |= (uint32_t)(exmc_sdram_init_struct->sdclock_config |
|
||||
(exmc_sdram_init_struct->burst_read_switch << SDCTL_BRSTRD_OFFSET) |
|
||||
exmc_sdram_init_struct->pipeline_read_delay);
|
||||
|
||||
sdctl1 = (uint32_t)(exmc_sdram_init_struct->column_address_width |
|
||||
exmc_sdram_init_struct->row_address_width |
|
||||
exmc_sdram_init_struct->data_width |
|
||||
exmc_sdram_init_struct->internal_bank_number |
|
||||
exmc_sdram_init_struct->cas_latency |
|
||||
(exmc_sdram_init_struct->write_protection << SDCTL_WPEN_OFFSET));
|
||||
|
||||
EXMC_SDCTL(EXMC_SDRAM_DEVICE0) = sdctl0;
|
||||
EXMC_SDCTL(EXMC_SDRAM_DEVICE1) = sdctl1;
|
||||
|
||||
/* configure EXMC_SDTCFG0 and EXMC_SDTCFG1 */
|
||||
/* some bits in the EXMC_SDTCFG1 register are reserved */
|
||||
sdtcfg0 = EXMC_SDTCFG(EXMC_SDRAM_DEVICE0) & (~(EXMC_SDTCFG_RPD | EXMC_SDTCFG_WRD | EXMC_SDTCFG_ARFD));
|
||||
|
||||
sdtcfg0 |= (uint32_t)((((exmc_sdram_init_struct->timing->auto_refresh_delay) - 1U) << SDTCFG_ARFD_OFFSET) |
|
||||
(((exmc_sdram_init_struct->timing->row_precharge_delay) - 1U) << SDTCFG_RPD_OFFSET) |
|
||||
(((exmc_sdram_init_struct->timing->write_recovery_delay) - 1U) << SDTCFG_WRD_OFFSET));
|
||||
|
||||
sdtcfg1 = (uint32_t)(((exmc_sdram_init_struct->timing->load_mode_register_delay) - 1U) |
|
||||
(((exmc_sdram_init_struct->timing->exit_selfrefresh_delay) - 1U) << SDTCFG_XSRD_OFFSET) |
|
||||
(((exmc_sdram_init_struct->timing->row_address_select_delay) - 1U) << SDTCFG_RASD_OFFSET) |
|
||||
(((exmc_sdram_init_struct->timing->row_to_column_delay) - 1U) << SDTCFG_RCD_OFFSET));
|
||||
|
||||
EXMC_SDTCFG(EXMC_SDRAM_DEVICE0) = sdtcfg0;
|
||||
EXMC_SDTCFG(EXMC_SDRAM_DEVICE1) = sdtcfg1;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure NOR/PSRAM and SDRAM remap
|
||||
\param[in] bank_remap: NOR/PSRAM and SDRAM map address
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXMC_BANK_REMAP_DEFAULT: default mapping
|
||||
\arg EXMC_BANK_NORPSRAM_SDRAM_SWAP: NOR/PSRAM bank and SDRAM device 0 swapped
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exmc_norsram_sdram_remap_config(uint32_t bank_remap)
|
||||
{
|
||||
/* reset BKREMAP bits */
|
||||
EXMC_SNCTL(EXMC_BANK0_NORSRAM_REGION0) &= (uint32_t)(~EXMC_SNCTL_BKREMAP);
|
||||
|
||||
EXMC_SNCTL(EXMC_BANK0_NORSRAM_REGION0) |= bank_remap;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get NOR/PSRAM and SDRAM remap configuration
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval bank remap value
|
||||
\arg EXMC_BANK_REMAP_DEFAULT: default mapping
|
||||
\arg EXMC_BANK_NORPSRAM_SDRAM_SWAP: NOR/PSRAM bank and SDRAM device 0 swapped
|
||||
*/
|
||||
uint32_t exmc_norsram_sdram_remap_get(void)
|
||||
{
|
||||
uint32_t bank_remap;
|
||||
|
||||
bank_remap = EXMC_SNCTL(EXMC_BANK0_NORSRAM_REGION0) & EXMC_SNCTL_BKREMAP;
|
||||
|
||||
return bank_remap;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure consecutive clock mode (consecutive clock is only supported in EXMC BANK0 REGION0)
|
||||
\param[in] clock_mode: specify when the clock is generated
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXMC_CLOCK_SYN_MODE: the clock is generated only during synchronous access
|
||||
\arg EXMC_CLOCK_UNCONDITIONALLY: the clock is generated unconditionally
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exmc_norsram_consecutive_clock_config(uint32_t clock_mode)
|
||||
{
|
||||
if(EXMC_CLOCK_UNCONDITIONALLY == clock_mode) {
|
||||
EXMC_SNCTL(EXMC_BANK0_NORSRAM_REGION0) |= EXMC_CLOCK_UNCONDITIONALLY;
|
||||
} else {
|
||||
EXMC_SNCTL(EXMC_BANK0_NORSRAM_REGION0) &= ~EXMC_CLOCK_UNCONDITIONALLY;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure CRAM page size
|
||||
\param[in] exmc_norsram_region: select the region of bank0
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXMC_BANK0_NORSRAM_REGIONx(x=0..3)
|
||||
\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 exmc_norsram_region, uint32_t page_size)
|
||||
{
|
||||
/* reset the bits */
|
||||
EXMC_SNCTL(exmc_norsram_region) &= ~EXMC_SNCTL_CPS;
|
||||
|
||||
EXMC_SNCTL(exmc_norsram_region) |= page_size;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable or disable the EXMC NAND ECC function
|
||||
\param[in] newvalue: ENABLE or DISABLE
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exmc_nand_ecc_config(ControlStatus newvalue)
|
||||
{
|
||||
if(ENABLE == newvalue) {
|
||||
/* enable NAND bank ECC function */
|
||||
EXMC_NCTL |= EXMC_NCTL_ECCEN;
|
||||
} else {
|
||||
/* disable NAND bank ECC function */
|
||||
EXMC_NCTL &= ~EXMC_NCTL_ECCEN;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the EXMC ECC value
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval the error correction code(ECC) value
|
||||
*/
|
||||
uint32_t exmc_ecc_get(void)
|
||||
{
|
||||
return(EXMC_NECC);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable read sample function
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exmc_sdram_readsample_enable(void)
|
||||
{
|
||||
EXMC_SDRSCTL |= EXMC_SDRSCTL_RSEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable read sample function
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exmc_sdram_readsample_disable(void)
|
||||
{
|
||||
EXMC_SDRSCTL &= (uint32_t)(~EXMC_SDRSCTL_RSEN);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the delayed sample clock of read data
|
||||
\param[in] delay_cell: SDRAM the delayed sample clock of read data
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXMC_SDRAM_x_DELAY_CELL(x=0..15)
|
||||
\param[in] extra_clk: sample cycle of read data
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXMC_SDRAM_READSAMPLE_0_EXTRACK: add 0 extra CK_EXMC cycle to the read data sample clock besides the delay chain
|
||||
\arg EXMC_SDRAM_READSAMPLE_1_EXTRACK: add 1 extra CK_EXMC cycle to the read data sample clock besides the delay chain
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exmc_sdram_readsample_config(uint32_t delay_cell, uint32_t extra_clk)
|
||||
{
|
||||
uint32_t sdrsctl = 0U;
|
||||
|
||||
/* reset the bits */
|
||||
sdrsctl = EXMC_SDRSCTL & (~(EXMC_SDRSCTL_SDSC | EXMC_SDRSCTL_SSCR));
|
||||
/* set the bits */
|
||||
sdrsctl |= (uint32_t)(delay_cell | extra_clk);
|
||||
EXMC_SDRSCTL = sdrsctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the SDRAM memory command
|
||||
\param[in] exmc_sdram_command_init_struct: initialize EXMC SDRAM command
|
||||
mode_register_content:
|
||||
auto_refresh_number: EXMC_SDRAM_AUTO_REFLESH_x_SDCLK, x=1~15
|
||||
bank_select: EXMC_SDRAM_DEVICE0_SELECT, EXMC_SDRAM_DEVICE1_SELECT, EXMC_SDRAM_DEVICE0_1_SELECT
|
||||
command: EXMC_SDRAM_NORMAL_OPERATION, EXMC_SDRAM_CLOCK_ENABLE, EXMC_SDRAM_PRECHARGE_ALL,
|
||||
EXMC_SDRAM_AUTO_REFRESH, EXMC_SDRAM_LOAD_MODE_REGISTER, EXMC_SDRAM_SELF_REFRESH,
|
||||
EXMC_SDRAM_POWERDOWN_ENTRY
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exmc_sdram_command_config(exmc_sdram_command_parameter_struct *exmc_sdram_command_init_struct)
|
||||
{
|
||||
/* configure command register */
|
||||
EXMC_SDCMD = (uint32_t)((exmc_sdram_command_init_struct->command) |
|
||||
(exmc_sdram_command_init_struct->bank_select) |
|
||||
((exmc_sdram_command_init_struct->auto_refresh_number)) |
|
||||
((exmc_sdram_command_init_struct->mode_register_content) << SDCMD_MRC_OFFSET));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set auto-refresh interval
|
||||
\param[in] exmc_count: the number SDRAM clock cycles unit between two successive auto-refresh commands, 0x00000000~0x00001FFF
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exmc_sdram_refresh_count_set(uint32_t exmc_count)
|
||||
{
|
||||
uint32_t sdari;
|
||||
sdari = EXMC_SDARI & (~EXMC_SDARI_ARINTV);
|
||||
EXMC_SDARI = sdari | (uint32_t)((exmc_count << SDARI_ARINTV_OFFSET) & EXMC_SDARI_ARINTV);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set the number of successive auto-refresh command
|
||||
\param[in] exmc_number: the number of successive Auto-refresh cycles will be send, 1~15
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exmc_sdram_autorefresh_number_set(uint32_t exmc_number)
|
||||
{
|
||||
uint32_t sdcmd;
|
||||
sdcmd = EXMC_SDCMD & (~EXMC_SDCMD_NARF);
|
||||
EXMC_SDCMD = sdcmd | (uint32_t)((exmc_number << SDCMD_NARF_OFFSET) & EXMC_SDCMD_NARF);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the write protection function
|
||||
\param[in] exmc_sdram_device: specify the SDRAM device
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXMC_SDRAM_DEVICEx(x=0,1)
|
||||
\param[in] newvalue: ENABLE or DISABLE
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exmc_sdram_write_protection_config(uint32_t exmc_sdram_device, ControlStatus newvalue)
|
||||
{
|
||||
if(ENABLE == newvalue) {
|
||||
EXMC_SDCTL(exmc_sdram_device) |= (uint32_t)EXMC_SDCTL_WPEN;
|
||||
} else {
|
||||
EXMC_SDCTL(exmc_sdram_device) &= ~((uint32_t)EXMC_SDCTL_WPEN);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the status of SDRAM device0 or device1
|
||||
\param[in] exmc_sdram_device: specify the SDRAM device
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXMC_SDRAM_DEVICEx(x=0,1)
|
||||
\param[out] none
|
||||
\retval the status of SDRAM device
|
||||
*/
|
||||
uint32_t exmc_sdram_bankstatus_get(uint32_t exmc_sdram_device)
|
||||
{
|
||||
uint32_t sdstat = 0U;
|
||||
|
||||
if(EXMC_SDRAM_DEVICE0 == exmc_sdram_device) {
|
||||
sdstat = ((uint32_t)(EXMC_SDSTAT & EXMC_SDSDAT_STA0) >> SDSTAT_STA0_OFFSET);
|
||||
} else {
|
||||
sdstat = ((uint32_t)(EXMC_SDSTAT & EXMC_SDSDAT_STA1) >> SDSTAT_STA1_OFFSET);
|
||||
}
|
||||
|
||||
return sdstat;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get EXMC flag status
|
||||
\param[in] exmc_bank: specify the NAND bank or SDRAM device
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXMC_BANK2_NAND: the NAND bank2
|
||||
\arg EXMC_SDRAM_DEVICE0: the SDRAM device0
|
||||
\arg EXMC_SDRAM_DEVICE1: the SDRAM device1
|
||||
\param[in] flag: EXMC status and flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXMC_NAND_FLAG_LEVEL: interrupt high-level status
|
||||
\arg EXMC_NAND_FLAG_RISE: interrupt rising edge status
|
||||
\arg EXMC_NAND_FLAG_FALL: interrupt falling edge status
|
||||
\arg EXMC_NAND_FLAG_FIFOE: FIFO empty flag
|
||||
\arg EXMC_SDRAM_FLAG_REFRESH: refresh error interrupt flag
|
||||
\arg EXMC_SDRAM_FLAG_NREADY: not ready status
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus exmc_flag_get(uint32_t exmc_bank, uint32_t flag)
|
||||
{
|
||||
uint32_t status = 0x00000000U;
|
||||
|
||||
if(EXMC_BANK2_NAND == exmc_bank) {
|
||||
/* NAND bank2 */
|
||||
status = EXMC_NINTEN;
|
||||
} else {
|
||||
/* SDRAM device0 or device1 */
|
||||
status = EXMC_SDSTAT;
|
||||
}
|
||||
|
||||
if((status & flag) != (uint32_t)flag) {
|
||||
/* flag is reset */
|
||||
return RESET;
|
||||
} else {
|
||||
/* flag is set */
|
||||
return SET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear EXMC flag status
|
||||
\param[in] exmc_bank: specify the NAND bank or SDRAM device
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXMC_BANK2_NAND: the NAND bank2
|
||||
\arg EXMC_SDRAM_DEVICE0: the SDRAM device0
|
||||
\arg EXMC_SDRAM_DEVICE1: the SDRAM device1
|
||||
\param[in] flag: EXMC status and flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXMC_NAND_FLAG_LEVEL: interrupt high-level status
|
||||
\arg EXMC_NAND_FLAG_RISE: interrupt rising edge status
|
||||
\arg EXMC_NAND_FLAG_FALL: interrupt falling edge status
|
||||
\arg EXMC_NAND_FLAG_FIFOE: FIFO empty flag
|
||||
\arg EXMC_SDRAM_FLAG_REFRESH: refresh error interrupt flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exmc_flag_clear(uint32_t exmc_bank, uint32_t flag)
|
||||
{
|
||||
if(EXMC_BANK2_NAND == exmc_bank) {
|
||||
/* NAND bank2 */
|
||||
EXMC_NINTEN &= ~flag;
|
||||
} else {
|
||||
/* SDRAM device0 or device1 */
|
||||
EXMC_SDARI |= EXMC_SDARI_REC;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable EXMC interrupt
|
||||
\param[in] exmc_bank: specify the NAND bank or SDRAM device
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXMC_BANK2_NAND: the NAND bank2
|
||||
\arg EXMC_SDRAM_DEVICE0: the SDRAM device0
|
||||
\arg EXMC_SDRAM_DEVICE1: the SDRAM device1
|
||||
\param[in] interrupt: specify get which interrupt flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXMC_NAND_INT_FLAG_LEVEL: high-level interrupt flag
|
||||
\arg EXMC_NAND_INT_FLAG_RISE: rising edge interrupt flag
|
||||
\arg EXMC_NAND_INT_FLAG_FALL: falling edge interrupt flag
|
||||
\arg EXMC_SDRAM_INT_FLAG_REFRESH: refresh error interrupt flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exmc_interrupt_enable(uint32_t exmc_bank, uint32_t interrupt)
|
||||
{
|
||||
if(EXMC_BANK2_NAND == exmc_bank) {
|
||||
/* NAND bank2 */
|
||||
EXMC_NINTEN |= interrupt;
|
||||
} else {
|
||||
/* SDRAM device0 or device1 */
|
||||
EXMC_SDARI |= EXMC_SDARI_REIE;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable EXMC interrupt
|
||||
\param[in] exmc_bank: specify the NAND bank or SDRAM device
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXMC_BANK2_NAND: the NAND bank2
|
||||
\arg EXMC_SDRAM_DEVICE0: the SDRAM device0
|
||||
\arg EXMC_SDRAM_DEVICE1: the SDRAM device1
|
||||
\param[in] interrupt: specify get which interrupt flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXMC_NAND_INT_LEVEL: high-level interrupt
|
||||
\arg EXMC_NAND_INT_RISE: rising edge interrupt
|
||||
\arg EXMC_NAND_INT_FALL: falling edge interrupt
|
||||
\arg EXMC_SDRAM_INT_REFRESH: refresh error interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exmc_interrupt_disable(uint32_t exmc_bank, uint32_t interrupt)
|
||||
{
|
||||
if(EXMC_BANK2_NAND == exmc_bank) {
|
||||
/* NAND bank2 */
|
||||
EXMC_NINTEN &= ~interrupt;
|
||||
} else {
|
||||
/* SDRAM device0 or device1 */
|
||||
EXMC_SDARI &= ~EXMC_SDARI_REIE;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get EXMC interrupt flag
|
||||
\param[in] exmc_bank: specify the NAND bank or SDRAM device
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXMC_BANK2_NAND: the NAND bank2
|
||||
\arg EXMC_SDRAM_DEVICE0: the SDRAM device0
|
||||
\arg EXMC_SDRAM_DEVICE1: the SDRAM device1
|
||||
\param[in] interrupt: EXMC interrupt flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXMC_NAND_INT_FLAG_LEVEL: high-level interrupt flag
|
||||
\arg EXMC_NAND_INT_FLAG_RISE: rising edge interrupt flag
|
||||
\arg EXMC_NAND_INT_FLAG_FALL: falling edge interrupt flag
|
||||
\arg EXMC_SDRAM_INT_FLAG_REFRESH: refresh error interrupt and flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus exmc_interrupt_flag_get(uint32_t exmc_bank, uint32_t interrupt)
|
||||
{
|
||||
uint32_t reg_value = 0x00000000U;
|
||||
uint32_t interrupt_enable = 0x00000000U;
|
||||
uint32_t interrupt_status = 0x00000000U;
|
||||
|
||||
if(EXMC_BANK2_NAND == exmc_bank) {
|
||||
/* NAND bank2 */
|
||||
reg_value = EXMC_NINTEN;
|
||||
interrupt_status = (reg_value & (interrupt >> NINTEN_INTEN_INTS_INTERVAL));
|
||||
} else {
|
||||
/* SDRAM device0 or device1 */
|
||||
reg_value = EXMC_SDARI;
|
||||
interrupt_status = (EXMC_SDSTAT & EXMC_SDSDAT_REIF);
|
||||
}
|
||||
|
||||
interrupt_enable = (reg_value & interrupt);
|
||||
|
||||
if((interrupt_enable) && (interrupt_status)) {
|
||||
/* interrupt flag is set */
|
||||
return SET;
|
||||
} else {
|
||||
/* interrupt flag is reset */
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear EXMC interrupt flag
|
||||
\param[in] exmc_bank: specify the NAND bank or SDRAM device
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXMC_BANK2_NAND: the NAND bank2
|
||||
\arg EXMC_SDRAM_DEVICE0: the SDRAM device0
|
||||
\arg EXMC_SDRAM_DEVICE1: the SDRAM device1
|
||||
\param[in] interrupt: EXMC interrupt flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXMC_NAND_INT_FLAG_LEVEL: high-level interrupt and flag
|
||||
\arg EXMC_NAND_INT_FLAG_RISE: rising edge interrupt and flag
|
||||
\arg EXMC_NAND_INT_FLAG_FALL: falling edge interrupt and flag
|
||||
\arg EXMC_SDRAM_INT_FLAG_REFRESH: refresh error interrupt and flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exmc_interrupt_flag_clear(uint32_t exmc_bank, uint32_t interrupt)
|
||||
{
|
||||
if(EXMC_BANK2_NAND == exmc_bank) {
|
||||
/* NAND bank2 */
|
||||
EXMC_NINTEN &= ~(interrupt >> NINTEN_INTEN_INTS_INTERVAL);
|
||||
} else {
|
||||
/* SDRAM device0 or device1 */
|
||||
EXMC_SDARI |= EXMC_SDARI_REC;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,254 @@
|
||||
/*!
|
||||
\file gd32h7xx_exti.c
|
||||
\brief EXTI driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_exti.h"
|
||||
|
||||
#define EXTI_REG_RESET_VALUE ((uint32_t)0x00000000U)
|
||||
|
||||
/*!
|
||||
\brief deinitialize the EXTI
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exti_deinit(void)
|
||||
{
|
||||
/* reset the value of all the EXTI registers */
|
||||
EXTI_INTEN0 = EXTI_REG_RESET_VALUE;
|
||||
EXTI_EVEN0 = EXTI_REG_RESET_VALUE;
|
||||
EXTI_RTEN0 = EXTI_REG_RESET_VALUE;
|
||||
EXTI_FTEN0 = EXTI_REG_RESET_VALUE;
|
||||
EXTI_SWIEV0 = EXTI_REG_RESET_VALUE;
|
||||
EXTI_INTEN1 = EXTI_REG_RESET_VALUE;
|
||||
EXTI_EVEN1 = EXTI_REG_RESET_VALUE;
|
||||
EXTI_RTEN1 = EXTI_REG_RESET_VALUE;
|
||||
EXTI_FTEN1 = EXTI_REG_RESET_VALUE;
|
||||
EXTI_SWIEV1 = EXTI_REG_RESET_VALUE;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the EXTI line x
|
||||
\param[in] linex: EXTI line number, refer to exti_line_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXTI_x (x=0..37): EXTI line x
|
||||
\param[in] mode: interrupt or event mode, refer to exti_mode_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXTI_INTERRUPT: interrupt mode
|
||||
\arg EXTI_EVENT: event mode
|
||||
\param[in] trig_type: interrupt and event trigger type, refer to exti_trig_type_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXTI_TRIG_RISING: rising edge trigger
|
||||
\arg EXTI_TRIG_FALLING: falling trigger
|
||||
\arg EXTI_TRIG_BOTH: rising and falling trigger
|
||||
\arg EXTI_TRIG_NONE: without rising edge or falling edge trigger
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exti_init(exti_line_enum linex, exti_mode_enum mode, exti_trig_type_enum trig_type)
|
||||
{
|
||||
/* reset the EXTI line x */
|
||||
EXTI_INTEN(EXTI_REG_VAL(linex)) &= ~EXTI_BIT_POS(linex);
|
||||
EXTI_EVEN(EXTI_REG_VAL(linex)) &= ~EXTI_BIT_POS(linex);
|
||||
EXTI_RTEN(EXTI_REG_VAL(linex)) &= ~EXTI_BIT_POS(linex);
|
||||
EXTI_FTEN(EXTI_REG_VAL(linex)) &= ~EXTI_BIT_POS(linex);
|
||||
|
||||
/* set the EXTI mode and enable the interrupts or events from EXTI line x */
|
||||
switch(mode) {
|
||||
case EXTI_INTERRUPT:
|
||||
EXTI_INTEN(EXTI_REG_VAL(linex)) |= EXTI_BIT_POS(linex);
|
||||
break;
|
||||
case EXTI_EVENT:
|
||||
EXTI_EVEN(EXTI_REG_VAL(linex)) |= EXTI_BIT_POS(linex);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* set the EXTI trigger type */
|
||||
switch(trig_type) {
|
||||
case EXTI_TRIG_RISING:
|
||||
EXTI_RTEN(EXTI_REG_VAL(linex)) |= EXTI_BIT_POS(linex);
|
||||
EXTI_FTEN(EXTI_REG_VAL(linex)) &= ~EXTI_BIT_POS(linex);
|
||||
break;
|
||||
case EXTI_TRIG_FALLING:
|
||||
EXTI_RTEN(EXTI_REG_VAL(linex)) &= ~EXTI_BIT_POS(linex);
|
||||
EXTI_FTEN(EXTI_REG_VAL(linex)) |= EXTI_BIT_POS(linex);
|
||||
break;
|
||||
case EXTI_TRIG_BOTH:
|
||||
EXTI_RTEN(EXTI_REG_VAL(linex)) |= EXTI_BIT_POS(linex);
|
||||
EXTI_FTEN(EXTI_REG_VAL(linex)) |= EXTI_BIT_POS(linex);
|
||||
break;
|
||||
case EXTI_TRIG_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the interrupts from EXTI line x
|
||||
\param[in] linex: EXTI line number, refer to exti_line_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXTI_x (x=0..37): EXTI line x
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exti_interrupt_enable(exti_line_enum linex)
|
||||
{
|
||||
EXTI_INTEN(EXTI_REG_VAL(linex)) |= EXTI_BIT_POS(linex);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the interrupts from EXTI line x
|
||||
\param[in] linex: EXTI line number, refer to exti_line_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXTI_x (x=0..37): EXTI line x
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exti_interrupt_disable(exti_line_enum linex)
|
||||
{
|
||||
EXTI_INTEN(EXTI_REG_VAL(linex)) &= ~EXTI_BIT_POS(linex);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the events from EXTI line x
|
||||
\param[in] linex: EXTI line number, refer to exti_line_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXTI_x (x=0..37): EXTI line x
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exti_event_enable(exti_line_enum linex)
|
||||
{
|
||||
EXTI_EVEN(EXTI_REG_VAL(linex)) |= EXTI_BIT_POS(linex);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the events from EXTI line x
|
||||
\param[in] linex: EXTI line number, refer to exti_line_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXTI_x (x=0..37): EXTI line x
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exti_event_disable(exti_line_enum linex)
|
||||
{
|
||||
EXTI_EVEN(EXTI_REG_VAL(linex)) &= ~EXTI_BIT_POS(linex);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the software interrupt event from EXTI line x
|
||||
\param[in] linex: EXTI line number, refer to exti_line_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXTI_x (x=0..37): EXTI line x
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exti_software_interrupt_enable(exti_line_enum linex)
|
||||
{
|
||||
EXTI_SWIEV(EXTI_REG_VAL(linex)) |= EXTI_BIT_POS(linex);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the software interrupt event from EXTI line x
|
||||
\param[in] linex: EXTI line number, refer to exti_line_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXTI_x (x=0..37): EXTI line x
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exti_software_interrupt_disable(exti_line_enum linex)
|
||||
{
|
||||
EXTI_SWIEV(EXTI_REG_VAL(linex)) &= ~EXTI_BIT_POS(linex);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get EXTI line x interrupt pending flag
|
||||
\param[in] linex: EXTI line number, refer to exti_line_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXTI_x (x=0..37): EXTI line x
|
||||
\param[out] none
|
||||
\retval FlagStatus: status of flag (RESET or SET)
|
||||
*/
|
||||
FlagStatus exti_flag_get(exti_line_enum linex)
|
||||
{
|
||||
if(RESET != (EXTI_PD(EXTI_REG_VAL(linex)) & EXTI_BIT_POS(linex))) {
|
||||
return SET;
|
||||
} else {
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear EXTI line x interrupt pending flag
|
||||
\param[in] linex: EXTI line number, refer to exti_line_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXTI_x (x=0..37): EXTI line x
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exti_flag_clear(exti_line_enum linex)
|
||||
{
|
||||
EXTI_PD(EXTI_REG_VAL(linex)) = EXTI_BIT_POS(linex);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get EXTI line x interrupt pending flag
|
||||
\param[in] linex: EXTI line number, refer to exti_line_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXTI_x (x=0..37): EXTI line x
|
||||
\param[out] none
|
||||
\retval FlagStatus: status of flag (RESET or SET)
|
||||
*/
|
||||
FlagStatus exti_interrupt_flag_get(exti_line_enum linex)
|
||||
{
|
||||
if(RESET != (EXTI_PD(EXTI_REG_VAL(linex)) & EXTI_BIT_POS(linex))) {
|
||||
return SET;
|
||||
} else {
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear EXTI line x interrupt pending flag
|
||||
\param[in] linex: EXTI line number, refer to exti_line_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXTI_x (x=0..37): EXTI line x
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exti_interrupt_flag_clear(exti_line_enum linex)
|
||||
{
|
||||
EXTI_PD(EXTI_REG_VAL(linex)) = EXTI_BIT_POS(linex);
|
||||
}
|
||||
@@ -0,0 +1,659 @@
|
||||
/*!
|
||||
\file gd32h7xx_fac.c
|
||||
\brief FAC driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_fac.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/*!
|
||||
\brief reset FAC peripheral
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fac_deinit(void)
|
||||
{
|
||||
rcu_periph_reset_enable(RCU_FACRST);
|
||||
rcu_periph_reset_disable(RCU_FACRST);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the FAC filter parameter struct with the default values
|
||||
\param[in] fac_parameter: fac parameter struct
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fac_struct_para_init(fac_parameter_struct *fac_parameter)
|
||||
{
|
||||
fac_parameter->input_addr = 0U;
|
||||
fac_parameter->input_size = 0U;
|
||||
fac_parameter->input_threshold = 0U;
|
||||
fac_parameter->coeff_addr = 0U;
|
||||
fac_parameter->coeff_size = 0U;
|
||||
fac_parameter->output_addr = 0U;
|
||||
fac_parameter->output_size = 0U;
|
||||
fac_parameter->output_threshold = 0U;
|
||||
fac_parameter->clip = 0U;
|
||||
fac_parameter->func = 0U;
|
||||
fac_parameter->ipp = 0U;
|
||||
fac_parameter->ipq = 0U;
|
||||
fac_parameter->ipr = 0U;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the FAC fixed data preload parameter struct with the default values
|
||||
\param[in] fac_parameter: fac parameter struct
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fac_fixed_data_preload_init(fac_fixed_data_preload_struct *init_struct)
|
||||
{
|
||||
init_struct->coeffa_size = 0U;
|
||||
init_struct->coeffa_ctx = 0U;
|
||||
init_struct->coeffb_size = 0U;
|
||||
init_struct->coeffb_ctx = 0U;
|
||||
init_struct->input_size = 0U;
|
||||
init_struct->input_ctx = 0U;
|
||||
init_struct->output_size = 0U;
|
||||
init_struct->output_ctx = 0U;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the FAC float data preload parameter struct with the default values
|
||||
\param[in] fac_parameter: fac parameter struct
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fac_float_data_preload_init(fac_float_data_preload_struct *init_struct)
|
||||
{
|
||||
init_struct->coeffa_size = 0U;
|
||||
init_struct->coeffa_ctx = 0U;
|
||||
init_struct->coeffb_size = 0U;
|
||||
init_struct->coeffb_ctx = 0U;
|
||||
init_struct->input_size = 0U;
|
||||
init_struct->input_ctx = 0U;
|
||||
init_struct->output_size = 0U;
|
||||
init_struct->output_ctx = 0U;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the FAC peripheral
|
||||
\param[in] init_struct: the data needed to initialize FAC
|
||||
input_addr: x0 buffer base address, 0..255
|
||||
input_size: x0 buffer size, 0..255
|
||||
input_threshold: FAC_THRESHOLD_1, FAC_THRESHOLD_2,
|
||||
FAC_THRESHOLD_4, FAC_THRESHOLD_8
|
||||
coeff_addr: x1 buffer base address, 0..255
|
||||
coeff_size: x1 buffer size, 0..255
|
||||
output_addr: Y buffer base address, 0..255
|
||||
output_size: Y buffer size, 0..255
|
||||
output_threshold: FAC_THRESHOLD_1, FAC_THRESHOLD_2,
|
||||
FAC_THRESHOLD_4, FAC_THRESHOLD_8
|
||||
clip: enable or disable the clipping feature
|
||||
ipp: value IPP (vector length, number of filter taps, etc.)
|
||||
ipq: value IPQ (vector length, etc.)
|
||||
ipr: value IPR (gain, etc.)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fac_init(fac_parameter_struct *fac_parameter)
|
||||
{
|
||||
/* FAC_X0BCFG: configure the input X0 buffer */
|
||||
FAC_X0BCFG = ((((uint32_t)fac_parameter->input_addr) & FAC_X0BCFG_X0B_ADDR) | \
|
||||
((((uint32_t)fac_parameter->input_size) << 8U) & FAC_X0BCFG_X0B_SIZE));
|
||||
|
||||
/* FAC_X0BCFG: configure the input X0 threshold */
|
||||
FAC_X0BCFG |= (((uint32_t)fac_parameter->input_threshold) & FAC_X0BCFG_X0_WBFF);
|
||||
|
||||
/* FAC_X1BCFG: configure the coefficient X1 buffer */
|
||||
FAC_X1BCFG = ((((uint32_t)fac_parameter->coeff_addr) & FAC_X1BCFG_X1B_ADDR) | \
|
||||
((((uint32_t)fac_parameter->coeff_size) << 8U) & FAC_X1BCFG_X1B_SIZE));
|
||||
|
||||
/* FAC_YBCFG: configure the output Y buffer */
|
||||
FAC_YBCFG = ((((uint32_t)fac_parameter->output_addr) & FAC_YBCFG_YB_ADDR) | \
|
||||
((((uint32_t)fac_parameter->output_size) << 8U) & FAC_YBCFG_YB_SIZE));
|
||||
|
||||
/* FAC_YBCFG: configure the output Y threshold */
|
||||
FAC_YBCFG |= (((uint32_t)fac_parameter->output_threshold) & FAC_YBCFG_Y_WBEF);
|
||||
|
||||
/* FAC_CTL: configure the state of clip */
|
||||
FAC_CTL |= ((((uint32_t)fac_parameter->clip) << 15U) & FAC_CTL_CPEN);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief FAC preload X0 X1 Y fixed buffer
|
||||
\param[in] init_struct: FAC preload init struct
|
||||
coeffa_size: size of the coefficient vector A,0~255
|
||||
coeffa_ctx: [IIR only] content of the coefficient vector A
|
||||
coeffb_size: size of the coefficient vector B
|
||||
coeffb_ctx: size of the coefficient vector B
|
||||
input_size: size of the input data,0~255
|
||||
input_ctx: content of the input data
|
||||
output_size: size of the output data,0~255
|
||||
output_ctx: content of the output data
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg PRELOAD_DMA_MODE: preload access buffer mode with dma
|
||||
\arg PRELOAD_POLLING_MODE: preload access buffer mode with polling
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fac_fixed_buffer_preload(fac_fixed_data_preload_struct *init_struct)
|
||||
{
|
||||
/* FAC_PARACFG: configure parameter of filter preload */
|
||||
FAC_PARACFG = ((uint32_t)init_struct->input_size & FAC_PARACFG_IPP) | \
|
||||
FUNC_LOAD_X0 | FAC_PARACFG_EXE;
|
||||
|
||||
/* load the X0 buffer for input data */
|
||||
fac_fixed_data_preload(init_struct->input_size, init_struct->input_ctx);
|
||||
/* configure dma for X0 preload */
|
||||
|
||||
/* FAC_PARACFG: configure parameter of filter preload */
|
||||
FAC_PARACFG = (((uint32_t)init_struct->coeffb_size) & FAC_PARACFG_IPP) | \
|
||||
((((uint32_t)init_struct->coeffa_size) << 8) & FAC_PARACFG_IPQ) | \
|
||||
FUNC_LOAD_X1 | FAC_PARACFG_EXE;
|
||||
|
||||
/* load the x1 buffer for cofficientB */
|
||||
fac_fixed_data_preload(init_struct->coeffb_size, (init_struct->coeffb_ctx));
|
||||
|
||||
/* load the x1 buffer for cofficientA */
|
||||
if((NULL != init_struct->coeffa_ctx) && (0U != init_struct->coeffa_size)) {
|
||||
/* Load the buffer into the internal memory */
|
||||
fac_fixed_data_preload(init_struct->coeffa_size, (init_struct->coeffa_ctx));
|
||||
}
|
||||
/* if need configure to preload output buffer */
|
||||
if((NULL != init_struct->output_ctx) && (0U != init_struct->output_size)) {
|
||||
FAC_PARACFG = ((uint32_t)init_struct->output_size & FAC_PARACFG_IPP) | \
|
||||
FUNC_LOAD_Y | FAC_PARACFG_EXE;
|
||||
|
||||
/* load the Y buffer for input data */
|
||||
fac_fixed_data_preload(init_struct->output_size, init_struct->output_ctx);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief FAC preload X0 X1 Y float buffer
|
||||
\param[in] init_struct: FAC preload init struct
|
||||
coeffa_size: size of the coefficient vector A,0~255
|
||||
coeffa_ctx: [IIR only] content of the coefficient vector A
|
||||
coeffb_size: size of the coefficient vector B
|
||||
coeffb_ctx: size of the coefficient vector B
|
||||
input_size: size of the input data,0~255
|
||||
input_ctx: content of the input data
|
||||
output_size: size of the output data,0~255
|
||||
output_ctx: content of the output data
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg PRELOAD_DMA_MODE: preload access buffer mode with dma
|
||||
\arg PRELOAD_POLLING_MODE: preload access buffer mode with polling
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fac_float_buffer_preload(fac_float_data_preload_struct *init_struct)
|
||||
{
|
||||
/* FAC_PARACFG: Config parameter of filter preload */
|
||||
FAC_PARACFG = ((uint32_t)init_struct->input_size & FAC_PARACFG_IPP) | \
|
||||
FUNC_LOAD_X0 | FAC_PARACFG_EXE;
|
||||
|
||||
/* load the x0 buffer for input data */
|
||||
fac_float_data_preload(init_struct->input_size, init_struct->input_ctx);
|
||||
/* configure dma for x0 preload */
|
||||
/* FAC_PARACFG: Config parameter of filter preload */
|
||||
FAC_PARACFG = (((uint32_t)init_struct->coeffb_size) & FAC_PARACFG_IPP) | \
|
||||
((((uint32_t)init_struct->coeffa_size) << 8) & FAC_PARACFG_IPQ) | \
|
||||
FUNC_LOAD_X1 | FAC_PARACFG_EXE;
|
||||
|
||||
/* load the x1 buffer for cofficientB */
|
||||
fac_float_data_preload(init_struct->coeffb_size, (init_struct->coeffb_ctx));
|
||||
|
||||
/* load the x1 buffer for cofficientA */
|
||||
if((NULL != init_struct->coeffa_ctx) && (0U != init_struct->coeffa_size)) {
|
||||
/* load the buffer into the internal memory */
|
||||
fac_float_data_preload(init_struct->coeffa_size, (init_struct->coeffa_ctx));
|
||||
}
|
||||
/* if need configure to preload output buffer */
|
||||
if((NULL != init_struct->output_ctx) && (0U != init_struct->output_size)) {
|
||||
FAC_PARACFG = ((uint32_t)init_struct->output_size & FAC_PARACFG_IPP) | \
|
||||
FUNC_LOAD_Y | FAC_PARACFG_EXE;
|
||||
|
||||
/* load the Y buffer for input data */
|
||||
fac_float_data_preload(init_struct->output_size, init_struct->output_ctx);
|
||||
}
|
||||
}
|
||||
/*!
|
||||
\brief FAC preload fixed data pointer
|
||||
\param[in] array: 16-bit data
|
||||
\param[in] size: size of data
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fac_fixed_data_preload(uint8_t size, int16_t array[])
|
||||
{
|
||||
uint8_t i;
|
||||
for(i = 0U; i < size; i++) {
|
||||
FAC_WDATA = ((*((uint16_t*)&array[i])) & FAC_WDATA_WDATA);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief FAC preload float data pointer
|
||||
\param[in] data: 32-bit data
|
||||
\param[in] size: size of data
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fac_float_data_preload(uint8_t size, float array[])
|
||||
{
|
||||
uint8_t i;
|
||||
for(i = 0U; i < size; i++) {
|
||||
FAC_WDATA = ((*((uint32_t*) & array[i])));
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief FAC reset write and read pointers. the internal control logic,FAC_STAT register and the FAC_PARACFG register is reset
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fac_reset(void)
|
||||
{
|
||||
FAC_CTL |= FAC_CTL_RST;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the FAC clip feature
|
||||
\param[in] cpmod: the state of clip
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg FAC_CP_ENABLE: ENABLE CLIP
|
||||
\arg FAC_CP_DISABLE: DISABLE CLIP
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fac_clip_config(uint8_t cpmod)
|
||||
{
|
||||
if(FAC_CP_ENABLE == cpmod) {
|
||||
FAC_CTL |= FAC_CTL_CPEN;
|
||||
} else {
|
||||
FAC_CTL &= ~(FAC_CTL_CPEN);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable FAC float point format
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fac_float_enable(void)
|
||||
{
|
||||
FAC_CTL |= FAC_CTL_FLTEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable FAC float point format
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fac_float_disable(void)
|
||||
{
|
||||
FAC_CTL &= ~FAC_CTL_FLTEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the FAC DMA
|
||||
\param[in] dma_req: dma transfer type
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg FAC_DMA_READ: read buffer dma
|
||||
\arg FAC_DMA_WRITE: write buffer dma
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fac_dma_enable(uint32_t dma_req)
|
||||
{
|
||||
FAC_CTL |= dma_req;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the FAC DMA
|
||||
\param[in] dma_req: dma transfer type
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg FAC_DMA_READ: read buffer dma
|
||||
\arg FAC_DMA_WRITE: write buffer dma
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fac_dma_disable(uint32_t dma_req)
|
||||
{
|
||||
FAC_CTL &= ~dma_req;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief FAC configure input buffer
|
||||
\param[in] watermark: threshold of input buffer
|
||||
FAC_THRESHOLD_1, FAC_THRESHOLD_2,
|
||||
FAC_THRESHOLD_4, FAC_THRESHOLD_8
|
||||
\param[in] baseaddr: base address of input buffer, 0..255
|
||||
\param[in] bufsize: buffer size of input buffer, 0..255
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fac_x0_config(uint32_t watermark, uint8_t baseaddr, uint8_t bufsize)
|
||||
{
|
||||
/* set base address */
|
||||
FAC_X0BCFG &= ~FAC_X0BCFG_X0B_ADDR;
|
||||
FAC_X0BCFG |= ((uint32_t)baseaddr);
|
||||
|
||||
/* set buffer size */
|
||||
FAC_X0BCFG &= ~FAC_X0BCFG_X0B_SIZE;
|
||||
FAC_X0BCFG |= (((uint32_t)bufsize) << 8U);
|
||||
|
||||
/* set watermark */
|
||||
FAC_X0BCFG &= ~FAC_X0BCFG_X0_WBFF;
|
||||
FAC_X0BCFG |= watermark;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief FAC configure coefficient buffer
|
||||
\param[in] baseaddr: base address of coefficient buffer, 0..255
|
||||
\param[in] bufsize: buffer size of coefficient buffer, 0..255
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fac_x1_config(uint8_t baseaddr, uint8_t bufsize)
|
||||
{
|
||||
/* set base address */
|
||||
FAC_X1BCFG &= ~FAC_X1BCFG_X1B_ADDR;
|
||||
FAC_X1BCFG |= ((uint32_t)baseaddr);
|
||||
|
||||
/* set buffer size */
|
||||
FAC_X1BCFG &= ~FAC_X1BCFG_X1B_SIZE;
|
||||
FAC_X1BCFG |= (((uint32_t)bufsize) << 8U);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief FAC configure output buffer
|
||||
\param[in] watermark: threshold of output buffer
|
||||
FAC_THRESHOLD_1, FAC_THRESHOLD_2,
|
||||
FAC_THRESHOLD_4, FAC_THRESHOLD_8
|
||||
\param[in] baseaddr: base address of output buffer, 0..255
|
||||
\param[in] bufsize: buffer size of output buffer, 0..255
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fac_y_config(uint32_t watermark, uint8_t baseaddr, uint8_t bufsize)
|
||||
{
|
||||
/* set base address */
|
||||
FAC_YBCFG &= ~FAC_YBCFG_YB_ADDR;
|
||||
FAC_YBCFG |= ((uint32_t)baseaddr);
|
||||
|
||||
/* set buffer size */
|
||||
FAC_YBCFG &= ~FAC_YBCFG_YB_SIZE;
|
||||
FAC_YBCFG |= (((uint32_t)bufsize) << 8U);
|
||||
|
||||
/* set watermark */
|
||||
FAC_YBCFG &= ~FAC_YBCFG_Y_WBEF;
|
||||
FAC_YBCFG |= watermark;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief FAC configure execute function
|
||||
\param[in] func: select function to excute
|
||||
FUNC_CONVO_FIR, FUNC_IIR_DIRECT_FORM_1
|
||||
\param[in] ipp: parameter of forward coefficient, 2..64
|
||||
\param[in] ipq: parameter of backward coefficient, 1..63
|
||||
\param[in] ipr: parameter of gain, 0..7
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fac_function_config(fac_parameter_struct *fac_parameter)
|
||||
{
|
||||
/* set function */
|
||||
FAC_PARACFG &= ~FAC_PARACFG_FUN;
|
||||
FAC_PARACFG |= fac_parameter->func;
|
||||
|
||||
/* set filter parameter */
|
||||
FAC_PARACFG &= ~(FAC_PARACFG_IPP | FAC_PARACFG_IPQ | FAC_PARACFG_IPR);
|
||||
FAC_PARACFG |= ((uint32_t)fac_parameter->ipp) | (((uint32_t)fac_parameter->ipq) << 8U) | (((uint32_t)fac_parameter->ipr) << 16U);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief start the fac
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fac_start(void)
|
||||
{
|
||||
/* set start */
|
||||
FAC_PARACFG |= FAC_PARACFG_EXE;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief stop the fac
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fac_stop(void)
|
||||
{
|
||||
/* set start */
|
||||
FAC_PARACFG &= ~FAC_PARACFG_EXE;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief finish the filter calculate
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fac_finish_calculate(void)
|
||||
{
|
||||
/* clear execute */
|
||||
FAC_PARACFG &= ~FAC_PARACFG_EXE;
|
||||
|
||||
/* disable read and write interrupt */
|
||||
fac_interrupt_disable(FAC_CTL_RIE | FAC_CTL_WIE);
|
||||
|
||||
/* disable read and write dma */
|
||||
fac_dma_disable(FAC_DMA_READ);
|
||||
fac_dma_disable(FAC_DMA_WRITE);
|
||||
|
||||
/* reset register and pointer */
|
||||
FAC_CTL |= FAC_CTL_RST;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief FAC write data with fixed ponit format
|
||||
\param[in] data: 16-bit data
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fac_fixed_data_write(int16_t data)
|
||||
{
|
||||
FAC_WDATA_INT = (int16_t)data;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief FAC read data with fixed point format
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval 16-bit data
|
||||
*/
|
||||
int16_t fac_fixed_data_read(void)
|
||||
{ int16_t value;
|
||||
value = (int16_t)FAC_RDATA_INT;
|
||||
return value;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief FAC write data with float ponit format
|
||||
\param[in] data: 16-bit data
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fac_float_data_write(float data)
|
||||
{
|
||||
FAC_WDATA_FLOAT = (float)data;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief FAC read data with fixed point format
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval 16-bit data
|
||||
*/
|
||||
float fac_float_data_read(void)
|
||||
{
|
||||
float value;
|
||||
value = (float)FAC_RDATA_FLOAT;
|
||||
return value;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the FAC Interrupt
|
||||
\param[in] interrupt: FAC Interrupt
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg FAC_CTL_RIE: Read buffer interrupt
|
||||
\arg FAC_CTL_WIE: Write buffer interrupt
|
||||
\arg FAC_CTL_OFEIE: Overflow error interrupt
|
||||
\arg FAC_CTL_UFEIE: Underflow error interrupt
|
||||
\arg FAC_CTL_STEIE: Saturation error interrupt
|
||||
\arg FAC_CTL_GSTEIE: gain saturation error interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fac_interrupt_enable(uint32_t interrupt)
|
||||
{
|
||||
FAC_CTL |= interrupt;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the FAC Interrupt
|
||||
\param[in] interrupt: FAC Interrupt
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg FAC_CTL_RIE: Read buffer interrupt
|
||||
\arg FAC_CTL_WIE: Write buffer interrupt
|
||||
\arg FAC_CTL_OFEIE: Overflow error interrupt
|
||||
\arg FAC_CTL_UFEIE: Underflow error interrupt
|
||||
\arg FAC_CTL_STEIE: Saturation error interrupt
|
||||
\arg FAC_CTL_GSTEIE: gain saturation error interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fac_interrupt_disable(uint32_t interrupt)
|
||||
{
|
||||
FAC_CTL &= ~interrupt;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get FAC interrupt flag status
|
||||
\param[in] interrupt: FAC interrupt flag status
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg FAC_INT_FLAG_YBEF: Y buffer read interrupt flag
|
||||
\arg FAC_INT_FLAG_X0BFF: X0 buffer write interrupt flag
|
||||
\arg FAC_INT_FLAG_OFEF: overflow error interrupt flag
|
||||
\arg FAC_INT_FLAG_UFEF: underflow error interrupt flag
|
||||
\arg FAC_INT_FLAG_STEF: saturation error interrupt flag
|
||||
\arg FAC_INT_FLAG_GSTEF: gain saturation error interrupt flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus fac_interrupt_flag_get(uint8_t interrupt)
|
||||
{
|
||||
uint32_t reg1 = FAC_CTL;
|
||||
uint32_t reg2 = FAC_STAT;
|
||||
|
||||
switch(interrupt) {
|
||||
/* Y buffer read interrupt */
|
||||
case FAC_INT_FLAG_YBEF:
|
||||
reg1 = reg1 & FAC_CTL_RIE;
|
||||
reg2 = (((reg2 & FAC_STAT_YBEF) == 0U)?FAC_STAT_YBEF:0U);
|
||||
break;
|
||||
/* X0 buffer write interrupt */
|
||||
case FAC_INT_FLAG_X0BFF:
|
||||
reg1 = reg1 & FAC_CTL_WIE;
|
||||
reg2 = (((reg2 & FAC_STAT_X0BFF) == 0U)?FAC_STAT_X0BFF:0U);
|
||||
break;
|
||||
/* overflow error interrupt */
|
||||
case FAC_INT_FLAG_OFEF:
|
||||
reg1 = reg1 & FAC_CTL_OFEIE;
|
||||
reg2 = reg2 & FAC_STAT_OFEF;
|
||||
break;
|
||||
/* underflow error interrupt */
|
||||
case FAC_INT_FLAG_UFEF:
|
||||
reg1 = reg1 & FAC_CTL_UFEIE;
|
||||
reg2 = reg2 & FAC_STAT_UFEF;
|
||||
break;
|
||||
/* saturation error interrupt */
|
||||
case FAC_INT_FLAG_STEF:
|
||||
reg1 = reg1 & FAC_CTL_STEIE;
|
||||
reg2 = reg2 & FAC_STAT_STEF;
|
||||
break;
|
||||
/* saturation error interrupt */
|
||||
case FAC_INT_FLAG_GSTEF:
|
||||
reg1 = reg1 & FAC_CTL_GSTEIE;
|
||||
reg2 = reg2 & FAC_STAT_GSTEF;
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
/*get FAC interrupt flag status */
|
||||
if(reg1 && reg2) {
|
||||
return SET;
|
||||
} else {
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get FAC flag status
|
||||
\param[in] flag: FAC flag status
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg FAC_FLAG_YBEF: Y buffer empty flag
|
||||
\arg FAC_FLAG_X0BFF: X0 buffer full flag
|
||||
\arg FAC_FLAG_OFEF: overflow error flag
|
||||
\arg FAC_FLAG_UFEF: underflow error flag
|
||||
\arg FAC_FLAG_STEF: saturation error flag
|
||||
\arg FAC_FLAG_GSTEF: gain saturation error flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus fac_flag_get(uint32_t flag)
|
||||
{
|
||||
if(FAC_STAT & flag) {
|
||||
return SET;
|
||||
} else {
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,250 @@
|
||||
/*!
|
||||
\file gd32h7xx_fwdgt.c
|
||||
\brief FWDGT driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_fwdgt.h"
|
||||
|
||||
/* write value to FWDGT_CTL_CMD bit field */
|
||||
#define CTL_CMD(regval) (BITS(0,15) & ((uint32_t)(regval) << 0U))
|
||||
/* write value to FWDGT_RLD_RLD bit field */
|
||||
#define RLD_RLD(regval) (BITS(0,11) & ((uint32_t)(regval) << 0U))
|
||||
/* write value to FWDGT_WND_WND bit field */
|
||||
#define WND_WND(regval) (BITS(0,11) & ((uint32_t)(regval) << 0U))
|
||||
|
||||
/*!
|
||||
\brief enable write access to FWDGT_PSC, FWDGT_RLD and FWDGT_WND
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fwdgt_write_enable(void)
|
||||
{
|
||||
FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable write access to FWDGT_PSC, FWDGT_RLD and FWDGT_WND
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fwdgt_write_disable(void)
|
||||
{
|
||||
FWDGT_CTL = FWDGT_WRITEACCESS_DISABLE;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief start the FWDGT counter
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fwdgt_enable(void)
|
||||
{
|
||||
FWDGT_CTL = FWDGT_KEY_ENABLE;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the FWDGT counter prescaler value
|
||||
\param[in] prescaler_value: specify prescaler value
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg FWDGT_PSC_DIV4: FWDGT prescaler set to 4
|
||||
\arg FWDGT_PSC_DIV8: FWDGT prescaler set to 8
|
||||
\arg FWDGT_PSC_DIV16: FWDGT prescaler set to 16
|
||||
\arg FWDGT_PSC_DIV32: FWDGT prescaler set to 32
|
||||
\arg FWDGT_PSC_DIV64: FWDGT prescaler set to 64
|
||||
\arg FWDGT_PSC_DIV128: FWDGT prescaler set to 128
|
||||
\arg FWDGT_PSC_DIV256: FWDGT prescaler set to 256
|
||||
\param[out] none
|
||||
\retval ErrStatus: ERROR or SUCCESS
|
||||
*/
|
||||
ErrStatus fwdgt_prescaler_value_config(uint16_t prescaler_value)
|
||||
{
|
||||
uint32_t timeout = FWDGT_PSC_TIMEOUT;
|
||||
uint32_t flag_status = RESET;
|
||||
|
||||
/* enable write access to FWDGT_PSC */
|
||||
FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE;
|
||||
|
||||
/* wait until the PUD flag to be reset */
|
||||
do{
|
||||
flag_status = FWDGT_STAT & FWDGT_STAT_PUD;
|
||||
} while((--timeout > (uint32_t)0x00000000U) && (RESET != flag_status));
|
||||
|
||||
if(RESET != flag_status){
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* configure FWDGT */
|
||||
FWDGT_PSC = (uint32_t)prescaler_value;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the FWDGT counter reload value
|
||||
\param[in] reload_value: specify reload value(0x0000 - 0x0FFF)
|
||||
\param[out] none
|
||||
\retval ErrStatus: ERROR or SUCCESS
|
||||
*/
|
||||
ErrStatus fwdgt_reload_value_config(uint16_t reload_value)
|
||||
{
|
||||
uint32_t timeout = FWDGT_RLD_TIMEOUT;
|
||||
uint32_t flag_status = RESET;
|
||||
|
||||
/* enable write access to FWDGT_RLD */
|
||||
FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE;
|
||||
|
||||
/* wait until the RUD flag to be reset */
|
||||
do{
|
||||
flag_status = FWDGT_STAT & FWDGT_STAT_RUD;
|
||||
}while((--timeout > (uint32_t)0x00000000U) && ((uint32_t)RESET != flag_status));
|
||||
|
||||
if ((uint32_t)RESET != flag_status){
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
FWDGT_RLD = RLD_RLD(reload_value);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the FWDGT counter window value
|
||||
\param[in] window_value: specify window value(0x0000 - 0x0FFF)
|
||||
\param[out] none
|
||||
\retval ErrStatus: ERROR or SUCCESS
|
||||
*/
|
||||
ErrStatus fwdgt_window_value_config(uint16_t window_value)
|
||||
{
|
||||
uint32_t time_index = FWDGT_WND_TIMEOUT;
|
||||
uint32_t flag_status = RESET;
|
||||
|
||||
/* enable write access to FWDGT_WND */
|
||||
FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE;
|
||||
|
||||
/* wait until the WUD flag to be reset */
|
||||
do{
|
||||
flag_status = FWDGT_STAT & FWDGT_STAT_WUD;
|
||||
}while((--time_index > (uint32_t)0x00000000U) && ((uint32_t)RESET != flag_status));
|
||||
|
||||
if ((uint32_t)RESET != flag_status){
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
FWDGT_WND = WND_WND(window_value);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief reload the counter of FWDGT
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fwdgt_counter_reload(void)
|
||||
{
|
||||
FWDGT_CTL = FWDGT_KEY_RELOAD;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure counter reload value, and prescaler divider value
|
||||
\param[in] reload_value: specify reload value(0x0000 - 0x0FFF)
|
||||
\param[in] prescaler_div: FWDGT prescaler value
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg FWDGT_PSC_DIV4: FWDGT prescaler set to 4
|
||||
\arg FWDGT_PSC_DIV8: FWDGT prescaler set to 8
|
||||
\arg FWDGT_PSC_DIV16: FWDGT prescaler set to 16
|
||||
\arg FWDGT_PSC_DIV32: FWDGT prescaler set to 32
|
||||
\arg FWDGT_PSC_DIV64: FWDGT prescaler set to 64
|
||||
\arg FWDGT_PSC_DIV128: FWDGT prescaler set to 128
|
||||
\arg FWDGT_PSC_DIV256: FWDGT prescaler set to 256
|
||||
\param[out] none
|
||||
\retval ErrStatus: ERROR or SUCCESS
|
||||
*/
|
||||
ErrStatus fwdgt_config(uint16_t reload_value, uint8_t prescaler_div)
|
||||
{
|
||||
uint32_t timeout = FWDGT_PSC_TIMEOUT;
|
||||
uint32_t flag_status = RESET;
|
||||
|
||||
/* enable write access to FWDGT_PSC,and FWDGT_RLD */
|
||||
FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE;
|
||||
|
||||
/* wait until the PUD flag to be reset */
|
||||
do{
|
||||
flag_status = FWDGT_STAT & FWDGT_STAT_PUD;
|
||||
}while((--timeout > (uint32_t)0x00000000U) && ((uint32_t)RESET != flag_status));
|
||||
|
||||
if ((uint32_t)RESET != flag_status){
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* configure FWDGT */
|
||||
FWDGT_PSC = (uint32_t)prescaler_div;
|
||||
|
||||
timeout = FWDGT_RLD_TIMEOUT;
|
||||
/* wait until the RUD flag to be reset */
|
||||
do{
|
||||
flag_status = FWDGT_STAT & FWDGT_STAT_RUD;
|
||||
}while((--timeout > (uint32_t)0x00000000U) && ((uint32_t)RESET != flag_status));
|
||||
|
||||
if ((uint32_t)RESET != flag_status){
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
FWDGT_RLD = RLD_RLD(reload_value);
|
||||
|
||||
/* reload the counter */
|
||||
FWDGT_CTL = FWDGT_KEY_RELOAD;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get flag state of FWDGT
|
||||
\param[in] flag: flag to get
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg FWDGT_FLAG_PUD: a write operation to FWDGT_PSC register is on going
|
||||
\arg FWDGT_FLAG_RUD: a write operation to FWDGT_RLD register is on going
|
||||
\arg FWDGT_FLAG_WUD: a write operation to FWDGT_WND register is on going
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus fwdgt_flag_get(uint16_t flag)
|
||||
{
|
||||
if (RESET != (FWDGT_STAT & flag)){
|
||||
return SET;
|
||||
}
|
||||
return RESET;
|
||||
}
|
||||
@@ -0,0 +1,492 @@
|
||||
/*!
|
||||
\file gd32h7xx_gpio.c
|
||||
\brief GPIO driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_gpio.h"
|
||||
|
||||
/*!
|
||||
\brief reset GPIO port
|
||||
\param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,J,K)
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIOx(x = A,B,C,D,E,F,G,H,J,K)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void gpio_deinit(uint32_t gpio_periph)
|
||||
{
|
||||
switch(gpio_periph){
|
||||
case GPIOA:
|
||||
/* reset GPIOA */
|
||||
rcu_periph_reset_enable(RCU_GPIOARST);
|
||||
rcu_periph_reset_disable(RCU_GPIOARST);
|
||||
break;
|
||||
case GPIOB:
|
||||
/* reset GPIOB */
|
||||
rcu_periph_reset_enable(RCU_GPIOBRST);
|
||||
rcu_periph_reset_disable(RCU_GPIOBRST);
|
||||
break;
|
||||
case GPIOC:
|
||||
/* reset GPIOC */
|
||||
rcu_periph_reset_enable(RCU_GPIOCRST);
|
||||
rcu_periph_reset_disable(RCU_GPIOCRST);
|
||||
break;
|
||||
case GPIOD:
|
||||
/* reset GPIOD */
|
||||
rcu_periph_reset_enable(RCU_GPIODRST);
|
||||
rcu_periph_reset_disable(RCU_GPIODRST);
|
||||
break;
|
||||
case GPIOE:
|
||||
/* reset GPIOE */
|
||||
rcu_periph_reset_enable(RCU_GPIOERST);
|
||||
rcu_periph_reset_disable(RCU_GPIOERST);
|
||||
break;
|
||||
case GPIOF:
|
||||
/* reset GPIOF */
|
||||
rcu_periph_reset_enable(RCU_GPIOFRST);
|
||||
rcu_periph_reset_disable(RCU_GPIOFRST);
|
||||
break;
|
||||
case GPIOG:
|
||||
/* reset GPIOG */
|
||||
rcu_periph_reset_enable(RCU_GPIOGRST);
|
||||
rcu_periph_reset_disable(RCU_GPIOGRST);
|
||||
break;
|
||||
case GPIOH:
|
||||
/* reset GPIOH */
|
||||
rcu_periph_reset_enable(RCU_GPIOHRST);
|
||||
rcu_periph_reset_disable(RCU_GPIOHRST);
|
||||
break;
|
||||
case GPIOJ:
|
||||
/* reset GPIOJ */
|
||||
rcu_periph_reset_enable(RCU_GPIOJRST);
|
||||
rcu_periph_reset_disable(RCU_GPIOJRST);
|
||||
break;
|
||||
case GPIOK:
|
||||
/* reset GPIOK */
|
||||
rcu_periph_reset_enable(RCU_GPIOKRST);
|
||||
rcu_periph_reset_disable(RCU_GPIOKRST);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set GPIO mode
|
||||
\param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,J,K)
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIOx(x = A,B,C,D,E,F,G,H,J,K)
|
||||
\param[in] mode: gpio pin mode
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIO_MODE_INPUT: input mode
|
||||
\arg GPIO_MODE_OUTPUT: output mode
|
||||
\arg GPIO_MODE_AF: alternate function mode
|
||||
\arg GPIO_MODE_ANALOG: analog mode
|
||||
\param[in] pull_up_down: gpio pin with pull-up or pull-down resistor
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIO_PUPD_NONE: floating mode, no pull-up and pull-down resistors
|
||||
\arg GPIO_PUPD_PULLUP: with pull-up resistor
|
||||
\arg GPIO_PUPD_PULLDOWN:with pull-down resistor
|
||||
\param[in] pin: GPIO pin
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void gpio_mode_set(uint32_t gpio_periph, uint32_t mode, uint32_t pull_up_down, uint32_t pin)
|
||||
{
|
||||
uint16_t i;
|
||||
uint32_t ctl, pupd;
|
||||
|
||||
ctl = GPIO_CTL(gpio_periph);
|
||||
pupd = GPIO_PUD(gpio_periph);
|
||||
|
||||
for(i = 0U;i < 16U;i++){
|
||||
if((1U << i) & pin){
|
||||
/* clear the specified pin mode bits */
|
||||
ctl &= ~GPIO_MODE_MASK(i);
|
||||
/* set the specified pin mode bits */
|
||||
ctl |= GPIO_MODE_SET(i, mode);
|
||||
|
||||
/* clear the specified pin pupd bits */
|
||||
pupd &= ~GPIO_PUPD_MASK(i);
|
||||
/* set the specified pin pupd bits */
|
||||
pupd |= GPIO_PUPD_SET(i, pull_up_down);
|
||||
}
|
||||
}
|
||||
|
||||
GPIO_CTL(gpio_periph) = ctl;
|
||||
GPIO_PUD(gpio_periph) = pupd;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set GPIO output type and speed
|
||||
\param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,J,K)
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIOx(x = A,B,C,D,E,F,G,H,J,K)
|
||||
\param[in] otype: gpio pin output mode
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIO_OTYPE_PP: push pull mode
|
||||
\arg GPIO_OTYPE_OD: open drain mode
|
||||
\param[in] speed: gpio pin output max speed
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIO_OSPEED_12MHZ: output max speed 12MHz
|
||||
\arg GPIO_OSPEED_60MHZ: output max speed 60MHz
|
||||
\arg GPIO_OSPEED_85MHZ: output max speed 85MHz
|
||||
\arg GPIO_OSPEED_100_220MHZ: output max speed 100/220MHz
|
||||
\param[in] pin: GPIO pin
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void gpio_output_options_set(uint32_t gpio_periph, uint8_t otype, uint32_t speed, uint32_t pin)
|
||||
{
|
||||
uint16_t i;
|
||||
uint32_t ospeed;
|
||||
|
||||
if(GPIO_OTYPE_OD == otype){
|
||||
GPIO_OMODE(gpio_periph) |= (uint32_t)pin;
|
||||
}else{
|
||||
GPIO_OMODE(gpio_periph) &= (uint32_t)(~pin);
|
||||
}
|
||||
|
||||
/* get the specified pin output speed bits value */
|
||||
ospeed = GPIO_OSPD(gpio_periph);
|
||||
|
||||
for(i = 0U;i < 16U;i++){
|
||||
if((1U << i) & pin){
|
||||
/* clear the specified pin output speed bits */
|
||||
ospeed &= ~GPIO_OSPEED_MASK(i);
|
||||
/* set the specified pin output speed bits */
|
||||
ospeed |= GPIO_OSPEED_SET(i,speed);
|
||||
}
|
||||
}
|
||||
GPIO_OSPD(gpio_periph) = ospeed;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set GPIO pin bit
|
||||
\param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,J,K)
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIOx(x = A,B,C,D,E,F,G,H,J,K)
|
||||
\param[in] pin: GPIO pin
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void gpio_bit_set(uint32_t gpio_periph, uint32_t pin)
|
||||
{
|
||||
GPIO_BOP(gpio_periph) = (uint32_t)pin;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief reset GPIO pin bit
|
||||
\param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,J,K)
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIOx(x = A,B,C,F)
|
||||
\param[in] pin: GPIO pin
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void gpio_bit_reset(uint32_t gpio_periph, uint32_t pin)
|
||||
{
|
||||
GPIO_BC(gpio_periph) = (uint32_t)pin;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief write data to the specified GPIO pin
|
||||
\param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,J,K)
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIOx(x = A,B,C,D,E,F,G,H,J,K)
|
||||
\param[in] pin: GPIO pin
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
|
||||
\param[in] bit_value: SET or RESET
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg RESET: clear the port pin
|
||||
\arg SET: set the port pin
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void gpio_bit_write(uint32_t gpio_periph, uint32_t pin, bit_status bit_value)
|
||||
{
|
||||
if(RESET != bit_value){
|
||||
GPIO_BOP(gpio_periph) = (uint32_t)pin;
|
||||
}else{
|
||||
GPIO_BC(gpio_periph) = (uint32_t)pin;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief write data to the specified GPIO port
|
||||
\param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,J,K)
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIOx(x = A,B,C,D,E,F,G,H,J,K)
|
||||
\param[in] data: specify the value to be written to the port output control register
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void gpio_port_write(uint32_t gpio_periph, uint16_t data)
|
||||
{
|
||||
GPIO_OCTL(gpio_periph) = (uint32_t)data;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set GPIO input filter
|
||||
\param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,J,K)
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIOx(x = A,B,C,D,E,F,G,H,J,K)
|
||||
\param[in] speriod: gpio pin input sample period
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIO_ISPERIOD(x): x = 0 ~ 255
|
||||
\param[in] iftype: gpio pin input filtering type
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIO_IFTYPE_SYNC: input filter type synchronization
|
||||
\arg GPIO_IFTYPE_3_SAMPLE: input filter type filter 3 samples
|
||||
\arg GPIO_IFTYPE_6_SAMPLE: input filter type filter 6 samples
|
||||
\arg GPIO_IFTYPE_ASYNC: input filter type asynchronous
|
||||
\param[in] pin: GPIO pin
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void gpio_input_filter_set(uint32_t gpio_periph, uint8_t speriod, uint32_t iftype, uint32_t pin)
|
||||
{
|
||||
uint16_t i;
|
||||
uint32_t isperiod;
|
||||
uint32_t iftp;
|
||||
|
||||
isperiod = GPIO_IFL(gpio_periph);
|
||||
if(pin & 0x000000FFU){
|
||||
isperiod &= ~GPIO_IFL_FLPRD0;
|
||||
isperiod |= (uint32_t)speriod;
|
||||
}
|
||||
if(pin & 0x0000FF00U){
|
||||
isperiod &= ~GPIO_IFL_FLPRD1;
|
||||
isperiod |= ((uint32_t)speriod << 8U);
|
||||
}
|
||||
GPIO_IFL(gpio_periph) = isperiod;
|
||||
|
||||
/* get the specified pin output speed bits value */
|
||||
iftp = GPIO_IFTP(gpio_periph);
|
||||
for(i = 0U;i < 16U;i++){
|
||||
if((1U << i) & pin){
|
||||
/* clear the specified pin output speed bits */
|
||||
iftp &= ~GPIO_IFTYPE_MASK(i);
|
||||
/* set the specified pin output speed bits */
|
||||
iftp |= GPIO_IFTYPE_SET(i,iftype);
|
||||
}
|
||||
}
|
||||
GPIO_IFTP(gpio_periph) = iftp;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get GPIO pin input status
|
||||
\param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,J,K)
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIOx(x = A,B,C,D,E,F,G,H,J,K)
|
||||
\param[in] pin: GPIO pin
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
|
||||
\param[out] none
|
||||
\retval SET or RESET
|
||||
*/
|
||||
FlagStatus gpio_input_bit_get(uint32_t gpio_periph, uint32_t pin)
|
||||
{
|
||||
if((uint32_t)RESET != (GPIO_ISTAT(gpio_periph)&(pin))){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get GPIO port input status
|
||||
\param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,J,K)
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIOx(x = A,B,C,D,E,F,G,H,J,K)
|
||||
\param[out] none
|
||||
\retval state of GPIO all pins
|
||||
*/
|
||||
uint16_t gpio_input_port_get(uint32_t gpio_periph)
|
||||
{
|
||||
return ((uint16_t)GPIO_ISTAT(gpio_periph));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get GPIO pin output status
|
||||
\param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,J,K)
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIOx(x = A,B,C,D,E,F,G,H,J,K)
|
||||
\param[in] pin: GPIO pin
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
|
||||
\param[out] none
|
||||
\retval SET or RESET
|
||||
*/
|
||||
FlagStatus gpio_output_bit_get(uint32_t gpio_periph, uint32_t pin)
|
||||
{
|
||||
if((uint32_t)RESET != (GPIO_OCTL(gpio_periph)&(pin))){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get GPIO port output status
|
||||
\param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,J,K)
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIOx(x = A,B,C,D,E,F,G,H,J,K)
|
||||
\param[out] none
|
||||
\retval state of GPIO all pins
|
||||
*/
|
||||
uint16_t gpio_output_port_get(uint32_t gpio_periph)
|
||||
{
|
||||
return ((uint16_t)GPIO_OCTL(gpio_periph));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set GPIO alternate function
|
||||
\param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,J,K)
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIOx(x = A,B,C,D,E,F,G,H,J,K)
|
||||
\param[in] alt_func_num: GPIO pin af function, please refer to specific device datasheet
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIO_AF_0: SYSTEM, TIMER40, TIMER41, TIMER42, TIMER43, TIMER44
|
||||
\arg GPIO_AF_1: TIMER0, TIMER1, TIMER15, TIMER16, EXMC, SAI1, SAI2
|
||||
\arg GPIO_AF_2: TIMER2, TIMER3, TIMER4, TIMER7, TIMER14, TLI, CAN2, SAI0, EXMC
|
||||
\arg GPIO_AF_3: TIMER7, TIMER9, EDOUT, EXMC, TLI, HPDF, OSPIM
|
||||
\arg GPIO_AF_4: TIMER14, TIMER30, TIMER31, I2C0, I2C1, I2C2, I2C3, USART0, HPDF, OSPIM, TLI
|
||||
\arg GPIO_AF_5: SPI0, SPI1, SPI2, SPI3, SPI4, SPI5, CAN2
|
||||
\arg GPIO_AF_6: UART3, SPI2, I2C3, HPDF, SAI0, ETH1, EDOUT, OSPIM
|
||||
\arg GPIO_AF_7: USART0, USART1, USART2, USART5, UART6, TIMER40, TIMER41, TIMER42, TIMER43,
|
||||
SPI1, SPI2, SPI5, SDIO0, USBHS1
|
||||
\arg GPIO_AF_8: UART3, UART4, UART7, SPI5, SDIO0, RSPDIF, TIMER44, USBHS1, SAI1, SAI2
|
||||
\arg GPIO_AF_9: SDIO1, TRGSEL, CAN0, CAN1, TLI, OPSIM, EXMC, RSPDIF, SAI2
|
||||
\arg GPIO_AF_10: SAI1, SAI2, SDIO1, CMP, USBHS0, OPSIM, EXMC
|
||||
\arg GPIO_AF_11: ETH0, MDIO, CMP, UART6, EXMC, HPDF, I2C3, TLI, SDIO1, OPSIM
|
||||
\arg GPIO_AF_12: TIMER0, MDIOS, SDIO0, EXMC, OPSIM, CMP, TLI, USBHS1
|
||||
\arg GPIO_AF_13: TRGSEL, DCI, COMP0, CMP, TIMER22
|
||||
\arg GPIO_AF_14: TLI, UART4, TIMER23
|
||||
\arg GPIO_AF_15: EVENTOUT
|
||||
\param[in] pin: GPIO pin
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void gpio_af_set(uint32_t gpio_periph, uint32_t alt_func_num, uint32_t pin)
|
||||
{
|
||||
uint16_t i;
|
||||
uint32_t afrl, afrh;
|
||||
|
||||
afrl = GPIO_AFSEL0(gpio_periph);
|
||||
afrh = GPIO_AFSEL1(gpio_periph);
|
||||
|
||||
for(i = 0U;i < 8U;i++){
|
||||
if((1U << i) & pin){
|
||||
/* clear the specified pin alternate function bits */
|
||||
afrl &= ~GPIO_AFR_MASK(i);
|
||||
afrl |= GPIO_AFR_SET(i,alt_func_num);
|
||||
}
|
||||
}
|
||||
|
||||
for(i = 8U;i < 16U;i++){
|
||||
if((1U << i) & pin){
|
||||
/* clear the specified pin alternate function bits */
|
||||
afrh &= ~GPIO_AFR_MASK(i - 8U);
|
||||
afrh |= GPIO_AFR_SET(i - 8U,alt_func_num);
|
||||
}
|
||||
}
|
||||
|
||||
GPIO_AFSEL0(gpio_periph) = afrl;
|
||||
GPIO_AFSEL1(gpio_periph) = afrh;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief lock GPIO pin bit
|
||||
\param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,J,K)
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIOx(x = A,B,C,D,E,F,G,H,J,K)
|
||||
\param[in] pin: GPIO pin
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void gpio_pin_lock(uint32_t gpio_periph, uint32_t pin)
|
||||
{
|
||||
uint32_t lock = 0x00010000U;
|
||||
lock |= pin;
|
||||
|
||||
/* lock key writing sequence: write 1->write 0->write 1->read 0->read 1 */
|
||||
GPIO_LOCK(gpio_periph) = (uint32_t)lock;
|
||||
GPIO_LOCK(gpio_periph) = (uint32_t)pin;
|
||||
GPIO_LOCK(gpio_periph) = (uint32_t)lock;
|
||||
lock = GPIO_LOCK(gpio_periph);
|
||||
lock = GPIO_LOCK(gpio_periph);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief toggle GPIO pin status
|
||||
\param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,J,K)
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIOx(x = A,B,C,D,E,F,G,H,J,K)
|
||||
\param[in] pin: GPIO pin
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void gpio_bit_toggle(uint32_t gpio_periph, uint32_t pin)
|
||||
{
|
||||
GPIO_TG(gpio_periph) = (uint32_t)pin;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief toggle GPIO port status
|
||||
\param[in] gpio_periph: GPIOx(x = A,B,C,D,E,F,G,H,J,K)
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIOx(x = A,B,C,D,E,F,G,H,J,K)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void gpio_port_toggle(uint32_t gpio_periph)
|
||||
{
|
||||
GPIO_TG(gpio_periph) = 0x0000FFFFU;
|
||||
}
|
||||
@@ -0,0 +1,398 @@
|
||||
/*!
|
||||
\file gd32h7xx_hau.c
|
||||
\brief HAU driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_hau.h"
|
||||
#include "gd32h7xx_rcu.h"
|
||||
|
||||
#define HASH_CONTEXT_INTERNAL_REG 37U
|
||||
#define HMAC_CONTEXT_INTERNAL_REG 53U
|
||||
|
||||
/*!
|
||||
\brief reset the HAU peripheral
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void hau_deinit(void)
|
||||
{
|
||||
/* enable HAU reset state */
|
||||
rcu_periph_reset_enable(RCU_HAURST);
|
||||
/* release HAU from reset state */
|
||||
rcu_periph_reset_disable(RCU_HAURST);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the HAU peripheral parameters
|
||||
\param[in] initpara: HAU init parameter struct
|
||||
members of the structure and the member values are shown as below:
|
||||
algo: HAU_ALGO_SHA1, HAU_ALGO_SHA224, HAU_ALGO_SHA256, HAU_ALGO_MD5
|
||||
mode: HAU_MODE_HASH, HAU_MODE_HMAC
|
||||
datatype: HAU_SWAPPING_32BIT, HAU_SWAPPING_16BIT, HAU_SWAPPING_8BIT, HAU_SWAPPING_1BIT
|
||||
keytype: HAU_KEY_SHORTER_64, HAU_KEY_LONGGER_64
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void hau_init(hau_init_parameter_struct* initpara)
|
||||
{
|
||||
/* configure the algorithm, mode and the data type */
|
||||
HAU_CTL &= (~(uint32_t)(HAU_CTL_ALGM_0 | HAU_CTL_ALGM_1 | HAU_CTL_DATAM | HAU_CTL_HMS));
|
||||
HAU_CTL |= (initpara->algo | initpara->datatype | initpara->mode);
|
||||
|
||||
/* when mode is HMAC, set the key */
|
||||
if(HAU_MODE_HMAC == initpara->mode){
|
||||
HAU_CTL &= (~(uint32_t)HAU_CTL_KLM);
|
||||
HAU_CTL |= initpara->keytype;
|
||||
}
|
||||
|
||||
/* start the digest of a new message */
|
||||
HAU_CTL |= HAU_CTL_START;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the structure hau_initpara with default value
|
||||
\param[in] none
|
||||
\param[out] initpara: HAU init parameter struct
|
||||
\retval none
|
||||
*/
|
||||
void hau_init_struct_para_init(hau_init_parameter_struct* initpara)
|
||||
{
|
||||
initpara->algo = HAU_ALGO_SHA1;
|
||||
initpara->mode = HAU_MODE_HASH;
|
||||
initpara->datatype = HAU_SWAPPING_32BIT;
|
||||
initpara->keytype = HAU_KEY_SHORTER_64;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief reset the HAU processor core
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void hau_reset(void)
|
||||
{
|
||||
/* set to 1 to reset the HAU processor core, then it is ready to start the digest calculation */
|
||||
HAU_CTL |= HAU_CTL_START;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the number of valid bits in last word of the message
|
||||
\param[in] valid_num: number of valid bits in last word of the message
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg 0x00: all 32 bits of the last data written are valid
|
||||
\arg 0x01: only bit [31] of the last data written to HAU_DI after data swapping are valid
|
||||
\arg 0x02: only bits [31:30] of the last data written to HAU_DI after data swapping are valid
|
||||
\arg 0x03: only bits [31:29] of the last data written to HAU_DI after data swapping are valid
|
||||
...
|
||||
\arg 0x1F: only bits [31:1] of the last data written to HAU_DI after data swapping are valid
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void hau_last_word_validbits_num_config(uint32_t valid_num)
|
||||
{
|
||||
HAU_CFG &= (~(uint32_t)HAU_CFG_VBL);
|
||||
HAU_CFG |= CFG_VBL(valid_num);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief write data to the IN FIFO
|
||||
\param[in] data: data to write
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void hau_data_write(uint32_t data)
|
||||
{
|
||||
HAU_DI = data;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief return the number of words already written into the IN FIFO
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval number of words in the input FIFO
|
||||
*/
|
||||
uint32_t hau_infifo_words_num_get(void)
|
||||
{
|
||||
uint32_t ret = 0U;
|
||||
ret = GET_CTL_NWIF(HAU_CTL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief read the message digest result
|
||||
\param[in] none
|
||||
\param[out] digestpara: HAU digest parameter struct
|
||||
out[x](x = 0...7): message digest result 0-7
|
||||
\retval none
|
||||
*/
|
||||
void hau_digest_read(hau_digest_parameter_struct* digestpara)
|
||||
{
|
||||
digestpara->out[0] = HAU_DO0;
|
||||
digestpara->out[1] = HAU_DO1;
|
||||
digestpara->out[2] = HAU_DO2;
|
||||
digestpara->out[3] = HAU_DO3;
|
||||
digestpara->out[4] = HAU_DO4;
|
||||
digestpara->out[5] = HAU_DO5;
|
||||
digestpara->out[6] = HAU_DO6;
|
||||
digestpara->out[7] = HAU_DO7;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable digest calculation
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void hau_digest_calculation_enable(void)
|
||||
{
|
||||
HAU_CFG |= HAU_CFG_CALEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure single or multiple DMA is used, and digest calculation at the end of a DMA transfer or not
|
||||
\param[in] multi_single
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SINGLE_DMA_AUTO_DIGEST: message padding and message digest calculation at the end of a DMA transfer
|
||||
\arg MULTIPLE_DMA_NO_DIGEST: multiple DMA transfers needed and CALEN bit is not automatically set at the end of a DMA transfer
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void hau_multiple_single_dma_config(uint32_t multi_single)
|
||||
{
|
||||
HAU_CTL &= (~(uint32_t)HAU_CTL_MDS);
|
||||
HAU_CTL |= multi_single;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the HAU DMA interface
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void hau_dma_enable(void)
|
||||
{
|
||||
HAU_CTL |= HAU_CTL_DMAE;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the HAU DMA interface
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void hau_dma_disable(void)
|
||||
{
|
||||
HAU_CTL &= (~(uint32_t)HAU_CTL_DMAE);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the struct context
|
||||
\param[in] none
|
||||
\param[out] context: HAU context parameter struct
|
||||
\retval none
|
||||
*/
|
||||
void hau_context_struct_para_init(hau_context_parameter_struct* context)
|
||||
{
|
||||
uint8_t i = 0U;
|
||||
|
||||
/* initialize context parameter struct */
|
||||
context->hau_inten_bak = 0U;
|
||||
context->hau_cfg_bak = 0U;
|
||||
context->hau_ctl_bak = 0U;
|
||||
for(i = 0U; i <= HMAC_CONTEXT_INTERNAL_REG; i++){
|
||||
context->hau_ctxs_bak[i] = 0U;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief save the HAU peripheral context
|
||||
\param[in] none
|
||||
\param[out] context_save: pointer to a hau_context structure that contains the repository for current context
|
||||
\retval none
|
||||
*/
|
||||
void hau_context_save(hau_context_parameter_struct* context_save)
|
||||
{
|
||||
uint8_t i = 0U;
|
||||
uint8_t i_max = HASH_CONTEXT_INTERNAL_REG;
|
||||
|
||||
hau_context_struct_para_init(context_save);
|
||||
/* save context registers */
|
||||
context_save->hau_inten_bak = HAU_INTEN;
|
||||
context_save->hau_cfg_bak = HAU_CFG;
|
||||
context_save->hau_ctl_bak = HAU_CTL;
|
||||
|
||||
if(0U != (HAU_CTL & HAU_CTL_HMS)){
|
||||
i_max = HMAC_CONTEXT_INTERNAL_REG;
|
||||
}
|
||||
for(i = 0U; i <= i_max; i++){
|
||||
context_save->hau_ctxs_bak[i] = HAU_CTXS(i);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief restore the HAU peripheral context
|
||||
\param[in] context_restore: pointer to a hau_context_parameter_struct structure that contains the repository for saved context
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void hau_context_restore(hau_context_parameter_struct* context_restore)
|
||||
{
|
||||
uint8_t i = 0U;
|
||||
uint8_t i_max = HASH_CONTEXT_INTERNAL_REG;
|
||||
|
||||
/* restore context registers */
|
||||
HAU_INTEN = context_restore->hau_inten_bak;
|
||||
HAU_CFG = context_restore->hau_cfg_bak;
|
||||
HAU_CTL = context_restore->hau_ctl_bak;
|
||||
/* Initialize the hash processor */
|
||||
HAU_CTL |= HAU_CTL_START;
|
||||
|
||||
/* continue restoring context registers */
|
||||
if(0U != (HAU_CTL & HAU_CTL_HMS)){
|
||||
i_max = HMAC_CONTEXT_INTERNAL_REG;
|
||||
}
|
||||
for(i = 0U; i <= i_max; i++){
|
||||
HAU_CTXS(i) = context_restore->hau_ctxs_bak[i];
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the HAU flag status
|
||||
\param[in] flag: HAU flag status
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg HAU_FLAG_DATA_INPUT: there is enough space (16 bytes) in the input FIFO
|
||||
\arg HAU_FLAG_CALCULATION_COMPLETE: digest calculation is completed
|
||||
\arg HAU_FLAG_DMA: DMA is enabled (DMAE =1) or a transfer is processing
|
||||
\arg HAU_FLAG_BUSY: data block is in process
|
||||
\arg HAU_FLAG_INFIFO_NO_EMPTY: the input FIFO is not empty
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus hau_flag_get(uint32_t flag)
|
||||
{
|
||||
uint32_t ret = 0U;
|
||||
FlagStatus ret_flag = RESET;
|
||||
|
||||
/* check if the flag is in HAU_CTL register */
|
||||
if(RESET != (flag & HAU_FLAG_INFIFO_NO_EMPTY)){
|
||||
ret = HAU_CTL;
|
||||
}else{
|
||||
ret = HAU_STAT;
|
||||
}
|
||||
|
||||
if (RESET != (ret & flag)){
|
||||
ret_flag = SET;
|
||||
}
|
||||
|
||||
return ret_flag;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear the HAU flag status
|
||||
\param[in] flag: HAU flag status
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg HAU_FLAG_DATA_INPUT: there is enough space (16 bytes) in the input FIFO
|
||||
\arg HAU_FLAG_CALCULATION_COMPLETE: digest calculation is completed
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void hau_flag_clear(uint32_t flag)
|
||||
{
|
||||
HAU_STAT = ~(uint32_t)(flag);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the HAU interrupts
|
||||
\param[in] interrupt: specify the HAU interrupt source to be enabled
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg HAU_INT_DATA_INPUT: a new block can be entered into the IN buffer
|
||||
\arg HAU_INT_CALCULATION_COMPLETE: calculation complete
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void hau_interrupt_enable(uint32_t interrupt)
|
||||
{
|
||||
HAU_INTEN |= interrupt;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the HAU interrupts
|
||||
\param[in] interrupt: specify the HAU interrupt source to be disabled
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg HAU_INT_DATA_INPUT: a new block can be entered into the IN buffer
|
||||
\arg HAU_INT_CALCULATION_COMPLETE: calculation complete
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void hau_interrupt_disable(uint32_t interrupt)
|
||||
{
|
||||
HAU_INTEN &= ~(uint32_t)(interrupt);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the HAU interrupt flag status
|
||||
\param[in] int_flag: HAU interrupt flag status
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg HAU_INT_FLAG_DATA_INPUT: there is enough space (16 bytes) in the input FIFO
|
||||
\arg HAU_INT_FLAG_CALCULATION_COMPLETE: digest calculation is completed
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus hau_interrupt_flag_get(uint32_t int_flag)
|
||||
{
|
||||
uint32_t ret = 0U;
|
||||
FlagStatus flag = RESET;
|
||||
|
||||
/* return the status of the interrupt */
|
||||
ret = HAU_STAT;
|
||||
|
||||
if(RESET != ((HAU_INTEN & ret) & int_flag)){
|
||||
flag = SET;
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear the HAU interrupt flag status
|
||||
\param[in] int_flag: HAU interrupt flag status
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg HAU_INT_FLAG_DATA_INPUT: there is enough space (16 bytes) in the input FIFO
|
||||
\arg HAU_INT_FLAG_CALCULATION_COMPLETE: digest calculation is completed
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void hau_interrupt_flag_clear(uint32_t int_flag)
|
||||
{
|
||||
HAU_STAT = ~(uint32_t)(int_flag);
|
||||
}
|
||||
@@ -0,0 +1,422 @@
|
||||
/*!
|
||||
\file gd32h7xx_hau_sha_md5.c
|
||||
\brief HAU_SHA_MD5 driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_hau.h"
|
||||
|
||||
#define SHAMD5_BSY_TIMEOUT ((uint32_t)0x00010000U)
|
||||
|
||||
/* HAU SHA/MD5 digest read in HASH mode */
|
||||
static void hau_sha_md5_digest_read(uint32_t algo, uint8_t output[]);
|
||||
/* HAU digest calculate process in HASH mode */
|
||||
static ErrStatus hau_hash_calculate(uint32_t algo, uint8_t input[], uint32_t in_length, uint8_t output[]);
|
||||
/* HAU digest calculate process in HMAC mode */
|
||||
static ErrStatus hau_hmac_calculate(uint32_t algo, uint8_t key[], uint32_t keysize, uint8_t input[], uint32_t in_length, uint8_t output[]);
|
||||
|
||||
/*!
|
||||
\brief calculate digest using SHA1 in HASH mode
|
||||
\param[in] input: pointer to the input buffer
|
||||
\param[in] in_length: length of the input buffer
|
||||
\param[out] output: the result digest
|
||||
\retval ErrStatus: SUCCESS or ERROR
|
||||
*/
|
||||
ErrStatus hau_hash_sha_1(uint8_t input[], uint32_t in_length, uint8_t output[])
|
||||
{
|
||||
ErrStatus ret = ERROR;
|
||||
ret = hau_hash_calculate(HAU_ALGO_SHA1, input, in_length, output);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief calculate digest using SHA1 in HMAC mode
|
||||
\param[in] key: pointer to the key used for HMAC
|
||||
\param[in] keysize: length of the key used for HMAC
|
||||
\param[in] input: pointer to the input buffer
|
||||
\param[in] in_length: length of the input buffer
|
||||
\param[out] output: the result digest
|
||||
\retval ErrStatus: SUCCESS or ERROR
|
||||
*/
|
||||
ErrStatus hau_hmac_sha_1(uint8_t key[], uint32_t keysize, uint8_t input[], uint32_t in_length, uint8_t output[])
|
||||
{
|
||||
ErrStatus ret = ERROR;
|
||||
ret = hau_hmac_calculate(HAU_ALGO_SHA1, key, keysize, input, in_length, output);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief calculate digest using SHA224 in HASH mode
|
||||
\param[in] input: pointer to the input buffer
|
||||
\param[in] in_length: length of the input buffer
|
||||
\param[out] output: the result digest
|
||||
\retval ErrStatus: SUCCESS or ERROR
|
||||
*/
|
||||
ErrStatus hau_hash_sha_224(uint8_t input[], uint32_t in_length, uint8_t output[])
|
||||
{
|
||||
ErrStatus ret = ERROR;
|
||||
ret = hau_hash_calculate(HAU_ALGO_SHA224, input, in_length, output);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief calculate digest using SHA224 in HMAC mode
|
||||
\param[in] key: pointer to the key used for HMAC
|
||||
\param[in] keysize: length of the key used for HMAC
|
||||
\param[in] input: pointer to the input buffer
|
||||
\param[in] in_length: length of the input buffer
|
||||
\param[out] output: the result digest
|
||||
\retval ErrStatus: SUCCESS or ERROR
|
||||
*/
|
||||
ErrStatus hau_hmac_sha_224(uint8_t key[], uint32_t keysize, uint8_t input[], uint32_t in_length, uint8_t output[])
|
||||
{
|
||||
ErrStatus ret = ERROR;
|
||||
ret = hau_hmac_calculate(HAU_ALGO_SHA224, key, keysize, input, in_length, output);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief calculate digest using SHA256 in HASH mode
|
||||
\param[in] input: pointer to the input buffer
|
||||
\param[in] in_length: length of the input buffer
|
||||
\param[out] output: the result digest
|
||||
\retval ErrStatus: SUCCESS or ERROR
|
||||
*/
|
||||
ErrStatus hau_hash_sha_256(uint8_t input[], uint32_t in_length, uint8_t output[])
|
||||
{
|
||||
ErrStatus ret = ERROR;
|
||||
ret = hau_hash_calculate(HAU_ALGO_SHA256, input, in_length, output);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief calculate digest using SHA256 in HMAC mode
|
||||
\param[in] key: pointer to the key used for HMAC
|
||||
\param[in] keysize: length of the key used for HMAC
|
||||
\param[in] input: pointer to the input buffer
|
||||
\param[in] in_length: length of the input buffer
|
||||
\param[out] output: the result digest
|
||||
\retval ErrStatus: SUCCESS or ERROR
|
||||
*/
|
||||
ErrStatus hau_hmac_sha_256(uint8_t key[], uint32_t keysize, uint8_t input[], uint32_t in_length, uint8_t output[])
|
||||
{
|
||||
ErrStatus ret = ERROR;
|
||||
ret = hau_hmac_calculate(HAU_ALGO_SHA256, key, keysize, input, in_length, output);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief calculate digest using MD5 in HASH mode
|
||||
\param[in] input: pointer to the input buffer
|
||||
\param[in] in_length: length of the input buffer
|
||||
\param[out] output: the result digest
|
||||
\retval ErrStatus: SUCCESS or ERROR
|
||||
*/
|
||||
ErrStatus hau_hash_md5(uint8_t input[], uint32_t in_length, uint8_t output[])
|
||||
{
|
||||
ErrStatus ret = ERROR;
|
||||
ret = hau_hash_calculate(HAU_ALGO_MD5, input, in_length, output);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief calculate digest using MD5 in HMAC mode
|
||||
\param[in] key: pointer to the key used for HMAC
|
||||
\param[in] keysize: length of the key used for HMAC
|
||||
\param[in] input: pointer to the input buffer
|
||||
\param[in] in_length: length of the input buffer
|
||||
\param[out] output: the result digest
|
||||
\retval ErrStatus: SUCCESS or ERROR
|
||||
*/
|
||||
ErrStatus hau_hmac_md5(uint8_t key[], uint32_t keysize, uint8_t input[], uint32_t in_length, uint8_t output[])
|
||||
{
|
||||
ErrStatus ret = ERROR;
|
||||
ret = hau_hmac_calculate(HAU_ALGO_MD5, key, keysize, input, in_length, output);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief HAU SHA/MD5 digest read
|
||||
\param[in] algo: algorithm selection
|
||||
only one parameter can be selected which is shown as below
|
||||
\arg HAU_ALGO_SHA1: SHA1 algorithm
|
||||
\arg HAU_ALGO_SHA224: SHA224 algorithm
|
||||
\arg HAU_ALGO_SHA256: SHA256 algorithm
|
||||
\arg HAU_ALGO_MD5: MD5 algorithm
|
||||
\param[out] output: the result digest
|
||||
\retval none
|
||||
*/
|
||||
static void hau_sha_md5_digest_read(uint32_t algo, uint8_t output[])
|
||||
{
|
||||
hau_digest_parameter_struct digest_para;
|
||||
uint32_t outputaddr = (uint32_t)output;
|
||||
|
||||
switch(algo){
|
||||
case HAU_ALGO_SHA1:
|
||||
/* read the message digest result */
|
||||
hau_digest_read(&digest_para);
|
||||
/* reverse byte order, copy result to outputaddr */
|
||||
*(uint32_t*)(outputaddr) = __REV(digest_para.out[0]);
|
||||
outputaddr += 4U;
|
||||
*(uint32_t*)(outputaddr) = __REV(digest_para.out[1]);
|
||||
outputaddr += 4U;
|
||||
*(uint32_t*)(outputaddr) = __REV(digest_para.out[2]);
|
||||
outputaddr += 4U;
|
||||
*(uint32_t*)(outputaddr) = __REV(digest_para.out[3]);
|
||||
outputaddr += 4U;
|
||||
*(uint32_t*)(outputaddr) = __REV(digest_para.out[4]);
|
||||
break;
|
||||
case HAU_ALGO_SHA224:
|
||||
/* read the message digest result */
|
||||
hau_digest_read(&digest_para);
|
||||
/* reverse byte order, copy result to outputaddr */
|
||||
*(uint32_t*)(outputaddr) = __REV(digest_para.out[0]);
|
||||
outputaddr += 4U;
|
||||
*(uint32_t*)(outputaddr) = __REV(digest_para.out[1]);
|
||||
outputaddr += 4U;
|
||||
*(uint32_t*)(outputaddr) = __REV(digest_para.out[2]);
|
||||
outputaddr += 4U;
|
||||
*(uint32_t*)(outputaddr) = __REV(digest_para.out[3]);
|
||||
outputaddr += 4U;
|
||||
*(uint32_t*)(outputaddr) = __REV(digest_para.out[4]);
|
||||
outputaddr += 4U;
|
||||
*(uint32_t*)(outputaddr) = __REV(digest_para.out[5]);
|
||||
outputaddr += 4U;
|
||||
*(uint32_t*)(outputaddr) = __REV(digest_para.out[6]);
|
||||
break;
|
||||
case HAU_ALGO_SHA256:
|
||||
/* read the message digest result */
|
||||
hau_digest_read(&digest_para);
|
||||
/* reverse byte order, copy result to outputaddr */
|
||||
*(uint32_t*)(outputaddr) = __REV(digest_para.out[0]);
|
||||
outputaddr += 4U;
|
||||
*(uint32_t*)(outputaddr) = __REV(digest_para.out[1]);
|
||||
outputaddr += 4U;
|
||||
*(uint32_t*)(outputaddr) = __REV(digest_para.out[2]);
|
||||
outputaddr += 4U;
|
||||
*(uint32_t*)(outputaddr) = __REV(digest_para.out[3]);
|
||||
outputaddr += 4U;
|
||||
*(uint32_t*)(outputaddr) = __REV(digest_para.out[4]);
|
||||
outputaddr += 4U;
|
||||
*(uint32_t*)(outputaddr) = __REV(digest_para.out[5]);
|
||||
outputaddr += 4U;
|
||||
*(uint32_t*)(outputaddr) = __REV(digest_para.out[6]);
|
||||
outputaddr += 4U;
|
||||
*(uint32_t*)(outputaddr) = __REV(digest_para.out[7]);
|
||||
break;
|
||||
case HAU_ALGO_MD5:
|
||||
/* read the message digest result */
|
||||
hau_digest_read(&digest_para);
|
||||
/* reverse byte order, copy result to outputaddr */
|
||||
*(uint32_t*)(outputaddr) = __REV(digest_para.out[0]);
|
||||
outputaddr += 4U;
|
||||
*(uint32_t*)(outputaddr) = __REV(digest_para.out[1]);
|
||||
outputaddr += 4U;
|
||||
*(uint32_t*)(outputaddr) = __REV(digest_para.out[2]);
|
||||
outputaddr += 4U;
|
||||
*(uint32_t*)(outputaddr) = __REV(digest_para.out[3]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief HAU digest calculate process in HASH mode
|
||||
\param[in] algo: algorithm selection
|
||||
\param[in] input: pointer to the input buffer
|
||||
\param[in] in_length: length of the input buffer
|
||||
\param[out] output: the result digest
|
||||
\retval ErrStatus: SUCCESS or ERROR
|
||||
*/
|
||||
static ErrStatus hau_hash_calculate(uint32_t algo, uint8_t input[], uint32_t in_length, uint8_t output[])
|
||||
{
|
||||
hau_init_parameter_struct init_para;
|
||||
|
||||
__IO uint32_t num_last_valid = 0U;
|
||||
uint32_t i = 0U;
|
||||
__IO uint32_t counter = 0U;
|
||||
uint32_t busystatus = 0U;
|
||||
uint32_t inputaddr = (uint32_t)input;
|
||||
|
||||
/* number of valid bits in last word */
|
||||
num_last_valid = 8U * (in_length % 4U);
|
||||
|
||||
/* HAU peripheral initialization */
|
||||
hau_deinit();
|
||||
|
||||
/* HAU configuration */
|
||||
init_para.algo = algo;
|
||||
init_para.mode = HAU_MODE_HASH;
|
||||
init_para.datatype = HAU_SWAPPING_8BIT;
|
||||
hau_init(&init_para);
|
||||
|
||||
/* configure the number of valid bits in last word of the message */
|
||||
hau_last_word_validbits_num_config(num_last_valid);
|
||||
|
||||
/* write data to the IN FIFO */
|
||||
for(i = 0U; i < in_length; i += 4U){
|
||||
hau_data_write(*(uint32_t*)inputaddr);
|
||||
inputaddr += 4U;
|
||||
}
|
||||
|
||||
/* enable digest calculation */
|
||||
hau_digest_calculation_enable();
|
||||
|
||||
/* wait until the busy flag is reset */
|
||||
do{
|
||||
busystatus = hau_flag_get(HAU_FLAG_BUSY);
|
||||
counter++;
|
||||
}while((SHAMD5_BSY_TIMEOUT != counter) && (RESET != busystatus));
|
||||
|
||||
if(RESET != busystatus){
|
||||
return ERROR;
|
||||
}else{
|
||||
/* read the message digest */
|
||||
hau_sha_md5_digest_read(algo, output);
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief HAU digest calculate process in HMAC mode
|
||||
\param[in] algo: algorithm selection
|
||||
\param[in] key: pointer to the key used for HMAC
|
||||
\param[in] keysize: length of the key used for HMAC
|
||||
\param[in] input: pointer to the input buffer
|
||||
\param[in] in_length: length of the input buffer
|
||||
\param[out] output: the result digest
|
||||
\retval ErrStatus: SUCCESS or ERROR
|
||||
*/
|
||||
static ErrStatus hau_hmac_calculate(uint32_t algo, uint8_t key[], uint32_t keysize, uint8_t input[], uint32_t in_length, uint8_t output[])
|
||||
{
|
||||
hau_init_parameter_struct init_para;
|
||||
|
||||
__IO uint16_t num_last_valid = 0U;
|
||||
__IO uint16_t num_key_valid = 0U;
|
||||
uint32_t i = 0U;
|
||||
__IO uint32_t counter = 0U;
|
||||
uint32_t busystatus = 0U;
|
||||
uint32_t keyaddr = (uint32_t)key;
|
||||
uint32_t inputaddr = (uint32_t)input;
|
||||
|
||||
/* number of valid bits in last word of the message */
|
||||
num_last_valid = 8U * (uint16_t)(in_length % 4U);
|
||||
/* number of valid bits in last word of the key */
|
||||
num_key_valid = 8U * (uint16_t)(keysize % 4U);
|
||||
|
||||
/* HAU peripheral initialization */
|
||||
hau_deinit();
|
||||
|
||||
/* HAU configuration */
|
||||
init_para.algo = algo;
|
||||
init_para.mode = HAU_MODE_HMAC;
|
||||
init_para.datatype = HAU_SWAPPING_8BIT;
|
||||
if(keysize > 64U){
|
||||
init_para.keytype = HAU_KEY_LONGGER_64;
|
||||
}else{
|
||||
init_para.keytype = HAU_KEY_SHORTER_64;
|
||||
}
|
||||
hau_init(&init_para);
|
||||
|
||||
/* configure the number of valid bits in last word of the key */
|
||||
hau_last_word_validbits_num_config((uint32_t)num_key_valid);
|
||||
|
||||
/* write the key */
|
||||
for(i = 0U; i < keysize; i += 4U){
|
||||
hau_data_write(*(uint32_t*)keyaddr);
|
||||
keyaddr += 4U;
|
||||
}
|
||||
|
||||
/* enable digest calculation */
|
||||
hau_digest_calculation_enable();
|
||||
|
||||
/* wait until the busy flag is reset */
|
||||
do{
|
||||
busystatus = hau_flag_get(HAU_FLAG_BUSY);
|
||||
counter++;
|
||||
}while((SHAMD5_BSY_TIMEOUT != counter) && (RESET != busystatus));
|
||||
|
||||
if(RESET != busystatus){
|
||||
return ERROR;
|
||||
}else{
|
||||
/* configure the number of valid bits in last word of the message */
|
||||
hau_last_word_validbits_num_config((uint32_t)num_last_valid);
|
||||
|
||||
/* write data to the IN FIFO */
|
||||
for(i = 0U; i < in_length; i += 4U){
|
||||
hau_data_write(*(uint32_t*)inputaddr);
|
||||
inputaddr += 4U;
|
||||
}
|
||||
|
||||
/* enable digest calculation */
|
||||
hau_digest_calculation_enable();
|
||||
|
||||
/* wait until the busy flag is reset */
|
||||
counter = 0U;
|
||||
do{
|
||||
busystatus = hau_flag_get(HAU_FLAG_BUSY);
|
||||
counter++;
|
||||
}while((SHAMD5_BSY_TIMEOUT != counter) && (RESET != busystatus));
|
||||
|
||||
if(RESET != busystatus){
|
||||
return ERROR;
|
||||
}else{
|
||||
/* configure the number of valid bits in last word of the key */
|
||||
hau_last_word_validbits_num_config((uint32_t)num_key_valid);
|
||||
|
||||
/* write the key */
|
||||
keyaddr = (uint32_t)key;
|
||||
for(i = 0U; i < keysize; i += 4U){
|
||||
hau_data_write(*(uint32_t*)keyaddr);
|
||||
keyaddr += 4U;
|
||||
}
|
||||
|
||||
/* enable digest calculation */
|
||||
hau_digest_calculation_enable();
|
||||
|
||||
/* wait until the busy flag is reset */
|
||||
counter = 0U;
|
||||
do{
|
||||
busystatus = hau_flag_get(HAU_FLAG_BUSY);
|
||||
counter++;
|
||||
}while((SHAMD5_BSY_TIMEOUT != counter) && (RESET != busystatus));
|
||||
|
||||
if(RESET != busystatus){
|
||||
return ERROR;
|
||||
}else{
|
||||
/* read the message digest */
|
||||
hau_sha_md5_digest_read(algo, output);
|
||||
}
|
||||
}
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,286 @@
|
||||
/*!
|
||||
\file gd32h7xx_hwsem.c
|
||||
\brief HWSEM driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_hwsem.h"
|
||||
|
||||
/*!
|
||||
\brief try to lock the specific semaphore by writing process ID
|
||||
\param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SEMx (x=0..31): semaphore x
|
||||
\param[in] process: the process to lock the semaphore
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg 0 - 0xFF
|
||||
\param[out] none
|
||||
\retval ErrStatus: SUCCESS or ERROR
|
||||
*/
|
||||
ErrStatus hwsem_lock_set(hwsem_semaphore_enum semaphore, uint8_t process)
|
||||
{
|
||||
uint32_t temp_mid = 0U, temp_pid = 0U;
|
||||
ErrStatus ret = ERROR;
|
||||
|
||||
/* try to lock the semaphore */
|
||||
HWSEM_CTL(semaphore) = (uint32_t)(HWSEM_LOCK | CTL_MID(HWSEM_MASTER_ID) | CTL_PID(process));
|
||||
|
||||
/* read the control register to confirm the semaphore is locked by target process or not */
|
||||
temp_mid = hwsem_master_id_get(semaphore);
|
||||
temp_pid = hwsem_process_id_get(semaphore);
|
||||
if((HWSEM_MASTER_ID == temp_mid) && (process == temp_pid)) {
|
||||
ret = SUCCESS;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief try to release the lock of the semaphore by writing process ID
|
||||
\param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SEMx (x=0..31): semaphore x
|
||||
\param[in] process: the process to unlock the semaphore
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg 0 - 0xFF
|
||||
\param[out] none
|
||||
\retval ErrStatus: SUCCESS or ERROR
|
||||
*/
|
||||
ErrStatus hwsem_lock_release(hwsem_semaphore_enum semaphore, uint8_t process)
|
||||
{
|
||||
uint32_t lock_state = 0U;
|
||||
ErrStatus ret = ERROR;
|
||||
|
||||
HWSEM_CTL(semaphore) = (uint32_t)(CTL_MID(HWSEM_MASTER_ID) | CTL_PID(process));
|
||||
|
||||
lock_state = HWSEM_CTL(semaphore) & HWSEM_CTL_LK;
|
||||
if(0U == lock_state) {
|
||||
ret = SUCCESS;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief try to lock the semaphore by reading
|
||||
\param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SEMx (x=0..31): semaphore x
|
||||
\param[out] none
|
||||
\retval ErrStatus: SUCCESS or ERROR
|
||||
*/
|
||||
ErrStatus hwsem_lock_by_reading(hwsem_semaphore_enum semaphore)
|
||||
{
|
||||
ErrStatus ret = ERROR;
|
||||
|
||||
if((uint32_t)(HWSEM_LOCK | CTL_MID(HWSEM_MASTER_ID)) == HWSEM_RLK(semaphore)) {
|
||||
ret = SUCCESS;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief unlock all semaphores of the master ID
|
||||
\param[in] key: key value
|
||||
\arg 0 - 0xFFFF
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
ErrStatus hwsem_unlock_all(uint16_t key)
|
||||
{
|
||||
ErrStatus ret = ERROR;
|
||||
|
||||
HWSEM_UNLK = UNLK_KEY(key) | UNLK_MID(HWSEM_MASTER_ID);
|
||||
|
||||
if(key == hwsem_key_get()) {
|
||||
ret = SUCCESS;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get process ID of the specific semaphore
|
||||
\param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SEMx (x=0..31): semaphore x
|
||||
\param[out] none
|
||||
\retval uint32_t: process ID of semaphore
|
||||
*/
|
||||
uint32_t hwsem_process_id_get(hwsem_semaphore_enum semaphore)
|
||||
{
|
||||
return (uint32_t)(GET_CTL_PID(HWSEM_CTL(semaphore)));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get master ID of the specific semaphore
|
||||
\param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SEMx (x=0..31): semaphore x
|
||||
\param[out] none
|
||||
\retval uint32_t: master ID of semaphore
|
||||
*/
|
||||
uint32_t hwsem_master_id_get(hwsem_semaphore_enum semaphore)
|
||||
{
|
||||
return (uint32_t)(GET_CTL_MID(HWSEM_CTL(semaphore)));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the lock status of the semaphore
|
||||
\param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SEMx (x=0..31): semaphore x
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus hwsem_lock_status_get(hwsem_semaphore_enum semaphore)
|
||||
{
|
||||
FlagStatus ret = RESET;
|
||||
|
||||
if(0U != (HWSEM_CTL(semaphore) & HWSEM_LOCK)) {
|
||||
ret = SET;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set the key
|
||||
\param[in] key: key value
|
||||
\arg 0 - 0xFFFF
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void hwsem_key_set(uint16_t key)
|
||||
{
|
||||
HWSEM_KEY = KEY_KEY(key);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the key
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval uint16_t: key to unlock all semaphores
|
||||
*/
|
||||
uint16_t hwsem_key_get(void)
|
||||
{
|
||||
return ((uint16_t)GET_KEY_KEY(HWSEM_KEY));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the HWSEM flag status
|
||||
\param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SEMx (x=0..31): semaphore x
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus hwsem_flag_get(hwsem_semaphore_enum semaphore)
|
||||
{
|
||||
FlagStatus ret = RESET;
|
||||
|
||||
if(RESET != ((HWSEM_STAT >> semaphore) & 0x1U)) {
|
||||
return SET;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear HWSEM flag status
|
||||
\param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SEMx (x=0..31): semaphore x
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void hwsem_flag_clear(hwsem_semaphore_enum semaphore)
|
||||
{
|
||||
HWSEM_INTC = (1U << semaphore);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get HWSEM interrupt flag status
|
||||
\param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SEMx (x=0..31): semaphore x
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus hwsem_interrupt_flag_get(hwsem_semaphore_enum semaphore)
|
||||
{
|
||||
FlagStatus ret = RESET;
|
||||
|
||||
if(RESET != ((HWSEM_INTF >> semaphore) & 0x1U)) {
|
||||
ret = SET;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear HWSEM interrupt flag
|
||||
\param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SEMx (x=0..31): semaphore x
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void hwsem_interrupt_flag_clear(hwsem_semaphore_enum semaphore)
|
||||
{
|
||||
HWSEM_INTC = (1U << semaphore);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable HWSEM interrupt
|
||||
\param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SEMx (x=0..31): semaphore x
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void hwsem_interrupt_enable(hwsem_semaphore_enum semaphore)
|
||||
{
|
||||
HWSEM_INTEN |= (1U << semaphore);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable HWSEM interrupt
|
||||
\param[in] semaphore: semaphore index, refer to hwsem_semaphore_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SEMx (x=0..31): semaphore x
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void hwsem_interrupt_disable(hwsem_semaphore_enum semaphore)
|
||||
{
|
||||
HWSEM_INTEN &= (uint32_t)(~((uint32_t)1U << semaphore));
|
||||
}
|
||||
@@ -0,0 +1,968 @@
|
||||
/*!
|
||||
\file gd32h7xx_i2c.c
|
||||
\brief I2C driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_i2c.h"
|
||||
|
||||
/* I2C register bit mask */
|
||||
#define I2C_ADDRESS_MASK ((uint32_t)0x000003FFU) /*!< i2c address mask */
|
||||
#define I2C_ADDRESS2_MASK ((uint32_t)0x000000FEU) /*!< the second i2c address mask */
|
||||
|
||||
/* I2C register bit offset */
|
||||
#define CTL0_DNF_OFFSET ((uint32_t)0x00000008U) /*!< bit offset of DNF in I2C_CTL0 */
|
||||
#define CTL1_BYTENUM_OFFSET ((uint32_t)0x00000010U) /*!< bit offset of BYTENUM in I2C_CTL1 */
|
||||
#define STAT_READDR_OFFSET ((uint32_t)0x00000011U) /*!< bit offset of READDR in I2C_STAT */
|
||||
#define TIMING_SCLL_OFFSET ((uint32_t)0x00000000U) /*!< bit offset of SCLL in I2C_TIMING */
|
||||
#define TIMING_SCLH_OFFSET ((uint32_t)0x00000008U) /*!< bit offset of SCLH in I2C_TIMING */
|
||||
#define TIMING_SDADELY_OFFSET ((uint32_t)0x00000010U) /*!< bit offset of SDADELY in I2C_TIMING */
|
||||
#define TIMING_SCLDELY_OFFSET ((uint32_t)0x00000014U) /*!< bit offset of SCLDELY in I2C_TIMING */
|
||||
#define TIMING_PSC_OFFSET ((uint32_t)0x0000001CU) /*!< bit offset of PSC in I2C_TIMING */
|
||||
#define SADDR1_ADDMSK_OFFSET ((uint32_t)0x00000008U) /*!< bit offset of ADDMSK in I2C_SADDR1 */
|
||||
#define TIMEOUT_BUSTOB_OFFSET ((uint32_t)0x00000010U) /*!< bit offset of BUSTOB in I2C_TIMEOUT */
|
||||
|
||||
/*!
|
||||
\brief reset I2C
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_deinit(uint32_t i2c_periph)
|
||||
{
|
||||
switch(i2c_periph) {
|
||||
/* reset I2C0 */
|
||||
case I2C0:
|
||||
rcu_periph_reset_enable(RCU_I2C0RST);
|
||||
rcu_periph_reset_disable(RCU_I2C0RST);
|
||||
break;
|
||||
/* reset I2C1 */
|
||||
case I2C1:
|
||||
rcu_periph_reset_enable(RCU_I2C1RST);
|
||||
rcu_periph_reset_disable(RCU_I2C1RST);
|
||||
break;
|
||||
/* reset I2C2 */
|
||||
case I2C2:
|
||||
rcu_periph_reset_enable(RCU_I2C2RST);
|
||||
rcu_periph_reset_disable(RCU_I2C2RST);
|
||||
break;
|
||||
/* reset I2C3 */
|
||||
case I2C3:
|
||||
rcu_periph_reset_enable(RCU_I2C3RST);
|
||||
rcu_periph_reset_disable(RCU_I2C3RST);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the timing parameters
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[in] psc: 0-0x0000000F, timing prescaler
|
||||
\param[in] scl_dely: 0-0x0000000F, data setup time
|
||||
\param[in] sda_dely: 0-0x0000000F, data hold time
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_timing_config(uint32_t i2c_periph, uint32_t psc, uint32_t scl_dely, uint32_t sda_dely)
|
||||
{
|
||||
/* clear PSC, SCLDELY, SDADELY bits in I2C_TIMING register */
|
||||
I2C_TIMING(i2c_periph) &= ~I2C_TIMING_PSC;
|
||||
I2C_TIMING(i2c_periph) &= ~I2C_TIMING_SCLDELY;
|
||||
I2C_TIMING(i2c_periph) &= ~I2C_TIMING_SDADELY;
|
||||
/* mask PSC, SCLDELY, SDADELY bits in I2C_TIMING register */
|
||||
psc = (uint32_t)(psc << TIMING_PSC_OFFSET) & I2C_TIMING_PSC;
|
||||
scl_dely = (uint32_t)(scl_dely << TIMING_SCLDELY_OFFSET) & I2C_TIMING_SCLDELY;
|
||||
sda_dely = (uint32_t)(sda_dely << TIMING_SDADELY_OFFSET) & I2C_TIMING_SDADELY;
|
||||
/* write PSC, SCLDELY, SDADELY bits in I2C_TIMING register */
|
||||
I2C_TIMING(i2c_periph) |= (psc | scl_dely | sda_dely);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure digital noise filter
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[in] filter_length: the length of filter spikes
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg FILTER_DISABLE: digital filter is disabled
|
||||
\arg FILTER_LENGTH_1: digital filter is enabled and filter spikes with a length of up to 1 tI2CCLK
|
||||
\arg FILTER_LENGTH_2: digital filter is enabled and filter spikes with a length of up to 2 tI2CCLK
|
||||
\arg FILTER_LENGTH_3: digital filter is enabled and filter spikes with a length of up to 3 tI2CCLK
|
||||
\arg FILTER_LENGTH_4: digital filter is enabled and filter spikes with a length of up to 4 tI2CCLK
|
||||
\arg FILTER_LENGTH_5: digital filter is enabled and filter spikes with a length of up to 5 tI2CCLK
|
||||
\arg FILTER_LENGTH_6: digital filter is enabled and filter spikes with a length of up to 6 tI2CCLK
|
||||
\arg FILTER_LENGTH_7: digital filter is enabled and filter spikes with a length of up to 7 tI2CCLK
|
||||
\arg FILTER_LENGTH_8: digital filter is enabled and filter spikes with a length of up to 8 tI2CCLK
|
||||
\arg FILTER_LENGTH_9: digital filter is enabled and filter spikes with a length of up to 9 tI2CCLK
|
||||
\arg FILTER_LENGTH_10: digital filter is enabled and filter spikes with a length of up to 10 tI2CCLK
|
||||
\arg FILTER_LENGTH_11: digital filter is enabled and filter spikes with a length of up to 11 tI2CCLK
|
||||
\arg FILTER_LENGTH_12: digital filter is enabled and filter spikes with a length of up to 12 tI2CCLK
|
||||
\arg FILTER_LENGTH_13: digital filter is enabled and filter spikes with a length of up to 13 tI2CCLK
|
||||
\arg FILTER_LENGTH_14: digital filter is enabled and filter spikes with a length of up to 14 tI2CCLK
|
||||
\arg FILTER_LENGTH_15: digital filter is enabled and filter spikes with a length of up to 15 tI2CCLK
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_digital_noise_filter_config(uint32_t i2c_periph, uint32_t filter_length)
|
||||
{
|
||||
I2C_CTL0(i2c_periph) &= (uint32_t)(~I2C_CTL0_DNF);
|
||||
I2C_CTL0(i2c_periph) |= (uint32_t)(filter_length << CTL0_DNF_OFFSET);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable analog noise filter
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_analog_noise_filter_enable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL0(i2c_periph) &= ~I2C_CTL0_ANOFF;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable analog noise filter
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_analog_noise_filter_disable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL0(i2c_periph) |= I2C_CTL0_ANOFF;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the SCL high and low period of clock in master mode
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[in] sclh: 0-0x000000FF, SCL high period
|
||||
\param[in] scll: 0-0x000000FF, SCL low period
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_master_clock_config(uint32_t i2c_periph, uint32_t sclh, uint32_t scll)
|
||||
{
|
||||
/* clear SCLH, SCLL bits in I2C_TIMING register */
|
||||
I2C_TIMING(i2c_periph) &= ~I2C_TIMING_SCLH;
|
||||
I2C_TIMING(i2c_periph) &= ~I2C_TIMING_SCLL;
|
||||
/* mask SCLH, SCLL bits in I2C_TIMING register */
|
||||
sclh = (uint32_t)(sclh << TIMING_SCLH_OFFSET) & I2C_TIMING_SCLH;
|
||||
scll = (uint32_t)(scll << TIMING_SCLL_OFFSET) & I2C_TIMING_SCLL;
|
||||
/* write SCLH, SCLL bits in I2C_TIMING register */
|
||||
I2C_TIMING(i2c_periph) |= (sclh | scll);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure I2C slave address and transfer direction in master mode
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[in] address: 0-0x3FF except reserved address, I2C slave address to be sent
|
||||
\param[in] trans_direction: I2C transfer direction in master mode
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2C_MASTER_TRANSMIT: master transmit
|
||||
\arg I2C_MASTER_RECEIVE: master receive
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_master_addressing(uint32_t i2c_periph, uint32_t address, uint32_t trans_direction)
|
||||
{
|
||||
/* configure slave address */
|
||||
I2C_CTL1(i2c_periph) &= ~I2C_CTL1_SADDRESS;
|
||||
I2C_CTL1(i2c_periph) |= address;
|
||||
/* configure transfer direction */
|
||||
I2C_CTL1(i2c_periph) &= ~I2C_CTL1_TRDIR;
|
||||
I2C_CTL1(i2c_periph) |= trans_direction;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief 10-bit address header executes read direction only in master receive mode
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_address10_header_enable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL1(i2c_periph) |= I2C_CTL1_HEAD10R;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief 10-bit address header executes complete sequence in master receive mode
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_address10_header_disable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL1(i2c_periph) &= ~I2C_CTL1_HEAD10R;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable 10-bit addressing mode in master mode
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_address10_enable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL1(i2c_periph) |= I2C_CTL1_ADD10EN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable 10-bit addressing mode in master mode
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_address10_disable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL1(i2c_periph) &= ~I2C_CTL1_ADD10EN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable I2C automatic end mode in master mode
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_automatic_end_enable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL1(i2c_periph) |= I2C_CTL1_AUTOEND;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable I2C automatic end mode in master mode
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_automatic_end_disable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL1(i2c_periph) &= ~I2C_CTL1_AUTOEND;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the response to a general call
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_slave_response_to_gcall_enable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL0(i2c_periph) |= I2C_CTL0_GCEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the response to a general call
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_slave_response_to_gcall_disable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL0(i2c_periph) &= ~I2C_CTL0_GCEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable to stretch SCL low when data is not ready in slave mode
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_stretch_scl_low_enable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL0(i2c_periph) &= ~I2C_CTL0_SS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable to stretch SCL low when data is not ready in slave mode
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_stretch_scl_low_disable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL0(i2c_periph) |= I2C_CTL0_SS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure I2C slave address
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[in] address: I2C address
|
||||
\param[in] addr_format: 7 bits or 10 bits
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2C_ADDFORMAT_7BITS: address format is 7 bits
|
||||
\arg I2C_ADDFORMAT_10BITS: address format is 10 bits
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_address_config(uint32_t i2c_periph, uint32_t address, uint32_t addr_format)
|
||||
{
|
||||
/* configure ADDRESS[7:1] and address format */
|
||||
address = address & I2C_ADDRESS_MASK;
|
||||
I2C_SADDR0(i2c_periph) = (addr_format | address);
|
||||
/* enable I2C address in slave mode */
|
||||
I2C_SADDR0(i2c_periph) |= I2C_SADDR0_ADDRESSEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief define which bits of ADDRESS[7:1] need to compare with the incoming address byte
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[in] compare_bits: the bits need to compare
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg ADDRESS_BIT1_COMPARE: address bit1 needs compare
|
||||
\arg ADDRESS_BIT2_COMPARE: address bit2 needs compare
|
||||
\arg ADDRESS_BIT3_COMPARE: address bit3 needs compare
|
||||
\arg ADDRESS_BIT4_COMPARE: address bit4 needs compare
|
||||
\arg ADDRESS_BIT5_COMPARE: address bit5 needs compare
|
||||
\arg ADDRESS_BIT6_COMPARE: address bit6 needs compare
|
||||
\arg ADDRESS_BIT7_COMPARE: address bit7 needs compare
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_address_bit_compare_config(uint32_t i2c_periph, uint32_t compare_bits)
|
||||
{
|
||||
I2C_CTL2(i2c_periph) &= ~I2C_CTL2_ADDM;
|
||||
I2C_CTL2(i2c_periph) |= compare_bits;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable I2C address in slave mode
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_address_disable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_SADDR0(i2c_periph) &= ~I2C_SADDR0_ADDRESSEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure I2C second slave address
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[in] address: I2C address
|
||||
\param[in] addr_mask: the bits not need to compare
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg ADDRESS2_NO_MASK: no mask, all the bits must be compared
|
||||
\arg ADDRESS2_MASK_BIT1: ADDRESS2[1] is masked, only ADDRESS2[7:2] are compared
|
||||
\arg ADDRESS2_MASK_BIT1_2: ADDRESS2[2:1] is masked, only ADDRESS2[7:3] are compared
|
||||
\arg ADDRESS2_MASK_BIT1_3: ADDRESS2[3:1] is masked, only ADDRESS2[7:4] are compared
|
||||
\arg ADDRESS2_MASK_BIT1_4: ADDRESS2[4:1] is masked, only ADDRESS2[7:5] are compared
|
||||
\arg ADDRESS2_MASK_BIT1_5: ADDRESS2[5:1] is masked, only ADDRESS2[7:6] are compared
|
||||
\arg ADDRESS2_MASK_BIT1_6: ADDRESS2[6:1] is masked, only ADDRESS2[7] are compared
|
||||
\arg ADDRESS2_MASK_ALL: all the ADDRESS2[7:1] bits are masked
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_second_address_config(uint32_t i2c_periph, uint32_t address, uint32_t addr_mask)
|
||||
{
|
||||
/* configure ADDRESS2[7:1] */
|
||||
address = address & I2C_ADDRESS2_MASK;
|
||||
I2C_SADDR1(i2c_periph) |= address;
|
||||
/* configure ADDRESS2[7:1] mask */
|
||||
I2C_SADDR1(i2c_periph) &= ~I2C_SADDR1_ADDMSK2;
|
||||
I2C_SADDR1(i2c_periph) |= (uint32_t)(addr_mask << SADDR1_ADDMSK_OFFSET);
|
||||
/* enable i2c second address in slave mode */
|
||||
I2C_SADDR1(i2c_periph) |= I2C_SADDR1_ADDRESS2EN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable I2C second address in slave mode
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_second_address_disable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_SADDR1(i2c_periph) &= ~I2C_SADDR1_ADDRESS2EN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get received match address in slave mode
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval uint32_t: received match address
|
||||
*/
|
||||
uint32_t i2c_recevied_address_get(uint32_t i2c_periph)
|
||||
{
|
||||
return (uint32_t)((I2C_STAT(i2c_periph) & I2C_STAT_READDR) >> STAT_READDR_OFFSET);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable slave byte control
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_slave_byte_control_enable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL0(i2c_periph) |= I2C_CTL0_SBCTL;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable slave byte control
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_slave_byte_control_disable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL0(i2c_periph) &= ~I2C_CTL0_SBCTL;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief generate a NACK in slave mode
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_nack_enable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL1(i2c_periph) |= I2C_CTL1_NACKEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief generate an ACK in slave mode
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_nack_disable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL1(i2c_periph) &= ~I2C_CTL1_NACKEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable wakeup from deep-sleep mode
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_wakeup_from_deepsleep_enable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL0(i2c_periph) |= I2C_CTL0_WUEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable wakeup from deep-sleep mode
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_wakeup_from_deepsleep_disable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL0(i2c_periph) &= ~I2C_CTL0_WUEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable I2C
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_enable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL0(i2c_periph) |= I2C_CTL0_I2CEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable I2C
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_disable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL0(i2c_periph) &= ~I2C_CTL0_I2CEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief generate a START condition on I2C bus
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_start_on_bus(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL1(i2c_periph) |= I2C_CTL1_START;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief generate a STOP condition on I2C bus
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_stop_on_bus(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL1(i2c_periph) |= I2C_CTL1_STOP;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief I2C transmit data
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[in] data: data to be transmitted
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_data_transmit(uint32_t i2c_periph, uint32_t data)
|
||||
{
|
||||
I2C_TDATA(i2c_periph) = (I2C_TDATA_TDATA & data);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief I2C receive data
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval uint32_t: 0x0-0xFF
|
||||
*/
|
||||
uint32_t i2c_data_receive(uint32_t i2c_periph)
|
||||
{
|
||||
return (I2C_RDATA(i2c_periph) & I2C_RDATA_RDATA);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable I2C reload mode
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_reload_enable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL1(i2c_periph) |= I2C_CTL1_RELOAD;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable I2C reload mode
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_reload_disable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL1(i2c_periph) &= ~I2C_CTL1_RELOAD;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure number of bytes to be transferred
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[in] byte_number: 0x0-0xFF, number of bytes to be transferred
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_transfer_byte_number_config(uint32_t i2c_periph, uint32_t byte_number)
|
||||
{
|
||||
I2C_CTL1(i2c_periph) &= (uint32_t)(~I2C_CTL1_BYTENUM);
|
||||
I2C_CTL1(i2c_periph) |= (uint32_t)(byte_number << CTL1_BYTENUM_OFFSET);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable I2C DMA for transmission or reception
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[in] dma: I2C DMA
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2C_DMA_TRANSMIT: transmit data using DMA
|
||||
\arg I2C_DMA_RECEIVE: receive data using DMA
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_dma_enable(uint32_t i2c_periph, uint8_t dma)
|
||||
{
|
||||
if(I2C_DMA_TRANSMIT == dma) {
|
||||
I2C_CTL0(i2c_periph) |= I2C_CTL0_DENT;
|
||||
} else {
|
||||
I2C_CTL0(i2c_periph) |= I2C_CTL0_DENR;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable I2C DMA for transmission or reception
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[in] dma: I2C DMA
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2C_DMA_TRANSMIT: transmit data using DMA
|
||||
\arg I2C_DMA_RECEIVE: receive data using DMA
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_dma_disable(uint32_t i2c_periph, uint8_t dma)
|
||||
{
|
||||
if(I2C_DMA_TRANSMIT == dma) {
|
||||
I2C_CTL0(i2c_periph) &= ~I2C_CTL0_DENT;
|
||||
} else {
|
||||
I2C_CTL0(i2c_periph) &= ~I2C_CTL0_DENR;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief I2C transfers PEC value
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_pec_transfer(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL1(i2c_periph) |= I2C_CTL1_PECTRANS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable I2C PEC calculation
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_pec_enable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL0(i2c_periph) |= I2C_CTL0_PECEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable I2C PEC calculation
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_pec_disable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL0(i2c_periph) &= ~I2C_CTL0_PECEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get packet error checking value
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval uint32_t: 0x0-0xFF
|
||||
*/
|
||||
uint32_t i2c_pec_value_get(uint32_t i2c_periph)
|
||||
{
|
||||
return (I2C_PEC(i2c_periph) & I2C_PEC_PECV);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable SMBus alert
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_smbus_alert_enable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL0(i2c_periph) |= I2C_CTL0_SMBALTEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable SMBus alert
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_smbus_alert_disable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL0(i2c_periph) &= ~I2C_CTL0_SMBALTEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable SMBus device default address
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_smbus_default_addr_enable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL0(i2c_periph) |= I2C_CTL0_SMBDAEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable SMBus device default address
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_smbus_default_addr_disable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL0(i2c_periph) &= ~I2C_CTL0_SMBDAEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable SMBus host address
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_smbus_host_addr_enable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL0(i2c_periph) |= I2C_CTL0_SMBHAEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable SMBus host address
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_smbus_host_addr_disable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL0(i2c_periph) &= ~I2C_CTL0_SMBHAEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable extended clock timeout detection
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_extented_clock_timeout_enable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_TIMEOUT(i2c_periph) |= I2C_TIMEOUT_EXTOEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable extended clock timeout detection
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_extented_clock_timeout_disable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_TIMEOUT(i2c_periph) &= ~I2C_TIMEOUT_EXTOEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable clock timeout detection
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_clock_timeout_enable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_TIMEOUT(i2c_periph) |= I2C_TIMEOUT_TOEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable clock timeout detection
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_clock_timeout_disable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_TIMEOUT(i2c_periph) &= ~I2C_TIMEOUT_TOEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure bus timeout B
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[in] timeout: bus timeout B
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_bus_timeout_b_config(uint32_t i2c_periph, uint32_t timeout)
|
||||
{
|
||||
I2C_TIMEOUT(i2c_periph) &= ~I2C_TIMEOUT_BUSTOB;
|
||||
I2C_TIMEOUT(i2c_periph) |= (uint32_t)(timeout << TIMEOUT_BUSTOB_OFFSET);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure bus timeout A
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[in] timeout: bus timeout A
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_bus_timeout_a_config(uint32_t i2c_periph, uint32_t timeout)
|
||||
{
|
||||
I2C_TIMEOUT(i2c_periph) &= ~I2C_TIMEOUT_BUSTOA;
|
||||
I2C_TIMEOUT(i2c_periph) |= timeout;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure idle clock timeout detection
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[in] timeout: bus timeout A
|
||||
\arg BUSTOA_DETECT_SCL_LOW: BUSTOA is used to detect SCL low timeout
|
||||
\arg BUSTOA_DETECT_IDLE: BUSTOA is used to detect both SCL and SDA high timeout when the bus is idle
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_idle_clock_timeout_config(uint32_t i2c_periph, uint32_t timeout)
|
||||
{
|
||||
I2C_TIMEOUT(i2c_periph) &= ~I2C_TIMEOUT_TOIDLE;
|
||||
I2C_TIMEOUT(i2c_periph) |= timeout;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get I2C flag status
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[in] flag: I2C flags
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2C_FLAG_TBE: I2C_TDATA is empty during transmitting
|
||||
\arg I2C_FLAG_TI: transmit interrupt
|
||||
\arg I2C_FLAG_RBNE: I2C_RDATA is not empty during receiving
|
||||
\arg I2C_FLAG_ADDSEND: address received matches in slave mode
|
||||
\arg I2C_FLAG_NACK: not acknowledge flag
|
||||
\arg I2C_FLAG_STPDET: STOP condition detected in slave mode
|
||||
\arg I2C_FLAG_TC: transfer complete in master mode
|
||||
\arg I2C_FLAG_TCR: transfer complete reload
|
||||
\arg I2C_FLAG_BERR: bus error
|
||||
\arg I2C_FLAG_LOSTARB: arbitration Lost
|
||||
\arg I2C_FLAG_OUERR: overrun/underrun error in slave mode
|
||||
\arg I2C_FLAG_PECERR: PEC error
|
||||
\arg I2C_FLAG_TIMEOUT: timeout flag
|
||||
\arg I2C_FLAG_SMBALT: SMBus alert
|
||||
\arg I2C_FLAG_I2CBSY: busy flag
|
||||
\arg I2C_FLAG_TR: whether the I2C is a transmitter or a receiver in slave mode
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus i2c_flag_get(uint32_t i2c_periph, uint32_t flag)
|
||||
{
|
||||
if(RESET != (I2C_STAT(i2c_periph) & flag)) {
|
||||
return SET;
|
||||
} else {
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear I2C flag status
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[in] flag: I2C flags
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2C_FLAG_ADDSEND: address received matches in slave mode
|
||||
\arg I2C_FLAG_NACK: not acknowledge flag
|
||||
\arg I2C_FLAG_STPDET: STOP condition detected in slave mode
|
||||
\arg I2C_FLAG_BERR: bus error
|
||||
\arg I2C_FLAG_LOSTARB: arbitration Lost
|
||||
\arg I2C_FLAG_OUERR: overrun/underrun error in slave mode
|
||||
\arg I2C_FLAG_PECERR: PEC error
|
||||
\arg I2C_FLAG_TIMEOUT: timeout flag
|
||||
\arg I2C_FLAG_SMBALT: SMBus Alert
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_flag_clear(uint32_t i2c_periph, uint32_t flag)
|
||||
{
|
||||
I2C_STATC(i2c_periph) |= flag;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable I2C interrupt
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[in] interrupt: I2C interrupts
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2C_INT_ERR: error interrupt
|
||||
\arg I2C_INT_TC: transfer complete interrupt
|
||||
\arg I2C_INT_STPDET: stop detection interrupt
|
||||
\arg I2C_INT_NACK: not acknowledge received interrupt
|
||||
\arg I2C_INT_ADDM: address match interrupt
|
||||
\arg I2C_INT_RBNE: receive interrupt
|
||||
\arg I2C_INT_TI: transmit interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_interrupt_enable(uint32_t i2c_periph, uint32_t interrupt)
|
||||
{
|
||||
I2C_CTL0(i2c_periph) |= interrupt;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable I2C interrupt
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[in] interrupt: I2C interrupts
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2C_INT_ERR: error interrupt
|
||||
\arg I2C_INT_TC: transfer complete interrupt
|
||||
\arg I2C_INT_STPDET: stop detection interrupt
|
||||
\arg I2C_INT_NACK: not acknowledge received interrupt
|
||||
\arg I2C_INT_ADDM: address match interrupt
|
||||
\arg I2C_INT_RBNE: receive interrupt
|
||||
\arg I2C_INT_TI: transmit interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_interrupt_disable(uint32_t i2c_periph, uint32_t interrupt)
|
||||
{
|
||||
I2C_CTL0(i2c_periph) &= ~interrupt;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get I2C interrupt flag status
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[in] int_flag: I2C interrupt flags
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2C_INT_FLAG_TI: transmit interrupt flag
|
||||
\arg I2C_INT_FLAG_RBNE: I2C_RDATA is not empty during receiving interrupt flag
|
||||
\arg I2C_INT_FLAG_ADDSEND: address received matches in slave mode interrupt flag
|
||||
\arg I2C_INT_FLAG_NACK: not acknowledge interrupt flag
|
||||
\arg I2C_INT_FLAG_STPDET: stop condition detected in slave mode interrupt flag
|
||||
\arg I2C_INT_FLAG_TC: transfer complete in master mode interrupt flag
|
||||
\arg I2C_INT_FLAG_TCR: transfer complete reload interrupt flag
|
||||
\arg I2C_INT_FLAG_BERR: bus error interrupt flag
|
||||
\arg I2C_INT_FLAG_LOSTARB: arbitration lost interrupt flag
|
||||
\arg I2C_INT_FLAG_OUERR: overrun/underrun error in slave mode interrupt flag
|
||||
\arg I2C_INT_FLAG_PECERR: PEC error interrupt flag
|
||||
\arg I2C_INT_FLAG_TIMEOUT: timeout interrupt flag
|
||||
\arg I2C_INT_FLAG_SMBALT: SMBus Alert interrupt flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus i2c_interrupt_flag_get(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag)
|
||||
{
|
||||
uint32_t ret1 = RESET;
|
||||
uint32_t ret2 = RESET;
|
||||
|
||||
/* get the status of interrupt enable bit */
|
||||
ret1 = (I2C_REG_VAL(i2c_periph, int_flag) & BIT(I2C_BIT_POS(int_flag)));
|
||||
/* get the status of interrupt flag */
|
||||
ret2 = (I2C_REG_VAL2(i2c_periph, int_flag) & BIT(I2C_BIT_POS2(int_flag)));
|
||||
if(ret1 && ret2) {
|
||||
return SET;
|
||||
} else {
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear I2C interrupt flag status
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2,3)
|
||||
\param[in] int_flag: I2C interrupt flags
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2C_INT_FLAG_ADDSEND: address received matches in slave mode interrupt flag
|
||||
\arg I2C_INT_FLAG_NACK: not acknowledge interrupt flag
|
||||
\arg I2C_INT_FLAG_STPDET: stop condition detected in slave mode interrupt flag
|
||||
\arg I2C_INT_FLAG_BERR: bus error interrupt flag
|
||||
\arg I2C_INT_FLAG_LOSTARB: arbitration lost interrupt flag
|
||||
\arg I2C_INT_FLAG_OUERR: overrun/underrun error in slave mode interrupt flag
|
||||
\arg I2C_INT_FLAG_PECERR: PEC error interrupt flag
|
||||
\arg I2C_INT_FLAG_TIMEOUT: timeout interrupt flag
|
||||
\arg I2C_INT_FLAG_SMBALT: SMBus Alert interrupt flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_interrupt_flag_clear(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag)
|
||||
{
|
||||
I2C_STATC(i2c_periph) |= BIT(I2C_BIT_POS2(int_flag));
|
||||
}
|
||||
@@ -0,0 +1,823 @@
|
||||
/*!
|
||||
\file gd32h7xx_ipa.c
|
||||
\brief IPA driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_ipa.h"
|
||||
|
||||
#define IPA_DEFAULT_VALUE 0x00000000U
|
||||
#define IPA_DEFAULT_SCALE 0x00001000U
|
||||
|
||||
#define IPA_DEFAULT_YUV_CONV_YOFFSET 0x00000000U
|
||||
#define IPA_DEFAULT_YUV_CONV_UVOFFSET 0x00000000U
|
||||
#define IPA_DEFAULT_YUV_CONV_C0OFFSET 0x00000100U
|
||||
#define IPA_DEFAULT_YUV_CONV_C1OFFSET 0x00000123U
|
||||
#define IPA_DEFAULT_YUV_CONV_C2OFFSET 0x0000076BU
|
||||
#define IPA_DEFAULT_YUV_CONV_C3OFFSET 0x0000079CU
|
||||
#define IPA_DEFAULT_YUV_CONV_C4OFFSET 0x00000208U
|
||||
|
||||
#define IPA_DEFAULT_YCBCR_CONV_YOFFSET 0x000001F0U
|
||||
#define IPA_DEFAULT_YCBCR_CONV_UVOFFSET 0x00000180U
|
||||
#define IPA_DEFAULT_YCBCR_CONV_C0OFFSET 0x0000012AU
|
||||
#define IPA_DEFAULT_YCBCR_CONV_C1OFFSET 0x00000198U
|
||||
#define IPA_DEFAULT_YCBCR_CONV_C2OFFSET 0x00000730U
|
||||
#define IPA_DEFAULT_YCBCR_CONV_C3OFFSET 0x0000079CU
|
||||
#define IPA_DEFAULT_YCBCR_CONV_C4OFFSET 0x00000204U
|
||||
|
||||
/*!
|
||||
\brief deinitialize IPA registers
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ipa_deinit(void)
|
||||
{
|
||||
rcu_periph_reset_enable(RCU_IPARST);
|
||||
rcu_periph_reset_disable(RCU_IPARST);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable IPA transfer
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ipa_transfer_enable(void)
|
||||
{
|
||||
IPA_CTL |= IPA_CTL_TEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable IPA transfer hang up
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ipa_transfer_hangup_enable(void)
|
||||
{
|
||||
IPA_CTL |= IPA_CTL_THU;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable IPA transfer hang up
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ipa_transfer_hangup_disable(void)
|
||||
{
|
||||
IPA_CTL &= ~(IPA_CTL_THU);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable IPA transfer stop
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ipa_transfer_stop_enable(void)
|
||||
{
|
||||
IPA_CTL |= IPA_CTL_TST;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable IPA transfer stop
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ipa_transfer_stop_disable(void)
|
||||
{
|
||||
IPA_CTL &= ~(IPA_CTL_TST);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable IPA foreground LUT loading
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ipa_foreground_lut_loading_enable(void)
|
||||
{
|
||||
IPA_FPCTL |= IPA_FPCTL_FLLEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable IPA background LUT loading
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ipa_background_lut_loading_enable(void)
|
||||
{
|
||||
IPA_BPCTL |= IPA_BPCTL_BLLEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set pixel format convert mode, the function is invalid when the IPA transfer is enabled
|
||||
\param[in] pfcm: pixel format convert mode
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg IPA_FGTODE: foreground memory to destination memory without pixel format convert
|
||||
\arg IPA_FGTODE_PF_CONVERT: foreground memory to destination memory with pixel format convert
|
||||
\arg IPA_FGBGTODE: blending foreground and background memory to destination memory
|
||||
\arg IPA_FILL_UP_DE: fill up destination memory with specific color
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ipa_pixel_format_convert_mode_set(uint32_t pfcm)
|
||||
{
|
||||
IPA_CTL &= ~(IPA_CTL_PFCM);
|
||||
IPA_CTL |= pfcm;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable foreground interlace mode
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ipa_foreground_interlace_mode_enable(void)
|
||||
{
|
||||
IPA_FPCTL |= IPA_FPCTL_FIIMEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable foreground interlace mode
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ipa_foreground_interlace_mode_disable(void)
|
||||
{
|
||||
IPA_FPCTL &= ~(IPA_FPCTL_FIIMEN);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the structure of IPA foreground parameter struct with the default values, it is
|
||||
suggested that call this function after an ipa_foreground_parameter_struct structure is defined
|
||||
\param[in] none
|
||||
\param[out] foreground_struct: the data needed to initialize foreground
|
||||
\retval none
|
||||
*/
|
||||
void ipa_foreground_struct_para_init(ipa_foreground_parameter_struct* foreground_struct)
|
||||
{
|
||||
/* initialize the struct parameters with default values */
|
||||
foreground_struct->foreground_memaddr = IPA_DEFAULT_VALUE;
|
||||
foreground_struct->foreground_lineoff = IPA_DEFAULT_VALUE;
|
||||
foreground_struct->foreground_prealpha = IPA_DEFAULT_VALUE;
|
||||
foreground_struct->foreground_alpha_algorithm = IPA_FG_ALPHA_MODE_0;
|
||||
foreground_struct->foreground_pf = FOREGROUND_PPF_ARGB8888;
|
||||
foreground_struct->foreground_prered = IPA_DEFAULT_VALUE;
|
||||
foreground_struct->foreground_pregreen = IPA_DEFAULT_VALUE;
|
||||
foreground_struct->foreground_preblue = IPA_DEFAULT_VALUE;
|
||||
foreground_struct->foreground_interlace_mode = DISABLE;
|
||||
foreground_struct->foreground_efuv_memaddr = IPA_DEFAULT_VALUE;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize foreground parameters
|
||||
\param[in] foreground_struct: the data needed to initialize foreground
|
||||
foreground_memaddr: foreground memory base address
|
||||
foreground_lineoff: foreground line offset
|
||||
foreground_prealpha: foreground pre-defined alpha value
|
||||
foreground_alpha_algorithm: IPA_FG_ALPHA_MODE_0,IPA_FG_ALPHA_MODE_1,IPA_FG_ALPHA_MODE_2
|
||||
foreground_pf: foreground pixel format(FOREGROUND_PPF_ARGB8888, FOREGROUND_PPF_RGB888, FOREGROUND_PPF_RGB565,
|
||||
FOREGROUND_PPF_ARGB1555, FOREGROUND_PPF_ARGB4444, FOREGROUND_PPF_L8, FOREGROUND_PPF_AL44,
|
||||
FOREGROUND_PPF_AL88, FOREGROUND_PPF_L4, FOREGROUND_PPF_A8, FOREGROUND_PPF_A4,
|
||||
FOREGROUND_PPF_YUV444_1P, FOREGROUND_PPF_UYVY422_1P, FOREGROUND_PPF_VYUY422_1P,
|
||||
FOREGROUND_PPF_YUV420_2P, FOREGROUND_PPF_YVU420_2P)
|
||||
foreground_prered: foreground pre-defined red value
|
||||
foreground_pregreen: foreground pre-defined green value
|
||||
foreground_preblue: foreground pre-defined blue value
|
||||
foreground_interlace_mode: ENABLE, DISABLE
|
||||
foreground_efuv_memaddr: foreground even frame / UV memory base address
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ipa_foreground_init(ipa_foreground_parameter_struct* foreground_struct)
|
||||
{
|
||||
FlagStatus tempflag = RESET;
|
||||
if(RESET != (IPA_CTL & IPA_CTL_TEN)){
|
||||
tempflag = SET;
|
||||
/* reset the TEN in order to configure the following bits */
|
||||
IPA_CTL &= ~IPA_CTL_TEN;
|
||||
}
|
||||
|
||||
/* foreground memory base address configuration */
|
||||
IPA_FMADDR &= ~(IPA_FMADDR_FMADDR);
|
||||
IPA_FMADDR = foreground_struct->foreground_memaddr;
|
||||
/* foreground line offset configuration */
|
||||
IPA_FLOFF &= ~(IPA_FLOFF_FLOFF);
|
||||
IPA_FLOFF = foreground_struct->foreground_lineoff;
|
||||
/* foreground pixel format pre-defined alpha, alpha calculation algorithm configuration */
|
||||
IPA_FPCTL &= ~(IPA_FPCTL_FPDAV | IPA_FPCTL_FAVCA | IPA_FPCTL_FPF | IPA_FPCTL_FIIMEN);
|
||||
IPA_FPCTL |= (foreground_struct->foreground_prealpha << 24U);
|
||||
IPA_FPCTL |= foreground_struct->foreground_alpha_algorithm;
|
||||
IPA_FPCTL |= foreground_struct->foreground_pf;
|
||||
if(ENABLE == foreground_struct->foreground_interlace_mode){
|
||||
IPA_FPCTL |= IPA_FPCTL_FIIMEN;
|
||||
}
|
||||
/* foreground pre-defined red green blue configuration */
|
||||
IPA_FPV &= ~(IPA_FPV_FPDRV | IPA_FPV_FPDGV| IPA_FPV_FPDBV);
|
||||
IPA_FPV |= ((foreground_struct->foreground_prered << 16U) | (foreground_struct->foreground_pregreen << 8U)
|
||||
| (foreground_struct->foreground_preblue));
|
||||
/* foreground even frame / UV memory base address configuration */
|
||||
IPA_EF_UV_MADDR &= ~(IPA_EF_UV_MADDR_EFUVMADDR);
|
||||
IPA_EF_UV_MADDR = foreground_struct->foreground_efuv_memaddr;
|
||||
|
||||
if(SET == tempflag){
|
||||
/* restore the state of TEN */
|
||||
IPA_CTL |= IPA_CTL_TEN;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the structure of IPA background parameter struct with the default values, it is
|
||||
suggested that call this function after an ipa_background_parameter_struct structure is defined
|
||||
\param[in] none
|
||||
\param[out] background_struct: the data needed to initialize background
|
||||
\retval none
|
||||
*/
|
||||
void ipa_background_struct_para_init(ipa_background_parameter_struct* background_struct)
|
||||
{
|
||||
/* initialize the struct parameters with default values */
|
||||
background_struct->background_memaddr = IPA_DEFAULT_VALUE;
|
||||
background_struct->background_lineoff = IPA_DEFAULT_VALUE;
|
||||
background_struct->background_prealpha = IPA_DEFAULT_VALUE;
|
||||
background_struct->background_alpha_algorithm = IPA_BG_ALPHA_MODE_0;
|
||||
background_struct->background_pf = BACKGROUND_PPF_ARGB8888;
|
||||
background_struct->background_prered = IPA_DEFAULT_VALUE;
|
||||
background_struct->background_pregreen = IPA_DEFAULT_VALUE;
|
||||
background_struct->background_preblue = IPA_DEFAULT_VALUE;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize background parameters
|
||||
\param[in] background_struct: the data needed to initialize background
|
||||
background_memaddr: background memory base address
|
||||
background_lineoff: background line offset
|
||||
background_prealpha: background pre-defined alpha value
|
||||
background_alpha_algorithm: IPA_BG_ALPHA_MODE_0, IPA_FG_ALPHA_MODE_1, IPA_FG_ALPHA_MODE_2
|
||||
background_pf: background pixel format(BACKGROUND_PPF_ARGB8888, BACKGROUND_PPF_RGB888, BACKGROUND_PPF_RGB565,
|
||||
BACKGROUND_PPF_ARGB1555, BACKGROUND_PPF_ARGB4444, BACKGROUND_PPF_L8, BACKGROUND_PPF_AL44,
|
||||
BACKGROUND_PPF_AL88, BACKGROUND_PPF_L4, BACKGROUND_PPF_A8, BACKGROUND_PPF_A4)
|
||||
background_prered: background pre-defined red value
|
||||
background_pregreen: background pre-defined green value
|
||||
background_preblue: background pre-defined blue value
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ipa_background_init(ipa_background_parameter_struct* background_struct)
|
||||
{
|
||||
FlagStatus tempflag = RESET;
|
||||
if(RESET != (IPA_CTL & IPA_CTL_TEN)){
|
||||
tempflag = SET;
|
||||
/* reset the TEN in order to configure the following bits */
|
||||
IPA_CTL &= ~IPA_CTL_TEN;
|
||||
}
|
||||
|
||||
/* background memory base address configuration */
|
||||
IPA_BMADDR &= ~(IPA_BMADDR_BMADDR);
|
||||
IPA_BMADDR = background_struct->background_memaddr;
|
||||
/* background line offset configuration */
|
||||
IPA_BLOFF &= ~(IPA_BLOFF_BLOFF);
|
||||
IPA_BLOFF = background_struct->background_lineoff;
|
||||
/* background pixel format pre-defined alpha, alpha calculation algorithm configuration */
|
||||
IPA_BPCTL &= ~(IPA_BPCTL_BPDAV | IPA_BPCTL_BAVCA | IPA_BPCTL_BPF);
|
||||
IPA_BPCTL |= (background_struct->background_prealpha << 24U);
|
||||
IPA_BPCTL |= background_struct->background_alpha_algorithm;
|
||||
IPA_BPCTL |= background_struct->background_pf;
|
||||
/* background pre-defined red green blue configuration */
|
||||
IPA_BPV &= ~(IPA_BPV_BPDRV|IPA_BPV_BPDGV | IPA_BPV_BPDBV);
|
||||
IPA_BPV |= ((background_struct->background_prered << 16U) | (background_struct->background_pregreen << 8U)
|
||||
| (background_struct->background_preblue));
|
||||
|
||||
if(SET == tempflag){
|
||||
/* restore the state of TEN */
|
||||
IPA_CTL |= IPA_CTL_TEN;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the structure of IPA destination parameter struct with the default values, it is
|
||||
suggested that call this function after an ipa_destination_parameter_struct structure is defined
|
||||
\param[in] none
|
||||
\param[out] destination_struct: the data needed to initialize destination parameter
|
||||
\retval none
|
||||
*/
|
||||
void ipa_destination_struct_para_init(ipa_destination_parameter_struct* destination_struct)
|
||||
{
|
||||
/* initialize the struct parameters with default values */
|
||||
destination_struct->destination_pf = IPA_DPF_ARGB8888;
|
||||
destination_struct->destination_lineoff = IPA_DEFAULT_VALUE;
|
||||
destination_struct->destination_prealpha = IPA_DEFAULT_VALUE;
|
||||
destination_struct->destination_prered = IPA_DEFAULT_VALUE;
|
||||
destination_struct->destination_pregreen = IPA_DEFAULT_VALUE;
|
||||
destination_struct->destination_preblue = IPA_DEFAULT_VALUE;
|
||||
destination_struct->destination_memaddr = IPA_DEFAULT_VALUE;
|
||||
destination_struct->image_width = IPA_DEFAULT_VALUE;
|
||||
destination_struct->image_height = IPA_DEFAULT_VALUE;
|
||||
destination_struct->image_rotate = DESTINATION_ROTATE_0;
|
||||
destination_struct->image_hor_decimation = DESTINATION_HORDECIMATE_DISABLE;
|
||||
destination_struct->image_ver_decimation = DESTINATION_VERDECIMATE_DISABLE;
|
||||
destination_struct->image_bilinear_xscale = IPA_DEFAULT_SCALE;
|
||||
destination_struct->image_bilinear_yscale = IPA_DEFAULT_SCALE;
|
||||
destination_struct->image_scaling_width = IPA_DEFAULT_VALUE;
|
||||
destination_struct->image_scaling_height = IPA_DEFAULT_VALUE;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize destination parameters
|
||||
\param[in] destination_struct: the data needed to initialize destination parameters
|
||||
destination_pf: IPA_DPF_ARGB8888, IPA_DPF_RGB888, IPA_DPF_RGB565, IPA_DPF_ARGB1555,
|
||||
IPA_DPF_ARGB4444, refer to ipa_dpf_enum
|
||||
destination_lineoff: destination line offset
|
||||
destination_prealpha: destination pre-defined alpha value
|
||||
destination_prered: destination pre-defined red value
|
||||
destination_pregreen: destination pre-defined green value
|
||||
destination_preblue: destination pre-defined blue value
|
||||
destination_memaddr: destination memory base address
|
||||
image_width: width of the image to be processed
|
||||
image_height: height of the image to be processed
|
||||
image_rotate: DESTINATION_ROTATE_0, DESTINATION_ROTATE_90,
|
||||
DESTINATION_ROTATE_180, DESTINATION_ROTATE_270
|
||||
image_hor_decimation: DESTINATION_HORDECIMATE_DISABLE, DESTINATION_HORDECIMATE_2,
|
||||
DESTINATION_HORDECIMATE_4, DESTINATION_HORDECIMATE_8
|
||||
image_ver_decimation: DESTINATION_VERDECIMATE_DISABLE, DESTINATION_VERDECIMATE_2,
|
||||
DESTINATION_VERDECIMATE_4, DESTINATION_VERDECIMATE_8
|
||||
image_bilinear_xscale: x scaling factor
|
||||
image_bilinear_yscale: y scaling factor
|
||||
image_scaling_width: width of the image after scaling
|
||||
image_scaling_height: height of the image after scaling
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ipa_destination_init(ipa_destination_parameter_struct* destination_struct)
|
||||
{
|
||||
uint32_t destination_pixelformat;
|
||||
FlagStatus tempflag = RESET;
|
||||
if(RESET != (IPA_CTL & IPA_CTL_TEN)){
|
||||
tempflag = SET;
|
||||
/* reset the TEN in order to configure the following bits */
|
||||
IPA_CTL &= ~IPA_CTL_TEN;
|
||||
}
|
||||
|
||||
/* destination pixel format, interlace sampling method and rotation configuration */
|
||||
IPA_DPCTL &= ~(IPA_DPCTL_DPF | IPA_DPCTL_ROT | IPA_DPCTL_HORDEC | IPA_DPCTL_VERDEC);
|
||||
IPA_DPCTL = (destination_struct->destination_pf |
|
||||
destination_struct->image_rotate |
|
||||
destination_struct->image_hor_decimation |
|
||||
destination_struct->image_ver_decimation);
|
||||
destination_pixelformat = destination_struct->destination_pf;
|
||||
/* destination pixel format ARGB8888 */
|
||||
switch(destination_pixelformat){
|
||||
case IPA_DPF_ARGB8888:
|
||||
IPA_DPV &= ~(IPA_DPV_DPDBV_0 | (IPA_DPV_DPDGV_0) | (IPA_DPV_DPDRV_0) | (IPA_DPV_DPDAV_0));
|
||||
IPA_DPV = (destination_struct->destination_preblue | (destination_struct->destination_pregreen << 8U)
|
||||
| (destination_struct->destination_prered << 16U)
|
||||
| (destination_struct->destination_prealpha << 24U));
|
||||
break;
|
||||
/* destination pixel format RGB888 */
|
||||
case IPA_DPF_RGB888:
|
||||
IPA_DPV &= ~(IPA_DPV_DPDBV_1 | (IPA_DPV_DPDGV_1) | (IPA_DPV_DPDRV_1));
|
||||
IPA_DPV = (destination_struct->destination_preblue | (destination_struct->destination_pregreen << 8U)
|
||||
| (destination_struct->destination_prered << 16U));
|
||||
break;
|
||||
/* destination pixel format RGB565 */
|
||||
case IPA_DPF_RGB565:
|
||||
IPA_DPV &= ~(IPA_DPV_DPDBV_2 | (IPA_DPV_DPDGV_2) | (IPA_DPV_DPDRV_2));
|
||||
IPA_DPV = (destination_struct->destination_preblue | (destination_struct->destination_pregreen << 5U)
|
||||
| (destination_struct->destination_prered << 11U));
|
||||
break;
|
||||
/* destination pixel format ARGB1555 */
|
||||
case IPA_DPF_ARGB1555:
|
||||
IPA_DPV &= ~(IPA_DPV_DPDBV_3 | (IPA_DPV_DPDGV_3) | (IPA_DPV_DPDRV_3)|(IPA_DPV_DPDAV_3));
|
||||
IPA_DPV = (destination_struct->destination_preblue | (destination_struct->destination_pregreen << 5U)
|
||||
| (destination_struct->destination_prered << 10U)
|
||||
| (destination_struct->destination_prealpha << 15U));
|
||||
break;
|
||||
/* destination pixel format ARGB4444 */
|
||||
case IPA_DPF_ARGB4444:
|
||||
IPA_DPV &= ~(IPA_DPV_DPDBV_4 | (IPA_DPV_DPDGV_4) | (IPA_DPV_DPDRV_4)|(IPA_DPV_DPDAV_4));
|
||||
IPA_DPV = (destination_struct->destination_preblue | (destination_struct->destination_pregreen << 4U)
|
||||
| (destination_struct->destination_prered << 8U)
|
||||
| (destination_struct->destination_prealpha << 12U));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* destination memory base address configuration */
|
||||
IPA_DMADDR &= ~(IPA_DMADDR_DMADDR);
|
||||
IPA_DMADDR = destination_struct->destination_memaddr;
|
||||
/* destination line offset configuration */
|
||||
IPA_DLOFF &= ~(IPA_DLOFF_DLOFF);
|
||||
IPA_DLOFF = destination_struct->destination_lineoff;
|
||||
/* image size configuration */
|
||||
IPA_IMS &= ~(IPA_IMS_HEIGHT | IPA_IMS_WIDTH);
|
||||
IPA_IMS |= ((destination_struct->image_width << 16U) | (destination_struct->image_height));
|
||||
/* xscale and yscale configuration */
|
||||
IPA_BSCTL &= ~(IPA_BSCTL_XSCALE | IPA_BSCTL_YSCALE);
|
||||
IPA_BSCTL = ((destination_struct->image_bilinear_xscale & IPA_BSCTL_XSCALE) |
|
||||
((uint32_t)(destination_struct->image_bilinear_yscale << 16U) & IPA_BSCTL_YSCALE));
|
||||
/* image size after scaling configuration */
|
||||
IPA_DIMS &= ~(IPA_DIMS_DWIDTH | IPA_DIMS_DHEIGHT);
|
||||
IPA_DIMS = (destination_struct->image_scaling_height & IPA_DIMS_DHEIGHT) |
|
||||
((uint32_t)((destination_struct->image_scaling_width << 16U) & IPA_DIMS_DWIDTH));
|
||||
|
||||
if(SET == tempflag){
|
||||
/* restore the state of TEN */
|
||||
IPA_CTL |= IPA_CTL_TEN;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize IPA foreground LUT parameters
|
||||
\param[in] fg_lut_num: foreground LUT number of pixel
|
||||
\param[in] fg_lut_pf: foreground LUT pixel format(IPA_LUT_PF_ARGB8888, IPA_LUT_PF_RGB888)
|
||||
\param[in] fg_lut_addr: foreground LUT memory base address
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ipa_foreground_lut_init(uint8_t fg_lut_num, uint8_t fg_lut_pf, uint32_t fg_lut_addr)
|
||||
{
|
||||
FlagStatus tempflag = RESET;
|
||||
if(RESET != (IPA_FPCTL & IPA_FPCTL_FLLEN)){
|
||||
tempflag = SET;
|
||||
/* reset the FLLEN in order to configure the following bits */
|
||||
IPA_FPCTL &= ~IPA_FPCTL_FLLEN;
|
||||
}
|
||||
|
||||
/* foreground LUT number of pixel configuration */
|
||||
IPA_FPCTL |= ((uint32_t)fg_lut_num << 8U);
|
||||
/* foreground LUT pixel format configuration */
|
||||
if(IPA_LUT_PF_RGB888 == fg_lut_pf){
|
||||
IPA_FPCTL |= IPA_FPCTL_FLPF;
|
||||
}else if(IPA_LUT_PF_ARGB8888 == fg_lut_pf){
|
||||
IPA_FPCTL &= ~(IPA_FPCTL_FLPF);
|
||||
}else{
|
||||
}
|
||||
/* foreground LUT memory base address configuration */
|
||||
IPA_FLMADDR &= ~(IPA_FLMADDR_FLMADDR);
|
||||
IPA_FLMADDR = fg_lut_addr;
|
||||
|
||||
if(SET == tempflag){
|
||||
/* restore the state of FLLEN */
|
||||
IPA_FPCTL |= IPA_FPCTL_FLLEN;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize IPA background LUT parameters
|
||||
\param[in] bg_lut_num: background LUT number of pixel
|
||||
\param[in] bg_lut_pf: background LUT pixel format(IPA_LUT_PF_ARGB8888, IPA_LUT_PF_RGB888)
|
||||
\param[in] bg_lut_addr: background LUT memory base address
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ipa_background_lut_init(uint8_t bg_lut_num, uint8_t bg_lut_pf, uint32_t bg_lut_addr)
|
||||
{
|
||||
FlagStatus tempflag = RESET;
|
||||
if(RESET != (IPA_BPCTL & IPA_BPCTL_BLLEN)){
|
||||
tempflag = SET;
|
||||
/* reset the BLLEN in order to configure the following bits */
|
||||
IPA_BPCTL &= ~IPA_BPCTL_BLLEN;
|
||||
}
|
||||
|
||||
/* background LUT number of pixel configuration */
|
||||
IPA_BPCTL |= ((uint32_t)bg_lut_num << 8U);
|
||||
/* background LUT pixel format configuration */
|
||||
if(IPA_LUT_PF_RGB888 == bg_lut_pf){
|
||||
IPA_BPCTL |= IPA_BPCTL_BLPF;
|
||||
}else if(IPA_LUT_PF_ARGB8888 == bg_lut_pf){
|
||||
IPA_BPCTL &= ~(IPA_BPCTL_BLPF);
|
||||
}else{
|
||||
}
|
||||
/* background LUT memory base address configuration */
|
||||
IPA_BLMADDR &= ~(IPA_BLMADDR_BLMADDR);
|
||||
IPA_BLMADDR = bg_lut_addr;
|
||||
|
||||
if(SET == tempflag){
|
||||
/* restore the state of BLLEN */
|
||||
IPA_BPCTL |= IPA_BPCTL_BLLEN;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure IPA line mark
|
||||
\param[in] line_num: line number
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ipa_line_mark_config(uint16_t line_num)
|
||||
{
|
||||
IPA_LM &= ~(IPA_LM_LM);
|
||||
IPA_LM = line_num;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief inter-timer enable or disable
|
||||
\param[in] timer_cfg: IPA_INTER_TIMER_ENABLE,IPA_INTER_TIMER_DISABLE
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ipa_inter_timer_config(uint8_t timer_cfg)
|
||||
{
|
||||
if(IPA_INTER_TIMER_ENABLE == timer_cfg){
|
||||
/* inter-timer enable */
|
||||
IPA_ITCTL |= IPA_ITCTL_ITEN;
|
||||
}else if(IPA_INTER_TIMER_DISABLE == timer_cfg){
|
||||
/* inter-timer disable */
|
||||
IPA_ITCTL &= ~(IPA_ITCTL_ITEN);
|
||||
}else{
|
||||
/* do nothing */
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the number of clock cycles interval
|
||||
\param[in] clk_num: the number of clock cycles
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ipa_interval_clock_num_config(uint8_t clk_num)
|
||||
{
|
||||
/* NCCI[7:0] bits have no meaning if ITEN is '0' */
|
||||
IPA_ITCTL &= ~(IPA_ITCTL_NCCI);
|
||||
IPA_ITCTL |= ((uint32_t)clk_num << 8U);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the color space conversion parameter
|
||||
\param[out] conversion_struct: the data needed to configure color conversion parameters
|
||||
\param[in] ipa_colorspace_enum: the color space
|
||||
IPA_COLORSPACE_YUV: using default YUV parameter to initialization struct
|
||||
IPA_COLORSPACE_YCBCR: using default YCbCr parameter to initialization struct
|
||||
\retval none
|
||||
*/
|
||||
void ipa_color_conversion_struct_para_init(ipa_conversion_parameter_struct* conversion_struct, ipa_colorspace_enum colorspace)
|
||||
{
|
||||
if(IPA_COLORSPACE_YUV == colorspace){
|
||||
/* initialize the struct parameters with default YUV conversion values */
|
||||
conversion_struct->color_space = IPA_COLORSPACE_YUV;
|
||||
conversion_struct->y_offset = IPA_DEFAULT_YUV_CONV_YOFFSET;
|
||||
conversion_struct->uv_offset = IPA_DEFAULT_YUV_CONV_UVOFFSET;
|
||||
conversion_struct->coef_c0 = IPA_DEFAULT_YUV_CONV_C0OFFSET;
|
||||
conversion_struct->coef_c1 = IPA_DEFAULT_YUV_CONV_C1OFFSET;
|
||||
conversion_struct->coef_c2 = IPA_DEFAULT_YUV_CONV_C2OFFSET;
|
||||
conversion_struct->coef_c3 = IPA_DEFAULT_YUV_CONV_C3OFFSET;
|
||||
conversion_struct->coef_c4 = IPA_DEFAULT_YUV_CONV_C4OFFSET;
|
||||
}else if(IPA_COLORSPACE_YCBCR == colorspace){
|
||||
/* initialize the struct parameters with default YCbCr conversion values */
|
||||
conversion_struct->color_space = IPA_COLORSPACE_YCBCR;
|
||||
conversion_struct->y_offset = IPA_DEFAULT_YCBCR_CONV_YOFFSET;
|
||||
conversion_struct->uv_offset = IPA_DEFAULT_YCBCR_CONV_UVOFFSET;
|
||||
conversion_struct->coef_c0 = IPA_DEFAULT_YCBCR_CONV_C0OFFSET;
|
||||
conversion_struct->coef_c1 = IPA_DEFAULT_YCBCR_CONV_C1OFFSET;
|
||||
conversion_struct->coef_c2 = IPA_DEFAULT_YCBCR_CONV_C2OFFSET;
|
||||
conversion_struct->coef_c3 = IPA_DEFAULT_YCBCR_CONV_C3OFFSET;
|
||||
conversion_struct->coef_c4 = IPA_DEFAULT_YCBCR_CONV_C4OFFSET;
|
||||
}else{
|
||||
/* do nothing */
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the color space conversion parameter
|
||||
\param[in] conversion_struct: the data needed to configure color conversion parameters
|
||||
color_space: IPA_COLORSPACE_YUV, IPA_COLORSPACE_YCBCR
|
||||
y_offset: offset implicit in the Y data
|
||||
uv_offset: offset implicit in the UV data
|
||||
coef_c0: Y multiplier coefficient
|
||||
coef_c1: V/Cr red multiplier coefficient
|
||||
coef_c2: V/Cr green multiplier coefficient
|
||||
coef_c3: U/Cb green multiplier coefficient
|
||||
coef_c4: U/Cb blue multiplier coefficient
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ipa_color_conversion_config(ipa_conversion_parameter_struct* conversion_struct)
|
||||
{
|
||||
FlagStatus tempflag = RESET;
|
||||
if(RESET != (IPA_CTL & IPA_CTL_TEN)){
|
||||
tempflag = SET;
|
||||
/* reset the TEN in order to configure the following bits */
|
||||
IPA_CTL &= ~IPA_CTL_TEN;
|
||||
}
|
||||
|
||||
/* Y offset, UV offset, compliment Y multiplier configuration */
|
||||
IPA_CSCC_CFG0 &= ~(IPA_CSCC_CFG0_YOFF | IPA_CSCC_CFG0_UVOFF | IPA_CSCC_CFG0_C0);
|
||||
IPA_CSCC_CFG0 |= (((conversion_struct->y_offset) & IPA_CSCC_CFG0_YOFF) |
|
||||
((uint32_t)(conversion_struct->uv_offset << 9U) & IPA_CSCC_CFG0_UVOFF) |
|
||||
((uint32_t)(conversion_struct->coef_c0 << 18U) & IPA_CSCC_CFG0_C0));
|
||||
/* red V/Cr multiplier, blue U/Cb multiplier configuration */
|
||||
IPA_CSCC_CFG1 &= ~(IPA_CSCC_CFG1_C1 | IPA_CSCC_CFG1_C4);
|
||||
IPA_CSCC_CFG1 |= ((conversion_struct->coef_c4 & IPA_CSCC_CFG1_C4) |
|
||||
((uint32_t)(conversion_struct->coef_c1 << 16U) & IPA_CSCC_CFG1_C1));
|
||||
/* green V/Cr multiplier coefficient, green U/Cb multiplier configuration */
|
||||
IPA_CSCC_CFG2 &= ~(IPA_CSCC_CFG2_C2 | IPA_CSCC_CFG2_C3);
|
||||
IPA_CSCC_CFG2 |= ((conversion_struct->coef_c3 & IPA_CSCC_CFG2_C3) |
|
||||
((uint32_t)(conversion_struct->coef_c2 << 16U) & IPA_CSCC_CFG2_C2));
|
||||
|
||||
if(IPA_COLORSPACE_YUV == conversion_struct->color_space){
|
||||
/* convert YUV to RGB */
|
||||
IPA_CSCC_CFG0 &= ~(IPA_CSCC_CFG0_CONVMOD);
|
||||
}else{
|
||||
/* convert YCbCr to RGB */
|
||||
IPA_CSCC_CFG0 |= IPA_CSCC_CFG0_CONVMOD;
|
||||
}
|
||||
|
||||
if(SET == tempflag){
|
||||
/* restore the state of TEN */
|
||||
IPA_CTL |= IPA_CTL_TEN;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure IPA foreground scaling, including horizontal/vertical pre-decimation factors and X/Y scaling factors
|
||||
\param[in] horizontal_decimation: horizontal scaling value
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DESTINATION_HORDECIMATE_DISABLE: disable horizontal decimate
|
||||
\arg DESTINATION_HORDECIMATE_2: horizontal decimated by 2
|
||||
\arg DESTINATION_HORDECIMATE_4: horizontal decimated by 4
|
||||
\arg DESTINATION_HORDECIMATE_8: horizontal decimated by 8
|
||||
\param[in] vertical_decimation: vertical scaling value
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DESTINATION_VERDECIMATE_DISABLE: disable vertical decimate
|
||||
\arg DESTINATION_VERDECIMATE_2: vertical decimated by 2
|
||||
\arg DESTINATION_VERDECIMATE_4: vertical decimated by 4
|
||||
\arg DESTINATION_VERDECIMATE_8: vertical decimated by 8
|
||||
\param[in] image_scaling_width: image scaling factor of width
|
||||
\param[in] image_scaling_height: image scaling factor of height
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ipa_foreground_scaling_config(uint32_t horizontal_decimation, uint32_t vertical_decimation, uint32_t image_scaling_width, uint32_t image_scaling_height)
|
||||
{
|
||||
/* configure decimation filter */
|
||||
IPA_DPCTL &= ~(uint32_t)(IPA_DPCTL_VERDEC | IPA_DPCTL_HORDEC);
|
||||
IPA_DPCTL |= (horizontal_decimation | vertical_decimation);
|
||||
|
||||
/* XScaling and YScaling configuration */
|
||||
IPA_BSCTL &= ~(IPA_BSCTL_XSCALE | IPA_BSCTL_YSCALE);
|
||||
IPA_BSCTL = ((image_scaling_width & IPA_BSCTL_XSCALE) |
|
||||
((uint32_t)(image_scaling_height << 16U) & IPA_BSCTL_YSCALE));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure IPA destination scaling, including width/height of image to be processed
|
||||
\param[in] dest_scaling_width: width of destination image after scaling
|
||||
\param[in] dest_scaling_height: height of destination image after scaling
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ipa_destination_scaling_config(uint32_t dest_scaling_width, uint32_t dest_scaling_height)
|
||||
{
|
||||
IPA_DIMS &= ~(IPA_DIMS_DWIDTH | IPA_DIMS_DHEIGHT);
|
||||
IPA_DIMS = (dest_scaling_height & IPA_DIMS_DHEIGHT) |
|
||||
((uint32_t)((dest_scaling_width << 16U) & IPA_DIMS_DWIDTH));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get IPA flag status in IPA_INTF register
|
||||
\param[in] flag: IPA flags
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg IPA_FLAG_TAE: transfer access error interrupt flag
|
||||
\arg IPA_FLAG_FTF: full transfer finish interrupt flag
|
||||
\arg IPA_FLAG_TLM: transfer line mark interrupt flag
|
||||
\arg IPA_FLAG_LAC: LUT access conflict interrupt flag
|
||||
\arg IPA_FLAG_LLF: LUT loading finish interrupt flag
|
||||
\arg IPA_FLAG_WCF: wrong configuration interrupt flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
FlagStatus ipa_flag_get(uint32_t flag)
|
||||
{
|
||||
if(RESET != (IPA_INTF & flag)){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear IPA flag in IPA_INTF register
|
||||
\param[in] flag: IPA flags
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg IPA_FLAG_TAE: transfer access error interrupt flag
|
||||
\arg IPA_FLAG_FTF: full transfer finish interrupt flag
|
||||
\arg IPA_FLAG_TLM: transfer line mark interrupt flag
|
||||
\arg IPA_FLAG_LAC: LUT access conflict interrupt flag
|
||||
\arg IPA_FLAG_LLF: LUT loading finish interrupt flag
|
||||
\arg IPA_FLAG_WCF: wrong configuration interrupt flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ipa_flag_clear(uint32_t flag)
|
||||
{
|
||||
IPA_INTC |= (flag);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable IPA interrupt
|
||||
\param[in] int_flag: IPA interrupt flags
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg IPA_INT_TAE: transfer access error interrupt
|
||||
\arg IPA_INT_FTF: full transfer finish interrupt
|
||||
\arg IPA_INT_TLM: transfer line mark interrupt
|
||||
\arg IPA_INT_LAC: LUT access conflict interrupt
|
||||
\arg IPA_INT_LLF: LUT loading finish interrupt
|
||||
\arg IPA_INT_WCF: wrong configuration interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ipa_interrupt_enable(uint32_t int_flag)
|
||||
{
|
||||
IPA_CTL |= (int_flag);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable IPA interrupt
|
||||
\param[in] int_flag: IPA interrupt flags
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg IPA_INT_TAE: transfer access error interrupt
|
||||
\arg IPA_INT_FTF: full transfer finish interrupt
|
||||
\arg IPA_INT_TLM: transfer line mark interrupt
|
||||
\arg IPA_INT_LAC: LUT access conflict interrupt
|
||||
\arg IPA_INT_LLF: LUT loading finish interrupt
|
||||
\arg IPA_INT_WCF: wrong configuration interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ipa_interrupt_disable(uint32_t int_flag)
|
||||
{
|
||||
IPA_CTL &= ~(int_flag);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get IPA interrupt flag
|
||||
\param[in] int_flag: IPA interrupt flag flags
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg IPA_INT_FLAG_TAE: transfer access error interrupt flag
|
||||
\arg IPA_INT_FLAG_FTF: full transfer finish interrupt flag
|
||||
\arg IPA_INT_FLAG_TLM: transfer line mark interrupt flag
|
||||
\arg IPA_INT_FLAG_LAC: LUT access conflict interrupt flag
|
||||
\arg IPA_INT_FLAG_LLF: LUT loading finish interrupt flag
|
||||
\arg IPA_INT_FLAG_WCF: wrong configuration interrupt flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
FlagStatus ipa_interrupt_flag_get(uint32_t int_flag)
|
||||
{
|
||||
if(RESET != (IPA_INTF & int_flag)){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear IPA interrupt flag
|
||||
\param[in] int_flag: IPA interrupt flag flags
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg IPA_INT_FLAG_TAE: transfer access error interrupt flag
|
||||
\arg IPA_INT_FLAG_FTF: full transfer finish interrupt flag
|
||||
\arg IPA_INT_FLAG_TLM: transfer line mark interrupt flag
|
||||
\arg IPA_INT_FLAG_LAC: LUT access conflict interrupt flag
|
||||
\arg IPA_INT_FLAG_LLF: LUT loading finish interrupt flag
|
||||
\arg IPA_INT_FLAG_WCF: wrong configuration interrupt flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ipa_interrupt_flag_clear(uint32_t int_flag)
|
||||
{
|
||||
IPA_INTC |= (int_flag);
|
||||
}
|
||||
@@ -0,0 +1,332 @@
|
||||
/*!
|
||||
\file gd32h7xx_lpdts.c
|
||||
\brief LPDTS driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_lpdts.h"
|
||||
|
||||
/* LPDTS high threshold value offset macro */
|
||||
#define LPDTS_IT_INTHT_OFFSET ((uint32_t)16U)
|
||||
/* sampling time offset macro */
|
||||
#define LPDTS_CFG_SPT_OFFSET ((uint32_t)16U)
|
||||
/* engineering value offset macro */
|
||||
#define LPDTS_SDATA_VAL_OFFSET ((uint32_t)16U)
|
||||
/* the T0 temperature macro */
|
||||
#define LPDTS_T0_TMP_VAL ((uint32_t)25U)
|
||||
|
||||
/*!
|
||||
\brief reset the LPDTS registers
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void lpdts_deinit(void)
|
||||
{
|
||||
rcu_periph_reset_enable(RCU_LPDTSRST);
|
||||
rcu_periph_reset_disable(RCU_LPDTSRST);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the parameters of LPDTS struct with the default values
|
||||
\param[in] none
|
||||
\param[out] init_struct: the initialization data needed to initialize LPDTS
|
||||
\retval none
|
||||
*/
|
||||
void lpdts_struct_para_init(lpdts_parameter_struct *init_struct)
|
||||
{
|
||||
/* set the struct with the default values */
|
||||
init_struct->ref_clock = REF_PCLK;
|
||||
init_struct->trigger_input = NO_HARDWARE_TRIGGER;
|
||||
init_struct->sampling_time = SPT_CLOCK_15;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the LPDTS
|
||||
\param[in] init_struct: the initialization data needed to initialize LPDTS_CFG
|
||||
ref_clock: REF_PCLK, REF_LXTAL
|
||||
trigger_input: NO_HARDWARE_TRIGGER, LPDTS_TRG
|
||||
sampling_time: SPT_CLOCK_x(x=1..15)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void lpdts_init(lpdts_parameter_struct *init_struct)
|
||||
{
|
||||
uint32_t reg;
|
||||
/* configure the LPDTS_CFG */
|
||||
reg = LPDTS_CFG;
|
||||
reg &= ~(LPDTS_CFG_REFSEL | LPDTS_CFG_ITSEL | LPDTS_CFG_SPT);
|
||||
reg |= (init_struct->ref_clock | init_struct->trigger_input | init_struct->sampling_time);
|
||||
LPDTS_CFG = reg;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable LPDTS temperature sensor
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void lpdts_enable(void)
|
||||
{
|
||||
LPDTS_CFG |= LPDTS_CFG_TSEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable LPDTS temperature sensor
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void lpdts_disable(void)
|
||||
{
|
||||
LPDTS_CFG &= ~LPDTS_CFG_TSEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable LPDTS software trigger
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void lpdts_soft_trigger_enable(void)
|
||||
{
|
||||
LPDTS_CFG |= LPDTS_CFG_TRGS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable LPDTS software trigger
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void lpdts_soft_trigger_disable(void)
|
||||
{
|
||||
LPDTS_CFG &= ~LPDTS_CFG_TRGS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure LPDTS high threshold value
|
||||
\param[in] value: high threshold value(0~65535)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void lpdts_high_threshold_set(uint16_t value)
|
||||
{
|
||||
uint32_t reg;
|
||||
/* configure the LPDTS_IT */
|
||||
reg = LPDTS_IT;
|
||||
reg &= ~LPDTS_IT_INTHT;
|
||||
reg |= (uint32_t)value << LPDTS_IT_INTHT_OFFSET;
|
||||
LPDTS_IT = reg;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure LPDTS low threshold value
|
||||
\param[in] value: low threshold value(0~65535)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void lpdts_low_threshold_set(uint16_t value)
|
||||
{
|
||||
uint32_t reg;
|
||||
/* configure the LPDTS_IT */
|
||||
reg = LPDTS_IT;
|
||||
reg &= ~LPDTS_IT_INTLT;
|
||||
reg |= (uint32_t)value;
|
||||
LPDTS_IT = reg;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure LPDTS reference clock selection
|
||||
\param[in] source: reference clock source
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg REF_PCLK: high speed reference clock (PCLK)
|
||||
\arg REF_LXTAL: low speed reference clock (LXTAL)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void lpdts_ref_clock_source_config(uint32_t source)
|
||||
{
|
||||
uint32_t reg;
|
||||
/* configure the LPDTS_CFG */
|
||||
reg = LPDTS_CFG;
|
||||
reg &= ~LPDTS_CFG_REFSEL;
|
||||
reg |= source;
|
||||
LPDTS_CFG = reg;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get temperature from LPDTS
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval temperature: temperature in deg C
|
||||
*/
|
||||
int32_t lpdts_temperature_get(void)
|
||||
{
|
||||
uint32_t freq;
|
||||
uint32_t count;
|
||||
uint32_t t0;
|
||||
uint32_t t0_freq;
|
||||
uint32_t ramp_coeff;
|
||||
uint32_t reg_cfg;
|
||||
int32_t temperature;
|
||||
|
||||
/* get the total number of samples */
|
||||
count = (LPDTS_DATA & LPDTS_DATA_COVAL);
|
||||
/* get LPDTS_CFG configuration */
|
||||
reg_cfg = LPDTS_CFG;
|
||||
|
||||
/* get the module frequency on Hz */
|
||||
if((reg_cfg & LPDTS_CFG_REFSEL) == LPDTS_CFG_REFSEL) {
|
||||
freq = (LXTAL_VALUE * count) / (2U * ((reg_cfg & LPDTS_CFG_SPT) >> LPDTS_CFG_SPT_OFFSET));
|
||||
} else {
|
||||
freq = (2U * rcu_clock_freq_get(CK_APB1) / count) * ((reg_cfg & LPDTS_CFG_SPT) >> LPDTS_CFG_SPT_OFFSET);
|
||||
}
|
||||
|
||||
/* read factory settings */
|
||||
t0 = (LPDTS_SDATA & LPDTS_SDATA_VAL) >> LPDTS_SDATA_VAL_OFFSET;
|
||||
if(t0 == 0U) {
|
||||
t0 = LPDTS_T0_TMP_VAL;
|
||||
}
|
||||
|
||||
/* get the T0 frequency on Hz */
|
||||
t0_freq = (LPDTS_SDATA & LPDTS_SDATA_FREQ) * 100U;
|
||||
/* get the ramp coefficient for the temperature sensor on deg C/Hz */
|
||||
ramp_coeff = LPDTS_RDATA & LPDTS_RDATA_RCVAL;
|
||||
|
||||
/* figure out the temperature deg C */
|
||||
temperature = (int32_t)t0 + (((int32_t)freq - (int32_t)t0_freq) / (int32_t)ramp_coeff);
|
||||
|
||||
return temperature;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get LPDTS flag
|
||||
\param[in] flag: LPDTS ready flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg LPDTS_FLAG_TSR
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus lpdts_flag_get(uint32_t flag)
|
||||
{
|
||||
FlagStatus status = RESET;
|
||||
|
||||
if(LPDTS_STAT & flag) {
|
||||
status = SET;
|
||||
}
|
||||
/* return the state of corresponding LPDTS flag */
|
||||
return status;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable LPDTS interrupt
|
||||
\param[in] interrupt: the LPDTS interrupt
|
||||
one or more parameters can be selected which is shown as below:
|
||||
\arg LPDTS_INT_EM
|
||||
\arg LPDTS_INT_LT
|
||||
\arg LPDTS_INT_HT
|
||||
\arg LPDTS_INT_EMA
|
||||
\arg LPDTS_INT_LTA
|
||||
\arg LPDTS_INT_HTA
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void lpdts_interrupt_enable(uint32_t interrupt)
|
||||
{
|
||||
LPDTS_INTEN |= interrupt;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable LPDTS interrupt
|
||||
\param[in] interrupt: the LPDTS interrupt
|
||||
one or more parameters can be selected which is shown as below:
|
||||
\arg LPDTS_INT_EM
|
||||
\arg LPDTS_INT_LT
|
||||
\arg LPDTS_INT_HT
|
||||
\arg LPDTS_INT_EMA
|
||||
\arg LPDTS_INT_LTA
|
||||
\arg LPDTS_INT_HTA
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void lpdts_interrupt_disable(uint32_t interrupt)
|
||||
{
|
||||
LPDTS_INTEN &= ~interrupt;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get LPDTS interrupt flag
|
||||
\param[in] flag: LPDTS interrupt flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg LPDTS_INT_FLAG_EM
|
||||
\arg LPDTS_INT_FLAG_LT
|
||||
\arg LPDTS_INT_FLAG_HT
|
||||
\arg LPDTS_INT_FLAG_EMA
|
||||
\arg LPDTS_INT_FLAG_LTA
|
||||
\arg LPDTS_INT_FLAG_HTA
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus lpdts_interrupt_flag_get(uint32_t flag)
|
||||
{
|
||||
FlagStatus status = RESET;
|
||||
uint32_t state;
|
||||
|
||||
state = LPDTS_STAT;
|
||||
if(state & flag) {
|
||||
state = LPDTS_INTEN;
|
||||
if(state & flag) {
|
||||
status = SET;
|
||||
}
|
||||
}
|
||||
/* return the state of corresponding LPDTS flag */
|
||||
return status;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear the LPDTS interrupt flag
|
||||
\param[in] flag: LPDTS flag
|
||||
one or more parameter can be selected which is shown as below:
|
||||
\arg LPDTS_INT_FLAG_EM
|
||||
\arg LPDTS_INT_FLAG_LT
|
||||
\arg LPDTS_INT_FLAG_HT
|
||||
\arg LPDTS_INT_FLAG_EMA
|
||||
\arg LPDTS_INT_FLAG_LTA
|
||||
\arg LPDTS_INT_FLAG_HTA
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void lpdts_interrupt_flag_clear(uint32_t flag)
|
||||
{
|
||||
/* clear the flags */
|
||||
LPDTS_INTC = flag;
|
||||
}
|
||||
@@ -0,0 +1,404 @@
|
||||
/*!
|
||||
\file gd32h7xx_mdio.c
|
||||
\brief MDIO driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_mdio.h"
|
||||
|
||||
/*!
|
||||
\brief reset MDIO
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void mdio_deinit(void)
|
||||
{
|
||||
/* reset MDIO */
|
||||
rcu_periph_reset_enable(RCU_MDIORST);
|
||||
rcu_periph_reset_disable(RCU_MDIORST);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief reset MDIO block
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void mdio_software_reset(void)
|
||||
{
|
||||
MDIO_CTL |= MDIO_CTL_SWRST;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize MDIO for communication
|
||||
\param[in] phy_size: PHY bit length
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg MDIO_PHY_BITS_3: PHY use 3 bits
|
||||
\arg MDIO_PHY_BITS_5: PHY use 5 bits
|
||||
\param[in] phy_softaddr: software provided PHYADR (0 - 31)
|
||||
\param[in] phy_sel: PHYADR select
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg MDIO_PHYADR_HARDWARE: sets expected PHYADR = PHYPIN[4:0]
|
||||
\arg MDIO_PHYADR_HW_SW_MIX(regval): sets Software address valid bits
|
||||
\arg MDIO_PHYADR_SOFTWARE: sets expected PHYADR = PHYSW[4:0]
|
||||
\arg other user defined value: 1 - 30
|
||||
\param[in] devadd: device type
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DEVADD_PMA_PMD: device type PMA/PMD
|
||||
\arg DEVADD_WIS: device type WIS
|
||||
\arg DEVADD_PCS: device type PCS
|
||||
\arg DEVADD_PHY_XS: device type PHY XS
|
||||
\arg DEVADD_DTE_XS: device type DTE XS
|
||||
\param[out] none
|
||||
\retval uint32_t: the PHYADR that the device will respond to 0 - 31
|
||||
*/
|
||||
uint32_t mdio_init(uint32_t phy_size, uint32_t phy_softaddr, uint32_t phy_sel, uint16_t devadd)
|
||||
{
|
||||
uint32_t phy_addr = 0U, phy_hard = 0U;
|
||||
|
||||
/* configure MDIO phy bit length */
|
||||
MDIO_CTL &= ~MDIO_CTL_PHYB;
|
||||
MDIO_CTL |= phy_size;
|
||||
|
||||
/* configure the PHYADR and DEVADD */
|
||||
MDIO_CFG &= ~(MDIO_CFG_PHYSW | MDIO_CFG_EPHYSEL | MDIO_CFG_EDEVADD);
|
||||
MDIO_CFG |= CFG_PHYSW(phy_softaddr) | CFG_EPHYSEL(phy_sel) | CFG_EDEVADD(devadd);
|
||||
|
||||
/* calculate the PHYADR that the device will respond to */
|
||||
phy_hard = mdio_phy_pin_read();
|
||||
phy_addr = (phy_hard & (~phy_sel)) | (phy_softaddr & phy_sel);
|
||||
|
||||
return phy_addr;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure MDIO phy bit length
|
||||
\param[in] phy_bit: PHY bit length
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg MDIO_PHY_BITS_3: PHY use 3 bits
|
||||
\arg MDIO_PHY_BITS_5: PHY use 5 bits
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void mdio_phy_length_config(uint32_t phy_bit)
|
||||
{
|
||||
MDIO_CTL &= ~MDIO_CTL_PHYB;
|
||||
MDIO_CTL |= phy_bit;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set the software PHYADR value
|
||||
\param[in] phy_soft: software provided PHYADR (0 - 31)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void mdio_soft_phyadr_set(uint32_t phy_soft)
|
||||
{
|
||||
MDIO_CFG &= ~MDIO_CFG_PHYSW;
|
||||
MDIO_CFG |= CFG_PHYSW(phy_soft);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief select the expected frame field PHYADR
|
||||
\param[in] phy_sel: PHYADR select
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg MDIO_PHYADR_HARDWARE: sets expected PHYADR = PHYPIN[4:0]
|
||||
\arg MDIO_PHYADR_SOFTWARE: sets expected PHYADR = PHYSW[4:0]
|
||||
\arg other user defined value: 1 - 30
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void mdio_framefield_phyadr_config(uint32_t phy_sel)
|
||||
{
|
||||
MDIO_CFG &= ~MDIO_CFG_EPHYSEL;
|
||||
MDIO_CFG |= CFG_EPHYSEL(phy_sel);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the expected frame field DEVADD
|
||||
\param[in] type: device type
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DEVADD_PMA_PMD: device type PMA/PMD
|
||||
\arg DEVADD_WIS: device type WIS
|
||||
\arg DEVADD_PCS: device type PCS
|
||||
\arg DEVADD_PHY_XS: device type PHY XS
|
||||
\arg DEVADD_DTE_XS: device type DTE XS
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void mdio_framefield_devadd_config(uint16_t type)
|
||||
{
|
||||
MDIO_CFG &= ~MDIO_CFG_EDEVADD;
|
||||
MDIO_CFG |= CFG_EDEVADD(type);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief read the hardware PRTADR[4:0] value
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval uint32_t: 0x0-0x1F
|
||||
*/
|
||||
uint32_t mdio_phy_pin_read(void)
|
||||
{
|
||||
return GET_PIN_PHYPIN(MDIO_PIN);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the expected frame bit timeout
|
||||
\param[in] timeout: timeout counter among frame bits (0 - 0xFFFF)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void mdio_timeout_config(uint16_t timeout)
|
||||
{
|
||||
MDIO_TO &= ~MDIO_TO_TOCNT;
|
||||
MDIO_TO |= TO_TOCNT(timeout);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable MDIO frame bit timeout
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void mdio_timeout_enable(void)
|
||||
{
|
||||
MDIO_TO |= MDIO_TO_TOEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable MDIO frame bit timeout
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void mdio_timeout_disable(void)
|
||||
{
|
||||
MDIO_TO &= ~MDIO_TO_TOEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief read the received frame field OP
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval uint16_t: 0x0-0x11
|
||||
*/
|
||||
uint16_t mdio_op_receive(void)
|
||||
{
|
||||
return (uint16_t)(GET_RFRM_ROP(MDIO_RFRM));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief read the received frame field PHYADR
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval uint16_t: 0x0-0x1F
|
||||
*/
|
||||
uint16_t mdio_phyadr_receive(void)
|
||||
{
|
||||
return (uint16_t)(GET_RFRM_RPHY(MDIO_RFRM));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief read the received frame field DEVADD
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval uint16_t: 0x0-0x1F
|
||||
*/
|
||||
uint16_t mdio_devadd_receive(void)
|
||||
{
|
||||
return (uint16_t)(GET_RFRM_RDEV(MDIO_RFRM));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief read the received frame field TA
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval uint16_t: 0x0-0x11
|
||||
*/
|
||||
uint16_t mdio_ta_receive(void)
|
||||
{
|
||||
return (uint16_t)(GET_RFRM_RTA(MDIO_RFRM));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief read the received frame field DATA
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval uint16_t: 0x0-0xFFFF
|
||||
*/
|
||||
uint16_t mdio_data_receive(void)
|
||||
{
|
||||
return (uint16_t)(GET_RDATA_RDATA(MDIO_RDATA));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief read the received frame field ADDRESS
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval uint16_t: 0x0-0xFFFF
|
||||
*/
|
||||
uint16_t mdio_address_receive(void)
|
||||
{
|
||||
return (uint16_t)(GET_RADDR_RADDR(MDIO_RADDR));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief transmit the frame field DATA
|
||||
\param[in] data: data to put in a read or post read increment address frame for transmission (0x0-0xFFFF)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void mdio_data_transmit(uint16_t data)
|
||||
{
|
||||
MDIO_TDATA = (uint32_t)data;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the flag status of the frame
|
||||
\param[in] flag: MDIO flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg MDIO_FLAG_WRFRM: a write data frame flag status
|
||||
\arg MDIO_FLAG_ADDRFRM: an address frame flag status
|
||||
\arg MDIO_FLAG_RDINCFRM: a post read increment address frame flag status
|
||||
\arg MDIO_FLAG_RDFRM: a read data frame flag status
|
||||
\arg MDIO_FLAG_DEVM: a DEVADD match frame flag status
|
||||
\arg MDIO_FLAG_DEVNM: a DEVADD nonmatch frame flag status
|
||||
\arg MDIO_FLAG_PHYM: a PHYADR match frame flag status
|
||||
\arg MDIO_FLAG_PHYNM: a PHYADR nonmatch frame flag status
|
||||
\arg MDIO_FLAG_TANM: a TA nonmatch frame flag status
|
||||
\arg MDIO_FLAG_TIMEOUT: timeout flag
|
||||
\arg MDIO_FLAG_TX_UNDERRUN: transmit underrun flag
|
||||
\arg MDIO_FLAG_RX_OVERRUN: receive overrun flag
|
||||
\arg MDIO_FLAG_RBNE: read data buffer not empty flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus mdio_flag_get(uint32_t flag)
|
||||
{
|
||||
__IO uint32_t reg = 0U;
|
||||
|
||||
reg = MDIO_STAT;
|
||||
if(RESET != (reg & flag)){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear the flag status
|
||||
\param[in] flag: MDIO flag
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg MDIO_FLAG_WRFRM: a write data frame flag status
|
||||
\arg MDIO_FLAG_ADDRFRM: an address frame flag status
|
||||
\arg MDIO_FLAG_RDINCFRM: a post read increment address frame flag status
|
||||
\arg MDIO_FLAG_RDFRM: a read data frame flag status
|
||||
\arg MDIO_FLAG_DEVM: a DEVADD match frame flag status
|
||||
\arg MDIO_FLAG_DEVNM: a DEVADD nonmatch frame flag status
|
||||
\arg MDIO_FLAG_PHYM: a PHYADR match frame flag status
|
||||
\arg MDIO_FLAG_PHYNM: a PHYADR nonmatch frame flag status
|
||||
\arg MDIO_FLAG_TANM: a TA nonmatch frame flag status
|
||||
\arg MDIO_FLAG_TIMEOUT: timeout flag
|
||||
\arg MDIO_FLAG_TX_UNDERRUN: transmit underrun flag
|
||||
\arg MDIO_FLAG_RX_OVERRUN: receive overrun flag
|
||||
\arg MDIO_FLAG_RBNE: read data buffer not empty flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void mdio_flag_clear(uint32_t flag)
|
||||
{
|
||||
__IO uint32_t reg = 0U;
|
||||
|
||||
reg = MDIO_TDATA;
|
||||
|
||||
if((MDIO_FLAG_RX_OVERRUN | MDIO_FLAG_RBNE) & flag){
|
||||
(void)(MDIO_RDATA);
|
||||
}else if(MDIO_FLAG_TX_UNDERRUN & flag){
|
||||
MDIO_TDATA = reg;
|
||||
}else if((MDIO_FLAG_WRFRM | MDIO_FLAG_ADDRFRM | MDIO_FLAG_RDINCFRM | MDIO_FLAG_RDFRM
|
||||
| MDIO_FLAG_DEVM | MDIO_FLAG_DEVNM | MDIO_FLAG_PHYM | MDIO_FLAG_PHYNM | MDIO_FLAG_TIMEOUT) & flag){
|
||||
(void)(MDIO_STAT);
|
||||
} else {
|
||||
/* illegal parameters */
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable MDIO interrupt
|
||||
\param[in] interrupt: MDIO interrupt
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg MDIO_INT_WRFRM: a write data frame interrupt
|
||||
\arg MDIO_INT_ADDRFRM: an address frame interrupt
|
||||
\arg MDIO_INT_RDINCFRM: a post read increment address frame interrupt
|
||||
\arg MDIO_INT_RDFRM: a read data frame interrupt
|
||||
\arg MDIO_INT_DEVM: a DEVADD match frame interrupt
|
||||
\arg MDIO_INT_DEVNM: a DEVADD nonmatch frame interrupt
|
||||
\arg MDIO_INT_PHYM: a PHYADR match frame interrupt
|
||||
\arg MDIO_INT_PHYNM: a PHYADR nonmatch frame interrupt
|
||||
\arg MDIO_INT_TANM: a TA nonmatch frame flag interrupt
|
||||
\arg MDIO_INT_TIMEOUT: a timeout interrupt
|
||||
\arg MDIO_INT_TX_UNDERRUN: a transmit underrun interrupt
|
||||
\arg MDIO_INT_RX_OVERRUN: a receive overrun interrupt
|
||||
\arg MDIO_INT_RBNE: a read data buffer not empty interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void mdio_interrupt_enable(uint32_t interrupt)
|
||||
{
|
||||
MDIO_INTEN |= interrupt;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable MDIO interrupt
|
||||
\param[in] interrupt: MDIO interrupt
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg MDIO_INT_WRFRM: a write data frame interrupt
|
||||
\arg MDIO_INT_ADDRFRM: an address frame interrupt
|
||||
\arg MDIO_INT_RDINCFRM: a post read increment address frame interrupt
|
||||
\arg MDIO_INT_RDFRM: a read data frame interrupt
|
||||
\arg MDIO_INT_DEVM: a DEVADD match frame interrupt
|
||||
\arg MDIO_INT_DEVNM: a DEVADD nonmatch frame interrupt
|
||||
\arg MDIO_INT_PHYM: a PHYADR match frame interrupt
|
||||
\arg MDIO_INT_PHYNM: a PHYADR nonmatch frame interrupt
|
||||
\arg MDIO_INT_TANM: a TA nonmatch frame flag interrupt
|
||||
\arg MDIO_INT_TIMEOUT: a timeout interrupt
|
||||
\arg MDIO_INT_TX_UNDERRUN: a transmit underrun interrupt
|
||||
\arg MDIO_INT_RX_OVERRUN: a receive overrun interrupt
|
||||
\arg MDIO_INT_RBNE: a read data buffer not empty interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void mdio_interrupt_disable(uint32_t interrupt)
|
||||
{
|
||||
MDIO_INTEN &= ~(interrupt);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,259 @@
|
||||
/*!
|
||||
\file gd32h7xx_misc.c
|
||||
\brief MISC driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_misc.h"
|
||||
|
||||
/*!
|
||||
\brief set the priority group
|
||||
\param[in] nvic_prigroup: the NVIC priority group
|
||||
\arg NVIC_PRIGROUP_PRE0_SUB4: 0 bits for pre-emption priority, 4 bits for subpriority
|
||||
\arg NVIC_PRIGROUP_PRE1_SUB3: 1 bits for pre-emption priority, 3 bits for subpriority
|
||||
\arg NVIC_PRIGROUP_PRE2_SUB2: 2 bits for pre-emption priority, 2 bits for subpriority
|
||||
\arg NVIC_PRIGROUP_PRE3_SUB1: 3 bits for pre-emption priority, 1 bits for subpriority
|
||||
\arg NVIC_PRIGROUP_PRE4_SUB0: 4 bits for pre-emption priority, 0 bits for subpriority
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void nvic_priority_group_set(uint32_t nvic_prigroup)
|
||||
{
|
||||
/* set the priority group value */
|
||||
SCB->AIRCR = NVIC_AIRCR_VECTKEY_MASK | nvic_prigroup;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable NVIC interrupt request
|
||||
\param[in] nvic_irq: the NVIC interrupt request, detailed in IRQn_Type
|
||||
\param[in] nvic_irq_pre_priority: the pre-emption priority needed to set
|
||||
\param[in] nvic_irq_sub_priority: the subpriority needed to set
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void nvic_irq_enable(IRQn_Type nvic_irq,
|
||||
uint8_t nvic_irq_pre_priority,
|
||||
uint8_t nvic_irq_sub_priority)
|
||||
{
|
||||
uint32_t temp_priority = 0x00U, temp_pre = 0x00U, temp_sub = 0x00U;
|
||||
|
||||
/* use the priority group value to get the temp_pre and the temp_sub */
|
||||
switch((SCB->AIRCR) & (uint32_t)0x700U) {
|
||||
case NVIC_PRIGROUP_PRE0_SUB4:
|
||||
temp_pre = 0U;
|
||||
temp_sub = 0x4U;
|
||||
break;
|
||||
case NVIC_PRIGROUP_PRE1_SUB3:
|
||||
temp_pre = 1U;
|
||||
temp_sub = 0x3U;
|
||||
break;
|
||||
case NVIC_PRIGROUP_PRE2_SUB2:
|
||||
temp_pre = 2U;
|
||||
temp_sub = 0x2U;
|
||||
break;
|
||||
case NVIC_PRIGROUP_PRE3_SUB1:
|
||||
temp_pre = 3U;
|
||||
temp_sub = 0x1U;
|
||||
break;
|
||||
case NVIC_PRIGROUP_PRE4_SUB0:
|
||||
temp_pre = 4U;
|
||||
temp_sub = 0x0U;
|
||||
break;
|
||||
default:
|
||||
nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
|
||||
temp_pre = 2U;
|
||||
temp_sub = 0x2U;
|
||||
break;
|
||||
}
|
||||
|
||||
/* get the temp_priority to fill the NVIC->IP register */
|
||||
temp_priority = (uint32_t)nvic_irq_pre_priority << (0x4U - temp_pre);
|
||||
temp_priority |= nvic_irq_sub_priority & (0x0FU >> (0x4U - temp_sub));
|
||||
temp_priority = temp_priority << 0x04U;
|
||||
NVIC->IP[(uint8_t)nvic_irq] = (uint8_t)temp_priority;
|
||||
|
||||
/* enable the selected IRQ */
|
||||
NVIC->ISER[(uint8_t)nvic_irq >> 0x05U] = (uint32_t)0x01U << ((uint8_t)nvic_irq & (uint8_t)0x1FU);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable NVIC interrupt request
|
||||
\param[in] nvic_irq: the NVIC interrupt request, detailed in IRQn_Type
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void nvic_irq_disable(IRQn_Type nvic_irq)
|
||||
{
|
||||
/* disable the selected IRQ.*/
|
||||
NVIC->ICER[(uint8_t)nvic_irq >> 0x05U] = (uint32_t)0x01U << ((uint8_t)nvic_irq & (uint8_t)0x1FU);
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set the NVIC vector table base address
|
||||
\param[in] nvic_vect_tab: the RAM or FLASH base address
|
||||
\arg NVIC_VECTTAB_RAM: RAM base address
|
||||
\arg NVIC_VECTTAB_FLASH: Flash base address
|
||||
\param[in] offset: vector table offset
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void nvic_vector_table_set(uint32_t nvic_vect_tab, uint32_t offset)
|
||||
{
|
||||
SCB->VTOR = nvic_vect_tab | (offset & NVIC_VECTTAB_OFFSET_MASK);
|
||||
__DSB();
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set the state of the low power mode
|
||||
\param[in] lowpower_mode: the low power mode state
|
||||
\arg SCB_LPM_SLEEP_EXIT_ISR: if chose this para, the system always enter low power
|
||||
mode by exiting from ISR
|
||||
\arg SCB_LPM_DEEPSLEEP: if chose this para, the system will enter the DEEPSLEEP mode
|
||||
\arg SCB_LPM_WAKE_BY_ALL_INT: if chose this para, the low power mode can be woke up
|
||||
by all the enable and disable interrupts
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void system_lowpower_set(uint8_t lowpower_mode)
|
||||
{
|
||||
SCB->SCR |= (uint32_t)lowpower_mode;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief reset the state of the low power mode
|
||||
\param[in] lowpower_mode: the low power mode state
|
||||
\arg SCB_LPM_SLEEP_EXIT_ISR: if chose this para, the system will exit low power
|
||||
mode by exiting from ISR
|
||||
\arg SCB_LPM_DEEPSLEEP: if chose this para, the system will enter the SLEEP mode
|
||||
\arg SCB_LPM_WAKE_BY_ALL_INT: if chose this para, the low power mode only can be
|
||||
woke up by the enable interrupts
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void system_lowpower_reset(uint8_t lowpower_mode)
|
||||
{
|
||||
SCB->SCR &= (~(uint32_t)lowpower_mode);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set the systick clock source
|
||||
\param[in] systick_clksource: the systick clock source needed to choose
|
||||
\arg SYSTICK_CLKSOURCE_CKSYS: systick clock source is from CK_SYS
|
||||
\arg SYSTICK_CLKSOURCE_CKSYS_DIV8: systick clock source is from CK_SYS/8
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void systick_clksource_set(uint32_t systick_clksource)
|
||||
{
|
||||
if(SYSTICK_CLKSOURCE_CKSYS == systick_clksource) {
|
||||
/* set the systick clock source from CK_SYS */
|
||||
SysTick->CTRL |= SYSTICK_CLKSOURCE_CKSYS;
|
||||
} else {
|
||||
/* set the systick clock source from CK_SYS/8 */
|
||||
SysTick->CTRL &= SYSTICK_CLKSOURCE_CKSYS_DIV8;
|
||||
}
|
||||
}
|
||||
|
||||
#if (__MPU_PRESENT == 1)
|
||||
|
||||
/*!
|
||||
\brief initialize mpu_region_init_struct with the default values
|
||||
\param[in] mpu_init_struct: pointer to a mpu_region_init_struct structure
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void mpu_region_struct_para_init(mpu_region_init_struct *mpu_init_struct)
|
||||
{
|
||||
mpu_init_struct->region_number = MPU_REGION_NUMBER0;
|
||||
mpu_init_struct->region_base_address = 0x00000000U;
|
||||
mpu_init_struct->instruction_exec = MPU_INSTRUCTION_EXEC_PERMIT;
|
||||
mpu_init_struct->access_permission = MPU_AP_NO_ACCESS;
|
||||
mpu_init_struct->tex_type = MPU_TEX_TYPE0;
|
||||
mpu_init_struct->access_shareable = MPU_ACCESS_SHAREABLE;
|
||||
mpu_init_struct->access_cacheable = MPU_ACCESS_CACHEABLE;
|
||||
mpu_init_struct->access_bufferable = MPU_ACCESS_BUFFERABLE;
|
||||
mpu_init_struct->subregion_disable = MPU_SUBREGION_ENABLE;
|
||||
mpu_init_struct->region_size = MPU_REGION_SIZE_32B;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the MPU region
|
||||
It is highly recommended to use MPU to prevent Speculative Prefetching of external memory,
|
||||
which may cause CPU read locks and even system errors.
|
||||
\param[in] mpu_init_struct: MPU initialization structure
|
||||
region_number: region number
|
||||
MPU_REGION_NUMBERn (n=0,..,15)
|
||||
region_base_address: region base address
|
||||
region_size: MPU_REGION_SIZE_32B, MPU_REGION_SIZE_64B, MPU_REGION_SIZE_128B, MPU_REGION_SIZE_256B, MPU_REGION_SIZE_512B,
|
||||
MPU_REGION_SIZE_1KB, MPU_REGION_SIZE_2KB, MPU_REGION_SIZE_4KB, MPU_REGION_SIZE_8KB, MPU_REGION_SIZE_16KB,
|
||||
MPU_REGION_SIZE_32KB, MPU_REGION_SIZE_64KB, MPU_REGION_SIZE_128KB, MPU_REGION_SIZE_256KB, MPU_REGION_SIZE_512KB,
|
||||
MPU_REGION_SIZE_1MB, MPU_REGION_SIZE_2MB, MPU_REGION_SIZE_4MB, MPU_REGION_SIZE_8MB, MPU_REGION_SIZE_16MB,
|
||||
MPU_REGION_SIZE_32MB, MPU_REGION_SIZE_64MB, MPU_REGION_SIZE_128MB, MPU_REGION_SIZE_256MB, MPU_REGION_SIZE_512MB,
|
||||
MPU_REGION_SIZE_1GB, MPU_REGION_SIZE_2GB, MPU_REGION_SIZE_4GB
|
||||
subregion_disable: MPU_SUBREGION_ENABLE, MPU_SUBREGION_DISABLE or 0x00~0xFF
|
||||
tex_type: MPU_TEX_TYPE0, MPU_TEX_TYPE1, MPU_TEX_TYPE2 or 0x00~0x07
|
||||
access_permission: MPU_AP_NO_ACCESS, MPU_AP_PRIV_RW, MPU_AP_PRIV_RW_UNPRIV_RO, MPU_AP_FULL_ACCESS, MPU_AP_PRIV_RO,
|
||||
MPU_AP_PRIV_UNPRIV_RO
|
||||
access_shareable: MPU_ACCESS_SHAREABLE, MPU_ACCESS_NON_SHAREABLE
|
||||
access_cacheable: MPU_ACCESS_CACHEABLE, MPU_ACCESS_NON_CACHEABLE
|
||||
access_bufferable: MPU_ACCESS_BUFFERABLE, MPU_ACCESS_NON_BUFFERABLE
|
||||
instruction_exec: MPU_INSTRUCTION_EXEC_PERMIT, MPU_INSTRUCTION_EXEC_NOT_PERMIT
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void mpu_region_config(mpu_region_init_struct *mpu_init_struct)
|
||||
{
|
||||
MPU->RNR = mpu_init_struct->region_number;
|
||||
MPU->RBAR = mpu_init_struct->region_base_address;
|
||||
MPU->RASR = ((uint32_t)mpu_init_struct->instruction_exec << MPU_RASR_XN_Pos) |
|
||||
((uint32_t)mpu_init_struct->access_permission << MPU_RASR_AP_Pos) |
|
||||
((uint32_t)mpu_init_struct->tex_type << MPU_RASR_TEX_Pos)|
|
||||
((uint32_t)mpu_init_struct->access_shareable << MPU_RASR_S_Pos) |
|
||||
((uint32_t)mpu_init_struct->access_cacheable << MPU_RASR_C_Pos) |
|
||||
((uint32_t)mpu_init_struct->access_bufferable << MPU_RASR_B_Pos) |
|
||||
((uint32_t)mpu_init_struct->subregion_disable << MPU_RASR_SRD_Pos)|
|
||||
((uint32_t)mpu_init_struct->region_size << MPU_RASR_SIZE_Pos);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the MPU region
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void mpu_region_enable(void)
|
||||
{
|
||||
MPU->RASR |= MPU_RASR_ENABLE_Msk;
|
||||
}
|
||||
|
||||
#endif /* __MPU_PRESENT */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,206 @@
|
||||
/*!
|
||||
\file gd32h7xx_ospim.c
|
||||
\brief OSPIM driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_ospim.h"
|
||||
#include "gd32h7xx_ospi.h"
|
||||
|
||||
/*!
|
||||
\brief reset the OSPIM peripheral
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ospim_deinit(void)
|
||||
{
|
||||
/* reset OSPIM */
|
||||
rcu_periph_reset_enable(RCU_OSPIMRST);
|
||||
rcu_periph_reset_disable(RCU_OSPIMRST);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configurate SCK for port
|
||||
\param[in] port: number of port
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg OSPIM_PORT0: port 0
|
||||
\arg OSPIM_PORT1: port 1
|
||||
\param[in] sckconfg: enable or disable SCK
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg OSPIM_PORT_SCK_DISABLE: disable SCK
|
||||
\arg OSPIM_PORT_SCK_ENABLE: enable SCK
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ospim_port_sck_config(uint8_t port, uint32_t sckconfg)
|
||||
{
|
||||
OSPIM_PCFG(port) &= (uint32_t)(~OSPIM_PCFG_SCKEN);
|
||||
OSPIM_PCFG(port) |= (uint32_t)sckconfg;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief select source of SCK for port
|
||||
\param[in] port: number of port
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg OSPIM_PORT0: port 0
|
||||
\arg OSPIM_PORT1: port 1
|
||||
\param[in] sck_source: source of SCK
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg OSPIM_SCK_SOURCE_OSPI0_SCK: the source of SCK is OSPI0_SCK
|
||||
\arg OSPIM_SCK_SOURCE_OSPI1_SCK: the source of SCK is OSPI1_SCK
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ospim_port_sck_source_select(uint8_t port, uint32_t sck_source)
|
||||
{
|
||||
OSPIM_PCFG(port) &= (uint32_t)(~OSPIM_PCFG_SRCPCK);
|
||||
OSPIM_PCFG(port) |= (uint32_t)sck_source;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configurate CSN for port
|
||||
\param[in] port: number of port
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg OSPIM_PORT0: port 0
|
||||
\arg OSPIM_PORT1: port 1
|
||||
\param[in] csnconfig: enable or disable CSN
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg OSPIM_PORT_CSN_DISABLE: disable CSN
|
||||
\arg OSPIM_PORT_CSN_ENABLE: enable CSN
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ospim_port_csn_config(uint8_t port, uint32_t csnconfig)
|
||||
{
|
||||
OSPIM_PCFG(port) &= (uint32_t)(~OSPIM_PCFG_NCSEN);
|
||||
OSPIM_PCFG(port) |= (uint32_t)csnconfig;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief select source of CSN for port
|
||||
\param[in] port: number of port
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg OSPIM_PORT0: port 0
|
||||
\arg OSPIM_PORT1: port 1
|
||||
\param[in] csn_source: source of CSN
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg OSPIM_CSN_SOURCE_OSPI0_CSN: the source of CSN is OSPI0_CSN
|
||||
\arg OSPIM_CSN_SOURCE_OSPI1_CSN: the source of CSN is OSPI1_CSN
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ospim_port_csn_source_select(uint8_t port, uint32_t csn_source)
|
||||
{
|
||||
OSPIM_PCFG(port) &= (uint32_t)(~OSPIM_PCFG_SRCPCS);
|
||||
OSPIM_PCFG(port) |= (uint32_t)csn_source;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configurate IO[3:0] for port
|
||||
\param[in] port: number of port
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg OSPIM_PORT0: port 0
|
||||
\arg OSPIM_PORT1: port 1
|
||||
\param[in] ioconfig: enable or disable IO[3:0]
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg OSPIM_IO_LOW_DISABLE: disable IO[3:0]
|
||||
\arg OSPIM_IO_LOW_ENABLE: enable IO[3:0]
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ospim_port_io3_0_config(uint8_t port, uint32_t ioconfig)
|
||||
{
|
||||
OSPIM_PCFG(port) &= (uint32_t)(~OSPIM_PCFG_POLEN);
|
||||
OSPIM_PCFG(port) |= (uint32_t)ioconfig;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief select source of IO[3:0] for port
|
||||
\param[in] port: number of port
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg OSPIM_PORT0: port 0
|
||||
\arg OSPIM_PORT1: port 1
|
||||
\param[in] csn_source: source of IO[3:0]
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg OSPIM_SRCPLIO_OSPI0_IO_LOW: select OSPI0_IO[3:0]
|
||||
\arg OSPIM_SRCPLIO_OSPI0_IO_HIGH: select OSPI0_IO[7:4]
|
||||
\arg OSPIM_SRCPLIO_OSPI1_IO_LOW: select OSPI1_IO[3:0]
|
||||
\arg OSPIM_SRCPLIO_OSPI1_IO_HIGH: select OSPI1_IO[7:4]
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ospim_port_io3_0_source_select(uint8_t port, uint32_t io_source)
|
||||
{
|
||||
OSPIM_PCFG(port) &= (uint32_t)(~OSPIM_PCFG_SRCPLIO);
|
||||
OSPIM_PCFG(port) |= (uint32_t)io_source;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configurate IO[7:4] for port
|
||||
\param[in] port: number of port
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg OSPIM_PORT0: port 0
|
||||
\arg OSPIM_PORT1: port 1
|
||||
\param[in] ioconfig: enable or disable IO[7:4]
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg OSPIM_IO_HIGH_DISABLE: disable IO[7:4]
|
||||
\arg OSPIM_IO_HIGH_ENABLE: enable IO[7:4]
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ospim_port_io7_4_config(uint8_t port, uint32_t ioconfig)
|
||||
{
|
||||
OSPIM_PCFG(port) &= (uint32_t)(~OSPIM_PCFG_POHEN);
|
||||
OSPIM_PCFG(port) |= (uint32_t)ioconfig;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief select source of IO[7:4] for port
|
||||
\param[in] port: number of port
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg OSPIM_PORT0: port 0
|
||||
\arg OSPIM_PORT1: port 1
|
||||
\param[in] csn_source: source of IO[7:4]
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg OSPIM_SRCPHIO_OSPI0_IO_LOW: select OSPI0_IO[3:0]
|
||||
\arg OSPIM_SRCPHIO_OSPI0_IO_HIGH: select OSPI0_IO[7:4]
|
||||
\arg OSPIM_SRCPHIO_OSPI1_IO_LOW: select OSPI1_IO[3:0]
|
||||
\arg OSPIM_SRCPHIO_OSPI1_IO_HIGH: select OSPI1_IO[7:4]
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ospim_port_io7_4_source_select(uint8_t port, uint32_t io_source)
|
||||
{
|
||||
OSPIM_PCFG(port) &= (uint32_t)(~OSPIM_PCFG_SRCPHIO);
|
||||
OSPIM_PCFG(port) |= (uint32_t)io_source;
|
||||
}
|
||||
@@ -0,0 +1,568 @@
|
||||
/*!
|
||||
\file gd32h7xx_pmu.c
|
||||
\brief PMU driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_pmu.h"
|
||||
|
||||
/* PMU register bit offset */
|
||||
#define PAR_TSW_IRCCNT_OFFSET ((uint32_t)0x00000010U) /*!< bit offset of TSW_HSICNT in PMU_PAR */
|
||||
|
||||
/*!
|
||||
\brief reset PMU register
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_deinit(void)
|
||||
{
|
||||
/* reset PMU */
|
||||
rcu_periph_reset_enable(RCU_PMURST);
|
||||
rcu_periph_reset_disable(RCU_PMURST);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief select low voltage detector threshold
|
||||
\param[in] lvdt_n:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg PMU_LVDT_0: voltage threshold is 2.1V
|
||||
\arg PMU_LVDT_1: voltage threshold is 2.3V
|
||||
\arg PMU_LVDT_2: voltage threshold is 2.4V
|
||||
\arg PMU_LVDT_3: voltage threshold is 2.6V
|
||||
\arg PMU_LVDT_4: voltage threshold is 2.7V
|
||||
\arg PMU_LVDT_5: voltage threshold is 2.9V
|
||||
\arg PMU_LVDT_6: voltage threshold is 3.0V
|
||||
\arg PMU_LVDT_7: input analog voltage on PB7 (compared with 0.8V)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_lvd_select(uint32_t lvdt_n)
|
||||
{
|
||||
uint32_t temp;
|
||||
temp = PMU_CTL0;
|
||||
/* clear LVDT bits */
|
||||
temp &= ~PMU_CTL0_LVDT;
|
||||
/* set LVDT bits according to lvdt_n */
|
||||
temp |= lvdt_n;
|
||||
PMU_CTL0 = temp;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable PMU lvd
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_lvd_enable(void)
|
||||
{
|
||||
PMU_CTL0 |= PMU_CTL0_LVDEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable PMU lvd
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_lvd_disable(void)
|
||||
{
|
||||
PMU_CTL0 &= ~PMU_CTL0_LVDEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief select analog voltage detector threshold
|
||||
\param[in] vavdt_n:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg PMU_VAVDVC_0: voltage threshold of analog voltage detector is 1.7V
|
||||
\arg PMU_VAVDVC_1: voltage threshold of analog voltage detector is 2.1V
|
||||
\arg PMU_VAVDVC_2: voltage threshold of analog voltage detector is 2.5V
|
||||
\arg PMU_VAVDVC_3: voltage threshold of analog voltage detector is 2.8V
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_vavd_select(uint32_t vavdt_n)
|
||||
{
|
||||
uint32_t temp;
|
||||
temp = PMU_CTL0;
|
||||
/* clear VAVDVC bits */
|
||||
temp &= ~PMU_CTL0_VAVDVC;
|
||||
/* set VAVDVC bits according to vavdt_n */
|
||||
temp |= vavdt_n;
|
||||
PMU_CTL0 = temp;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable PMU analog voltage detector
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_vavd_enable(void)
|
||||
{
|
||||
PMU_CTL0 |= PMU_CTL0_VAVDEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable PMU analog voltage detector
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_vavd_disable(void)
|
||||
{
|
||||
PMU_CTL0 &= ~PMU_CTL0_VAVDEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable PMU V0.9V core voltage detector
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_vovd_enable(void)
|
||||
{
|
||||
PMU_CTL0 |= PMU_CTL0_VOVDEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable PMU V0.9V core voltage detector
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_vovd_disable(void)
|
||||
{
|
||||
PMU_CTL0 &= ~PMU_CTL0_VOVDEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief control the V0.9V core voltage level
|
||||
\param[in] ldo_n:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg PMU_LDOVS_0: LDO output voltage 0.8V mode
|
||||
\arg PMU_LDOVS_1: LDO output voltage 0.85V mode
|
||||
\arg PMU_LDOVS_2: LDO output voltage 0.9V mode
|
||||
\arg PMU_LDOVS_3: LDO output voltage 0.95V mode
|
||||
\arg PMU_LDOVS_4: LDO output voltage 0.975V mode
|
||||
\arg PMU_LDOVS_5: LDO output voltage 1V mode
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_ldo_output_select(uint32_t ldo_n)
|
||||
{
|
||||
uint32_t temp;
|
||||
temp = PMU_CTL3;
|
||||
temp &= ~PMU_CTL3_LDOVS;
|
||||
temp |= ldo_n;
|
||||
PMU_CTL3 = temp;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Deep-sleep mode V0.9V core voltage select
|
||||
\param[in] sldo:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg PMU_SLDOVS_0: SLDOVS scale 0.6V
|
||||
\arg PMU_SLDOVS_1: SLDOVS scale 0.7V
|
||||
\arg PMU_SLDOVS_2: SLDOVS scale 0.8V
|
||||
\arg PMU_SLDOVS_3: SLDOVS scale 0.9V
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_sldo_output_select(uint32_t sldo_n)
|
||||
{
|
||||
uint32_t temp;
|
||||
temp = PMU_CTL0;
|
||||
temp &= ~PMU_CTL0_SLDOVS;
|
||||
temp |= sldo_n;
|
||||
PMU_CTL0 = temp;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief PMU VBAT battery charging resistor selection
|
||||
\param[in] resistor:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg PMU_VCRSEL_5K: 5kOhms resistor is selected for charing VBAT battery
|
||||
\arg PMU_VCRSEL_1P5K: 1.5kOhms resistor is selected for charing VBAT battery
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_vbat_charging_select(uint32_t resistor)
|
||||
{
|
||||
PMU_CTL2 &= ~PMU_CTL2_VCRSEL;
|
||||
PMU_CTL2 |= resistor;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable VBAT battery charging
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_vbat_charging_enable(void)
|
||||
{
|
||||
PMU_CTL2 |= PMU_CTL2_VCEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable VBAT battery charging
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_vbat_charging_disable(void)
|
||||
{
|
||||
PMU_CTL2 &= ~PMU_CTL2_VCEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable VBAT and temperature monitoring
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_vbat_temp_moniter_enable(void)
|
||||
{
|
||||
PMU_CTL1 |= PMU_CTL1_VBTMEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable VBAT and temperature monitoring
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_vbat_temp_moniter_disable(void)
|
||||
{
|
||||
PMU_CTL1 &= ~PMU_CTL1_VBTMEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable USB regulator
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_usb_regulator_enable(void)
|
||||
{
|
||||
PMU_CTL2 |= PMU_CTL2_USBSEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable USB regulator
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_usb_regulator_disable(void)
|
||||
{
|
||||
PMU_CTL2 &= ~PMU_CTL2_USBSEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable VDD33USB voltage level detector
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_usb_voltage_detector_enable(void)
|
||||
{
|
||||
PMU_CTL2 |= PMU_CTL2_VUSB33DEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable VDD33USB voltage level detector
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_usb_voltage_detector_disable(void)
|
||||
{
|
||||
PMU_CTL2 &= ~PMU_CTL2_VUSB33DEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief power supply configurations
|
||||
\param[in] smpsmode:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg PMU_LDO_SUPPLY: V0.9V domains are suppplied from the LDO
|
||||
\arg PMU_DIRECT_SMPS_SUPPLY: V0.9V domains are suppplied from the SMPS only
|
||||
\arg PMU_BYPASS: the SMPS disabled and the LDO Bypass. The V0.9V domains are supplied from an external source
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_smps_ldo_supply_config(uint32_t smpsmode)
|
||||
{
|
||||
uint32_t temp;
|
||||
temp = PMU_CTL2;
|
||||
temp &= ~(PMU_CTL2_DVSEN | PMU_CTL2_LDOEN | PMU_CTL2_BYPASS);
|
||||
temp |= smpsmode;
|
||||
PMU_CTL2 = temp;
|
||||
|
||||
while(0U == (PMU_CTL3 & PMU_CTL3_VOVRF)) {
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enter sleep mode
|
||||
\param[in] sleepmodecmd:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg WFI_CMD: use WFI command
|
||||
\arg WFE_CMD: use WFE command
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_to_sleepmode(uint8_t sleepmodecmd)
|
||||
{
|
||||
/* clear sleepdeep bit of Cortex-M7 system control register */
|
||||
SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
|
||||
|
||||
/* select WFI or WFE command to enter sleep mode */
|
||||
if(WFI_CMD == sleepmodecmd) {
|
||||
__WFI();
|
||||
} else {
|
||||
__WFE();
|
||||
__WFE();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enter deepsleep mode
|
||||
\param[in] deepsleepmodecmd:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg WFI_CMD: use WFI command
|
||||
\arg WFE_CMD: use WFE command
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_to_deepsleepmode(uint8_t deepsleepmodecmd)
|
||||
{
|
||||
/* clear standby mode */
|
||||
PMU_CTL0 &= ~((uint32_t)(PMU_CTL0_STBMOD));
|
||||
|
||||
/* set sleepdeep bit of Cortex-M7 system control register */
|
||||
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
|
||||
|
||||
/* select WFI or WFE command to enter deepsleep mode */
|
||||
if(WFI_CMD == deepsleepmodecmd) {
|
||||
__WFI();
|
||||
} else {
|
||||
__SEV();
|
||||
__WFE();
|
||||
__WFE();
|
||||
}
|
||||
/* reset sleepdeep bit of Cortex-M7 system control register */
|
||||
SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enter standby mode
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_to_standbymode(void)
|
||||
{
|
||||
/* set stbmod bit */
|
||||
PMU_CTL0 |= PMU_CTL0_STBMOD;
|
||||
|
||||
/* reset wakeup flag */
|
||||
PMU_CTL0 |= PMU_CTL0_WURST;
|
||||
|
||||
/* set sleepdeep bit of Cortex-M7 system control register */
|
||||
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
|
||||
|
||||
REG32( 0xE000E010U ) &= 0x00010004U;
|
||||
REG32( 0xE000E180U ) = 0xFFFFFFF3U;
|
||||
REG32( 0xE000E184U ) = 0xFFFFFDFFU;
|
||||
REG32( 0xE000E188U ) = 0xFFFFFFFFU;
|
||||
REG32( 0xE000E18CU ) = 0xFFFFFFFFU;
|
||||
REG32( 0xE000E190U ) = 0xFFFFFFFFU;
|
||||
REG32( 0xE000E194U ) = 0xFFFFFFFFU;
|
||||
|
||||
/* enter standby mode */
|
||||
__WFI();
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable PMU wakeup pin
|
||||
\param[in] wakeup_pin:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg PMU_WAKEUP_PIN0: WKUP Pin 0
|
||||
\arg PMU_WAKEUP_PIN1: WKUP Pin 1
|
||||
\arg PMU_WAKEUP_PIN3: WKUP Pin 3
|
||||
\arg PMU_WAKEUP_PIN5: WKUP Pin 5
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_wakeup_pin_enable(uint32_t wakeup_pin)
|
||||
{
|
||||
PMU_CS |= wakeup_pin;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable PMU wakeup pin
|
||||
\param[in] wakeup_pin:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg PMU_WAKEUP_PIN0: WKUP Pin 0
|
||||
\arg PMU_WAKEUP_PIN1: WKUP Pin 1
|
||||
\arg PMU_WAKEUP_PIN3: WKUP Pin 3
|
||||
\arg PMU_WAKEUP_PIN5: WKUP Pin 5
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_wakeup_pin_disable(uint32_t wakeup_pin)
|
||||
{
|
||||
PMU_CS &= ~(wakeup_pin);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable backup domain write
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_backup_write_enable(void)
|
||||
{
|
||||
PMU_CTL0 |= PMU_CTL0_BKPWEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable backup domain write
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_backup_write_disable(void)
|
||||
{
|
||||
PMU_CTL0 &= ~PMU_CTL0_BKPWEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable backup voltage stabilizer
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_backup_voltage_stabilizer_enable(void)
|
||||
{
|
||||
PMU_CTL1 |= PMU_CTL1_BKPVSEN;
|
||||
while(RESET == (PMU_CTL1 & PMU_CTL1_BKPVSRF)) {
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable backup voltage stabilizer
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_backup_voltage_stabilizer_disable(void)
|
||||
{
|
||||
PMU_CTL1 &= ~PMU_CTL1_BKPVSEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure IRC counter before enter Deep-sleep mode
|
||||
\param[in] wait_time: 0x0~0x1F, IRC counter before enter Deep-sleep mode
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_enter_deepsleep_wait_time_config(uint32_t wait_time)
|
||||
{
|
||||
uint32_t temp;
|
||||
temp = PMU_PAR;
|
||||
temp &= ~PMU_PAR_TSW_IRCCNT;
|
||||
temp |= (uint32_t)(wait_time << PAR_TSW_IRCCNT_OFFSET);
|
||||
PMU_PAR = temp;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure IRC counter before exit Deep-sleep mode
|
||||
\param[in] wait_time: 0x0~0xFFF, IRC counter before exit Deep-sleep mode
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_exit_deepsleep_wait_time_config(uint32_t wait_time)
|
||||
{
|
||||
uint32_t temp;
|
||||
temp = PMU_PAR;
|
||||
temp &= ~PMU_PAR_CNT;
|
||||
temp |= (uint32_t)(wait_time);
|
||||
PMU_PAR = temp;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get flag state
|
||||
\param[in] flag:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg PMU_FLAG_WAKEUP: wakeup flag
|
||||
\arg PMU_FLAG_STANDBY: standby flag
|
||||
\arg PMU_FLAG_LVDF: low voltage detector status flag
|
||||
\arg PMU_FLAG_VAVDF: VDDA analog voltage detector voltage output on VDDA flag
|
||||
\arg PMU_FLAG_VOVDF: peripheral voltage on VDDA detector flag
|
||||
\arg PMU_FLAG_VBATLF: VBAT level monitoring versus low threshold
|
||||
\arg PMU_FLAG_VBATHF: VBAT level monitoring versus high threshold
|
||||
\arg PMU_FLAG_TEMPLF: temperature level monitoring versus low threshold
|
||||
\arg PMU_FLAG_TEMPHF: temperature level monitoring versus high threshold
|
||||
\arg PMU_FLAG_DVSRF: step-down voltage stabilizer ready flag bit
|
||||
\arg PMU_FLAG_USB33RF: USB supply ready flag bit
|
||||
\arg PMU_FLAG_PWRRF: power Ready flag bit.
|
||||
\param[out] none
|
||||
\retval FlagStatus SET or RESET
|
||||
*/
|
||||
FlagStatus pmu_flag_get(uint32_t flag)
|
||||
{
|
||||
if(PMU_REG_VAL(flag) & BIT(PMU_BIT_POS(flag))) {
|
||||
return SET;
|
||||
} else {
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear flag bit
|
||||
\param[in] flag_reset:
|
||||
\arg PMU_FLAG_WAKEUP: wakeup flag
|
||||
\arg PMU_FLAG_STANDBY: standby flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_flag_clear(uint32_t flag_reset)
|
||||
{
|
||||
if(PMU_FLAG_WAKEUP == flag_reset) {
|
||||
PMU_CTL0 |= PMU_CTL0_WURST;
|
||||
} else {
|
||||
if(PMU_FLAG_STANDBY == flag_reset) {
|
||||
PMU_CTL0 |= PMU_CTL0_STBRST;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,395 @@
|
||||
/*!
|
||||
\file gd32h7xx_rameccmu.c
|
||||
\brief RAMECCMU driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_rameccmu.h"
|
||||
|
||||
#define RAMECCMU_REG_RESET_VALUE 0x00000000U
|
||||
|
||||
/*!
|
||||
\brief deinit RAMECCMU unit
|
||||
\param[in] rameccmu_periph: RAMECCMUx(x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rameccmu_deinit(uint32_t rameccmu_periph)
|
||||
{
|
||||
RAMECCMU_INT(rameccmu_periph) = RAMECCMU_REG_RESET_VALUE;
|
||||
if(RAMECCMU0 == rameccmu_periph){
|
||||
/* reset RAMECCMU0_MONITOR0 registers */
|
||||
RAMECCMU_MXCTL(RAMECCMU0_MONITOR0) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXSTAT(RAMECCMU0_MONITOR0) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXFADDR(RAMECCMU0_MONITOR0) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXFDL(RAMECCMU0_MONITOR0) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXFDH(RAMECCMU0_MONITOR0) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXFECODE(RAMECCMU0_MONITOR0) = RAMECCMU_REG_RESET_VALUE;
|
||||
/* reset RAMECCMU0_MONITOR1 registers */
|
||||
RAMECCMU_MXCTL(RAMECCMU0_MONITOR1) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXSTAT(RAMECCMU0_MONITOR1) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXFADDR(RAMECCMU0_MONITOR1) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXFDL(RAMECCMU0_MONITOR1) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXFDH(RAMECCMU0_MONITOR1) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXFECODE(RAMECCMU0_MONITOR1) = RAMECCMU_REG_RESET_VALUE;
|
||||
/* reset RAMECCMU0_MONITOR2 registers */
|
||||
RAMECCMU_MXCTL(RAMECCMU0_MONITOR2) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXSTAT(RAMECCMU0_MONITOR2) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXFADDR(RAMECCMU0_MONITOR2) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXFDL(RAMECCMU0_MONITOR2) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXFDH(RAMECCMU0_MONITOR2) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXFECODE(RAMECCMU0_MONITOR2) = RAMECCMU_REG_RESET_VALUE;
|
||||
/* reset RAMECCMU0_MONITOR3 registers */
|
||||
RAMECCMU_MXCTL(RAMECCMU0_MONITOR3) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXSTAT(RAMECCMU0_MONITOR3) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXFADDR(RAMECCMU0_MONITOR3) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXFDL(RAMECCMU0_MONITOR3) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXFDH(RAMECCMU0_MONITOR3) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXFECODE(RAMECCMU0_MONITOR3) = RAMECCMU_REG_RESET_VALUE;
|
||||
/* reset RAMECCMU0_MONITOR4 registers */
|
||||
RAMECCMU_MXCTL(RAMECCMU0_MONITOR4) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXSTAT(RAMECCMU0_MONITOR4) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXFADDR(RAMECCMU0_MONITOR4) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXFDL(RAMECCMU0_MONITOR4) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXFDH(RAMECCMU0_MONITOR4) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXFECODE(RAMECCMU0_MONITOR4) = RAMECCMU_REG_RESET_VALUE;
|
||||
}else{
|
||||
/* reset RAMECCMU1_MONITOR0 registers */
|
||||
RAMECCMU_MXCTL(RAMECCMU1_MONITOR0) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXSTAT(RAMECCMU1_MONITOR0) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXFADDR(RAMECCMU1_MONITOR0) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXFDL(RAMECCMU1_MONITOR0) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXFDH(RAMECCMU1_MONITOR0) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXFECODE(RAMECCMU1_MONITOR0) = RAMECCMU_REG_RESET_VALUE;
|
||||
/* reset RAMECCMU1_MONITOR1 registers */
|
||||
RAMECCMU_MXCTL(RAMECCMU1_MONITOR1) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXSTAT(RAMECCMU1_MONITOR1) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXFADDR(RAMECCMU1_MONITOR1) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXFDL(RAMECCMU1_MONITOR1) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXFDH(RAMECCMU1_MONITOR1) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXFECODE(RAMECCMU1_MONITOR1) = RAMECCMU_REG_RESET_VALUE;
|
||||
/* reset RAMECCMU1_MONITOR2 registers */
|
||||
RAMECCMU_MXCTL(RAMECCMU1_MONITOR2) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXSTAT(RAMECCMU1_MONITOR2) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXFADDR(RAMECCMU1_MONITOR2) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXFDL(RAMECCMU1_MONITOR2) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXFDH(RAMECCMU1_MONITOR2) = RAMECCMU_REG_RESET_VALUE;
|
||||
RAMECCMU_MXFECODE(RAMECCMU1_MONITOR2) = RAMECCMU_REG_RESET_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get RAMECCMU monitor ECC failing address
|
||||
\param[in] rameccmu_monitor: RAMECCMU monitor
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg RAMECCMU0_MONITOR0: RAMECCMU0 monitor 0
|
||||
\arg RAMECCMU0_MONITOR1: RAMECCMU0 monitor 1
|
||||
\arg RAMECCMU0_MONITOR2: RAMECCMU0 monitor 2
|
||||
\arg RAMECCMU0_MONITOR3: RAMECCMU0 monitor 3
|
||||
\arg RAMECCMU0_MONITOR4: RAMECCMU0 monitor 4
|
||||
\arg RAMECCMU1_MONITOR0: RAMECCMU1 monitor 0
|
||||
\arg RAMECCMU1_MONITOR1: RAMECCMU1 monitor 1
|
||||
\arg RAMECCMU1_MONITOR2: RAMECCMU1 monitor 2
|
||||
\param[out] none
|
||||
\retval ECC error failing address
|
||||
*/
|
||||
uint32_t rameccmu_monitor_failing_address_get(rameccmu_monitor_enum rameccmu_monitor)
|
||||
{
|
||||
return RAMECCMU_MXFADDR(rameccmu_monitor);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get RAMECCMU monitor ECC failing data low 32 bits
|
||||
\param[in] rameccmu_monitor: RAMECCMU monitor
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg RAMECCMU0_MONITOR0: RAMECCMU0 monitor 0
|
||||
\arg RAMECCMU0_MONITOR1: RAMECCMU0 monitor 1
|
||||
\arg RAMECCMU0_MONITOR2: RAMECCMU0 monitor 2
|
||||
\arg RAMECCMU0_MONITOR3: RAMECCMU0 monitor 3
|
||||
\arg RAMECCMU0_MONITOR4: RAMECCMU0 monitor 4
|
||||
\arg RAMECCMU1_MONITOR0: RAMECCMU1 monitor 0
|
||||
\arg RAMECCMU1_MONITOR1: RAMECCMU1 monitor 1
|
||||
\arg RAMECCMU1_MONITOR2: RAMECCMU1 monitor 2
|
||||
\param[out] none
|
||||
\retval ECC failing data low 32 bits
|
||||
*/
|
||||
uint32_t rameccmu_monitor_failing_data_low_bits_get(rameccmu_monitor_enum rameccmu_monitor)
|
||||
{
|
||||
return RAMECCMU_MXFDL(rameccmu_monitor);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get RAMECCMU monitor ECC failing data high 32 bits
|
||||
\param[in] rameccmu_monitor: RAMECCMU monitor
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg RAMECCMU0_MONITOR0: RAMECCMU0 monitor 0
|
||||
\arg RAMECCMU0_MONITOR1: RAMECCMU0 monitor 1
|
||||
\arg RAMECCMU0_MONITOR2: RAMECCMU0 monitor 2
|
||||
\arg RAMECCMU0_MONITOR3: RAMECCMU0 monitor 3
|
||||
\arg RAMECCMU0_MONITOR4: RAMECCMU0 monitor 4
|
||||
\arg RAMECCMU1_MONITOR0: RAMECCMU1 monitor 0
|
||||
\arg RAMECCMU1_MONITOR1: RAMECCMU1 monitor 1
|
||||
\arg RAMECCMU1_MONITOR2: RAMECCMU1 monitor 2
|
||||
\param[out] none
|
||||
\retval ECC failing data high 32 bits
|
||||
*/
|
||||
uint32_t rameccmu_monitor_failing_data_high_bits_get(rameccmu_monitor_enum rameccmu_monitor)
|
||||
{
|
||||
return RAMECCMU_MXFDH(rameccmu_monitor);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get RAMECCMU monitor failing ECC error code
|
||||
\param[in] rameccmu_monitor: RAMECCMU monitor
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg RAMECCMU0_MONITOR0: RAMECCMU0 monitor 0
|
||||
\arg RAMECCMU0_MONITOR1: RAMECCMU0 monitor 1
|
||||
\arg RAMECCMU0_MONITOR2: RAMECCMU0 monitor 2
|
||||
\arg RAMECCMU0_MONITOR3: RAMECCMU0 monitor 3
|
||||
\arg RAMECCMU0_MONITOR4: RAMECCMU0 monitor 4
|
||||
\arg RAMECCMU1_MONITOR0: RAMECCMU1 monitor 0
|
||||
\arg RAMECCMU1_MONITOR1: RAMECCMU1 monitor 1
|
||||
\arg RAMECCMU1_MONITOR2: RAMECCMU1 monitor 2
|
||||
\param[out] none
|
||||
\retval ECC failing error code
|
||||
*/
|
||||
uint32_t rameccmu_monitor_failing_ecc_error_code_get(rameccmu_monitor_enum rameccmu_monitor)
|
||||
{
|
||||
return RAMECCMU_MXFECODE(rameccmu_monitor);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable RAMECCMU global ECC interruput
|
||||
\param[in] rameccmu_periph: RAMECCMU
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg RAMECCMU0: RAMECCMU for region 0
|
||||
\arg RAMECCMU1: RAMECCMU for region 1
|
||||
\param[in] interrupt: global ECC interruput
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg RAMECCMU_INT_ECC_GLOBAL_ERROR: ECC global error interrupt
|
||||
\arg RAMECCMU_INT_ECC_SINGLE_ERROR: ECC single error interrupt
|
||||
\arg RAMECCMU_INT_ECC_DOUBLE_ERROR: ECC double error interrupt
|
||||
\arg RAMECCMU_INT_ECC_DOUBLE_ERROR_BYTE_WRITE: ECC double error on byte write interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rameccmu_global_interrupt_enable(uint32_t rameccmu_periph, uint32_t interrupt)
|
||||
{
|
||||
RAMECCMU_INT(rameccmu_periph) |= interrupt;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable RAMECCMU global ECC interruput
|
||||
\param[in] rameccmu_periph: RAMECCMU
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg RAMECCMU0: RAMECCMU for region 0
|
||||
\arg RAMECCMU1: RAMECCMU for region 1
|
||||
\param[in] interrupt: global ECC interruput
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg RAMECCMU_INT_ECC_GLOBAL_ERROR: ECC global error interrupt
|
||||
\arg RAMECCMU_INT_ECC_SINGLE_ERROR: ECC single error interrupt
|
||||
\arg RAMECCMU_INT_ECC_DOUBLE_ERROR: ECC double error interrupt
|
||||
\arg RAMECCMU_INT_ECC_DOUBLE_ERROR_BYTE_WRITE: ECC double error on byte write interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rameccmu_global_interrupt_disable(uint32_t rameccmu_periph, uint32_t interrupt)
|
||||
{
|
||||
RAMECCMU_INT(rameccmu_periph) &= (uint32_t)(~interrupt);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable RAMECCMU monitor ECC error interruput
|
||||
\param[in] rameccmu_monitor: RAMECCMU monitor
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg RAMECCMU0_MONITOR0: RAMECCMU0 monitor 0
|
||||
\arg RAMECCMU0_MONITOR1: RAMECCMU0 monitor 1
|
||||
\arg RAMECCMU0_MONITOR2: RAMECCMU0 monitor 2
|
||||
\arg RAMECCMU0_MONITOR3: RAMECCMU0 monitor 3
|
||||
\arg RAMECCMU0_MONITOR4: RAMECCMU0 monitor 4
|
||||
\arg RAMECCMU1_MONITOR0: RAMECCMU1 monitor 0
|
||||
\arg RAMECCMU1_MONITOR1: RAMECCMU1 monitor 1
|
||||
\arg RAMECCMU1_MONITOR2: RAMECCMU1 monitor 2
|
||||
\param[in] monitor_interrupt: RAMECCMU monitor interruput
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg RAMECCMU_INT_ECC_SINGLE_ERROR: ECC single error interrupt
|
||||
\arg RAMECCMU_INT_ECC_DOUBLE_ERROR: ECC double error interrupt
|
||||
\arg RAMECCMU_INT_ECC_DOUBLE_ERROR_BYTE_WRITE: ECC double error on byte write interrupt
|
||||
\arg RAMECCMU_INT_ECC_ERROR_LATCHING: ECC error latching
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rameccmu_monitor_interrupt_enable(rameccmu_monitor_enum rameccmu_monitor, uint32_t monitor_interrupt)
|
||||
{
|
||||
RAMECCMU_MXCTL(rameccmu_monitor) |= (uint32_t)monitor_interrupt << 1U;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable RAMECCMU monitor ECC error interruput
|
||||
\param[in] rameccmu_monitor: RAMECCMU monitor
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg RAMECCMU0_MONITOR0: RAMECCMU0 monitor 0
|
||||
\arg RAMECCMU0_MONITOR1: RAMECCMU0 monitor 1
|
||||
\arg RAMECCMU0_MONITOR2: RAMECCMU0 monitor 2
|
||||
\arg RAMECCMU0_MONITOR3: RAMECCMU0 monitor 3
|
||||
\arg RAMECCMU0_MONITOR4: RAMECCMU0 monitor 4
|
||||
\arg RAMECCMU1_MONITOR0: RAMECCMU1 monitor 0
|
||||
\arg RAMECCMU1_MONITOR1: RAMECCMU1 monitor 1
|
||||
\arg RAMECCMU1_MONITOR2: RAMECCMU1 monitor 2
|
||||
\param[in] monitor_interrupt: RAMECCMU monitor interruput
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg RAMECCMU_INT_ECC_SINGLE_ERROR: ECC single error interrupt
|
||||
\arg RAMECCMU_INT_ECC_DOUBLE_ERROR: ECC double error interrupt
|
||||
\arg RAMECCMU_INT_ECC_DOUBLE_ERROR_BYTE_WRITE: ECC double error on byte write interrupt
|
||||
\arg RAMECCMU_INT_ECC_ERROR_LATCHING: ECC error latching
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rameccmu_monitor_interrupt_disable(rameccmu_monitor_enum rameccmu_monitor, uint32_t monitor_interrupt)
|
||||
{
|
||||
RAMECCMU_MXCTL(rameccmu_monitor) &= (uint32_t)~((uint32_t)monitor_interrupt << 1U);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get RAMECCMU monitor ECC error flag
|
||||
\param[in] rameccmu_monitor: RAMECCMU monitor
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg RAMECCMU0_MONITOR0: RAMECCMU0 monitor 0
|
||||
\arg RAMECCMU0_MONITOR1: RAMECCMU0 monitor 1
|
||||
\arg RAMECCMU0_MONITOR2: RAMECCMU0 monitor 2
|
||||
\arg RAMECCMU0_MONITOR3: RAMECCMU0 monitor 3
|
||||
\arg RAMECCMU0_MONITOR4: RAMECCMU0 monitor 4
|
||||
\arg RAMECCMU1_MONITOR0: RAMECCMU1 monitor 0
|
||||
\arg RAMECCMU1_MONITOR1: RAMECCMU1 monitor 1
|
||||
\arg RAMECCMU1_MONITOR2: RAMECCMU1 monitor 2
|
||||
\param[in] flag: RAMECCMU monitor flag
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg RAMECCMU_FLAG_ECC_SINGLE_ERROR: ECC single error detected and corrected flag
|
||||
\arg RAMECCMU_FLAG_ECC_DOUBLE_ERROR: ECC double error detected flag
|
||||
\arg RAMECCMU_FLAG_ECC_DOUBLE_ERROR_BYTE_WRITE: ECC double error on byte write detected flag
|
||||
\param[out] none
|
||||
\retval RESET or SET
|
||||
*/
|
||||
FlagStatus rameccmu_monitor_flag_get(rameccmu_monitor_enum rameccmu_monitor, uint32_t flag)
|
||||
{
|
||||
if(RESET != ((RAMECCMU_MXSTAT(rameccmu_monitor)) & flag)){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear RAMECCMU monitor ECC error flag
|
||||
\param[in] rameccmu_monitor: RAMECCMU monitor
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg RAMECCMU0_MONITOR0: RAMECCMU0 monitor 0
|
||||
\arg RAMECCMU0_MONITOR1: RAMECCMU0 monitor 1
|
||||
\arg RAMECCMU0_MONITOR2: RAMECCMU0 monitor 2
|
||||
\arg RAMECCMU0_MONITOR3: RAMECCMU0 monitor 3
|
||||
\arg RAMECCMU0_MONITOR4: RAMECCMU0 monitor 4
|
||||
\arg RAMECCMU1_MONITOR0: RAMECCMU1 monitor 0
|
||||
\arg RAMECCMU1_MONITOR1: RAMECCMU1 monitor 1
|
||||
\arg RAMECCMU1_MONITOR2: RAMECCMU1 monitor 2
|
||||
\param[in] flag: RAMECCMU monitor flag
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg RAMECCMU_FLAG_ECC_SINGLE_ERROR: ECC single error detected and corrected flag
|
||||
\arg RAMECCMU_FLAG_ECC_DOUBLE_ERROR: ECC double error detected flag
|
||||
\arg RAMECCMU_FLAG_ECC_DOUBLE_ERROR_BYTE_WRITE: ECC double error on byte write detected flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rameccmu_monitor_flag_clear(rameccmu_monitor_enum rameccmu_monitor, uint32_t flag)
|
||||
{
|
||||
RAMECCMU_MXSTAT(rameccmu_monitor) &= (uint32_t)(~flag);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get RAMECCMU monitor ECC interrupt error flag
|
||||
\param[in] rameccmu_monitor: RAMECCMU monitor
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg RAMECCMU0_MONITOR0: RAMECCMU0 monitor 0
|
||||
\arg RAMECCMU0_MONITOR1: RAMECCMU0 monitor 1
|
||||
\arg RAMECCMU0_MONITOR2: RAMECCMU0 monitor 2
|
||||
\arg RAMECCMU0_MONITOR3: RAMECCMU0 monitor 3
|
||||
\arg RAMECCMU0_MONITOR4: RAMECCMU0 monitor 4
|
||||
\arg RAMECCMU1_MONITOR0: RAMECCMU1 monitor 0
|
||||
\arg RAMECCMU1_MONITOR1: RAMECCMU1 monitor 1
|
||||
\arg RAMECCMU1_MONITOR2: RAMECCMU1 monitor 2
|
||||
\param[in] int_flag: RAMECCMU monitor flag
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg RAMECCMU_INT_FLAG_ECC_SINGLE_ERROR: ECC single error detected and corrected flag
|
||||
\arg RAMECCMU_INT_FLAG_ECC_DOUBLE_ERROR: ECC double error detected flag
|
||||
\arg RAMECCMU_INT_FLAG_ECC_DOUBLE_ERROR_BYTE_WRITE: ECC double error on byte write detected flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
FlagStatus rameccmu_monitor_interrupt_flag_get(rameccmu_monitor_enum rameccmu_monitor, uint32_t int_flag)
|
||||
{
|
||||
uint32_t ret1 = RESET;
|
||||
uint32_t ret2 = RESET;
|
||||
|
||||
/* get the status of interrupt enable bit */
|
||||
ret1 = RAMECCMU_MXCTL(rameccmu_monitor) & (uint32_t)(int_flag << 2U);
|
||||
/* get the status of interrupt flag */
|
||||
ret2 = RAMECCMU_MXSTAT(rameccmu_monitor) & int_flag;
|
||||
|
||||
if(ret1 && ret2) {
|
||||
return SET;
|
||||
} else {
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear RAMECCMU monitor interrupt ECC error flag
|
||||
\param[in] rameccmu_monitor: RAMECCMU monitor
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg RAMECCMU0_MONITOR0: RAMECCMU0 monitor 0
|
||||
\arg RAMECCMU0_MONITOR1: RAMECCMU0 monitor 1
|
||||
\arg RAMECCMU0_MONITOR2: RAMECCMU0 monitor 2
|
||||
\arg RAMECCMU0_MONITOR3: RAMECCMU0 monitor 3
|
||||
\arg RAMECCMU0_MONITOR4: RAMECCMU0 monitor 4
|
||||
\arg RAMECCMU1_MONITOR0: RAMECCMU1 monitor 0
|
||||
\arg RAMECCMU1_MONITOR1: RAMECCMU1 monitor 1
|
||||
\arg RAMECCMU1_MONITOR2: RAMECCMU1 monitor 2
|
||||
\param[in] int_flag: RAMECCMU monitor flag
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg RAMECCMU_INT_FLAG_ECC_SINGLE_ERROR: ECC single error detected and corrected flag
|
||||
\arg RAMECCMU_INT_FLAG_ECC_DOUBLE_ERROR: ECC double error detected flag
|
||||
\arg RAMECCMU_INT_FLAG_ECC_DOUBLE_ERROR_BYTE_WRITE: ECC double error on byte write detected flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rameccmu_monitor_interrupt_flag_clear(rameccmu_monitor_enum rameccmu_monitor, uint32_t int_flag)
|
||||
{
|
||||
RAMECCMU_MXSTAT(rameccmu_monitor) &= (uint32_t)(~int_flag);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,582 @@
|
||||
/*!
|
||||
\file gd32h7xx_rspdif.c
|
||||
\brief RSPDIF driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_rspdif.h"
|
||||
|
||||
#define RSPDIF_INIT_MASK (uint32_t)0xFFC88004U /*!< RSPDIF parameter initialization mask */
|
||||
|
||||
#define RSPDIF_CKCNT5_OFFSET (uint32_t)16U /*!< RSPDIF the number of consecutive time clock cycles offset */
|
||||
|
||||
#define RSPDIF_DATA_F0_PREF_OFFSET (uint32_t)28U /*!< RSPDIF data format 0 preamble type offset */
|
||||
#define RSPDIF_DATA_F0_C_OFFSET (uint32_t)27U /*!< RSPDIF data format 0 channel status offset */
|
||||
#define RSPDIF_DATA_F0_U_OFFSET (uint32_t)26U /*!< RSPDIF data format 0 user bit offset */
|
||||
#define RSPDIF_DATA_F0_V_OFFSET (uint32_t)25U /*!< RSPDIF data format 0 validity bit offset */
|
||||
#define RSPDIF_DATA_F0_P_OFFSET (uint32_t)24U /*!< RSPDIF data format 0 parity error bit offset */
|
||||
|
||||
#define RSPDIF_DATA_F1_PREF_OFFSET (uint32_t)4U /*!< RSPDIF data format 1 preamble type offset */
|
||||
#define RSPDIF_DATA_F1_C_OFFSET (uint32_t)3U /*!< RSPDIF data format 1 channel status offset */
|
||||
#define RSPDIF_DATA_F1_U_OFFSET (uint32_t)2U /*!< RSPDIF data format 1 user bit offset */
|
||||
#define RSPDIF_DATA_F1_V_OFFSET (uint32_t)1U /*!< RSPDIF data format 1 validity bit offset */
|
||||
#define RSPDIF_DATA_F1_DATA_OFFSET (uint32_t)8U /*!< RSPDIF data format 1 data offset */
|
||||
|
||||
/*!
|
||||
\brief reset the RSPDIF
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rspdif_deinit(void)
|
||||
{
|
||||
rcu_periph_reset_enable(RCU_RSPDIFRST);
|
||||
rcu_periph_reset_disable(RCU_RSPDIFRST);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the parameters of RSPDIF structure with the default values
|
||||
\param[in] none
|
||||
\param[out] rspdif_parameter_struct: the initialized structure rspdif_parameter_struct pointer
|
||||
\retval none
|
||||
*/
|
||||
void rspdif_struct_para_init(rspdif_parameter_struct *rspdif_struct)
|
||||
{
|
||||
/* configure the RSPDIF structure with the default values */
|
||||
rspdif_struct->input_sel = RSPDIF_INPUT_IN0;
|
||||
rspdif_struct->max_retrie = RSPDIF_MAXRETRIES_15;
|
||||
rspdif_struct->wait_activity = RSPDIF_WAIT_FOR_ACTIVITY_ON;
|
||||
rspdif_struct->channel_sel = RSPDIF_CHANNEL_A;
|
||||
rspdif_struct->sample_format = RSPDIF_DATAFORMAT_MSB;
|
||||
rspdif_struct->sound_mode = RSPDIF_STEREOMODE_ENABLE;
|
||||
rspdif_struct->pre_type = RSPDIF_PREAMBLE_TYPE_MASK_OFF;
|
||||
rspdif_struct->channel_status_bit = RSPDIF_CHANNEL_STATUS_MASK_OFF;
|
||||
rspdif_struct->validity_bit = RSPDIF_VALIDITY_MASK_OFF;
|
||||
rspdif_struct->parity_error_bit = RSPDIF_PERROR_MASK_OFF;
|
||||
rspdif_struct->symbol_clk = RSPDIF_SYMBOL_CLK_OFF;
|
||||
rspdif_struct->bak_symbol_clk = RSPDIF_BACKUP_SYMBOL_CLK_OFF;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the RSPDIF parameters
|
||||
\param[in] rspdif_struct : RSPDIF parameter initialization stucture and the member values are shown as below:
|
||||
input_sel : RSPDIF_INPUT_INx (x = 0 ~ 3)
|
||||
max_retrie : RSPDIF_MAXRETRIES_NONE, RSPDIF_MAXRETRIES_3, RSPDIF_MAXRETRIES_15, RSPDIF_MAXRETRIES_63
|
||||
wait_activity : RSPDIF_WAIT_FOR_ACTIVITY_OFF, RSPDIF_WAIT_FOR_ACTIVITY_ON
|
||||
channel_sel : RSPDIF_CHANNEL_A, RSPDIF_CHANNEL_B
|
||||
sample_format : RSPDIF_DATAFORMAT_LSB, RSPDIF_DATAFORMAT_MSB, RSPDIF_DATAFORMAT_32BITS
|
||||
sound_mode : RSPDIF_STEREOMODE_DISABLE, RSPDIF_STEREOMODE_ENABLE
|
||||
pre_type : RSPDIF_PREAMBLE_TYPE_MASK_OFF, RSPDIF_PREAMBLE_TYPE_MASK_ON
|
||||
channel_status_bit : RSPDIF_CHANNEL_STATUS_MASK_OFF, RSPDIF_CHANNEL_STATUS_MASK_ON
|
||||
validity_bit : RSPDIF_VALIDITY_MASK_OFF, RSPDIF_VALIDITY_MASK_ON
|
||||
parity_error_bit : RSPDIF_PERROR_MASK_OFF, RSPDIF_PERROR_MASK_ON
|
||||
symbol_clk : RSPDIF_BACKUP_SYMBOL_CLK_OFF, RSPDIF_BACKUP_SYMBOL_CLK_ON
|
||||
bak_symbol_clk : RSPDIF_SYMBOL_CLK_OFF, RSPDIF_SYMBOL_CLK_ON
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rspdif_init(rspdif_parameter_struct *rspdif_struct)
|
||||
{
|
||||
uint32_t reg = 0U;
|
||||
|
||||
reg = RSPDIF_CTL;
|
||||
reg &= RSPDIF_INIT_MASK;
|
||||
|
||||
/* select the RSPDIF input */
|
||||
reg |= rspdif_struct->input_sel;
|
||||
/* configure the RSPDIF maximum allowed re-tries during synchronization phase */
|
||||
reg |= rspdif_struct->max_retrie;
|
||||
/* configure the RSPDIF wait for activity on the selected input */
|
||||
reg |= rspdif_struct->wait_activity;
|
||||
/* select the channel status from channel A or B */
|
||||
reg |= rspdif_struct->channel_sel;
|
||||
/* configure the RSPDIF data samples format */
|
||||
reg |= rspdif_struct->sample_format;
|
||||
/* select stereo or mono mode */
|
||||
reg |= rspdif_struct->sound_mode;
|
||||
/* select whether the preamble type value into the RSPDIF_DATA */
|
||||
reg |= rspdif_struct->pre_type;
|
||||
/* select whether the channel status and user bits are copied or not into the received frame */
|
||||
reg |= rspdif_struct->channel_status_bit;
|
||||
/* select whether the validity bit is copied or not into the received frame */
|
||||
reg |= rspdif_struct->validity_bit;
|
||||
/* select whether the parity error bit is copied or not into the received frame */
|
||||
reg |= rspdif_struct->parity_error_bit;
|
||||
/* configure the RSPDIF symbol clock generation */
|
||||
reg |= rspdif_struct->symbol_clk;
|
||||
/* configure the RSPDIF backup symbol clock generation */
|
||||
reg |= rspdif_struct->bak_symbol_clk;
|
||||
|
||||
/* write to SPDIFRX_CTL register */
|
||||
RSPDIF_CTL = (uint32_t)reg;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief specifies the RSPDIF peripheral state
|
||||
\param[in] rspdif_state :
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg RSPDIF_STATE_SYNC: enable RSPDIF synchronization only
|
||||
\arg RSPDIF_STATE_RCV : enable RSPDIF receiver
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rspdif_enable(uint32_t mode)
|
||||
{
|
||||
uint32_t reg = 0U;
|
||||
|
||||
reg = RSPDIF_CTL;
|
||||
|
||||
/* clear RSPDIF state */
|
||||
reg &= ~(uint32_t)RSPDIF_CTL_RXCFG;
|
||||
reg |= (uint32_t)mode;
|
||||
|
||||
/* enable RSPDIF */
|
||||
RSPDIF_CTL = (uint32_t)reg;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable RSPDIF
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rspdif_disable(void)
|
||||
{
|
||||
/* clear RSPDIF state */
|
||||
RSPDIF_CTL &= ~(uint32_t)RSPDIF_CTL_RXCFG;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable RSPDIF symbol clock
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rspdif_symbol_clock_enable(void)
|
||||
{
|
||||
RSPDIF_CTL |= (uint32_t)RSPDIF_CTL_SCKEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable RSPDIF symbol clock
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rspdif_symbol_clock_disable(void)
|
||||
{
|
||||
RSPDIF_CTL &= ~(uint32_t)RSPDIF_CTL_SCKEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable RSPDIF backup symbol clock
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rspdif_backup_symbol_clock_enable(void)
|
||||
{
|
||||
RSPDIF_CTL |= (uint32_t)RSPDIF_CTL_BKSCKEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable RSPDIF backup symbol clock
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rspdif_backup_symbol_clock_disable(void)
|
||||
{
|
||||
RSPDIF_CTL &= ~(uint32_t)RSPDIF_CTL_BKSCKEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the RSPDIF receiver DMA
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rspdif_dma_enable(void)
|
||||
{
|
||||
RSPDIF_CTL |= RSPDIF_CTL_DMAREN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the RSPDIF receiver DMA
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rspdif_dma_disable(void)
|
||||
{
|
||||
RSPDIF_CTL &= ~RSPDIF_CTL_DMAREN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the RSPDIF control buffer DMA
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rspdif_control_buffer_dma_enable(void)
|
||||
{
|
||||
RSPDIF_CTL |= RSPDIF_CTL_DMACBEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the RSPDIF control buffer DMA
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rspdif_control_buffer_dma_disable(void)
|
||||
{
|
||||
RSPDIF_CTL &= ~RSPDIF_CTL_DMACBEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief RSPDIF read data
|
||||
\param[in] none
|
||||
\param[out] data_struct: RSPDIF data stucture and the member values are shown as below:
|
||||
format : RSPDIF_DATAFORMAT_LSB, RSPDIF_DATAFORMAT_MSB,RSPDIF_DATAFORMAT_32BITS
|
||||
preamble : RSPDIF_PREAMBLE_NONE,RSPDIF_PREAMBLE_B,RSPDIF_PREAMBLE_M,RSPDIF_PREAMBLE_W
|
||||
channel_status : 0 or 1
|
||||
user_bit : 0 or 1
|
||||
validity : 0 or 1
|
||||
parity_err : 0 or 1
|
||||
data0 : 0 ~ 65535
|
||||
data1 : 0 ~ 65535
|
||||
\retval none
|
||||
*/
|
||||
void rspdif_data_read(rspdif_data_struct *data_struct)
|
||||
{
|
||||
/* get data format */
|
||||
data_struct->format = RSPDIF_CTL & RSPDIF_CTL_RXDF;
|
||||
|
||||
switch(data_struct->format) {
|
||||
/* data format 0 */
|
||||
case RSPDIF_DATAFORMAT_LSB:
|
||||
/* the preamble type */
|
||||
data_struct->preamble = (uint32_t)((RSPDIF_DATA & RSPDIF_DATA_F0_PREF) >> RSPDIF_DATA_F0_PREF_OFFSET);
|
||||
/* channel status bit */
|
||||
data_struct->channel_status = (uint32_t)((RSPDIF_DATA & RSPDIF_DATA_F0_C) >> RSPDIF_DATA_F0_C_OFFSET);
|
||||
/* user bit */
|
||||
data_struct->user_bit = (uint32_t)((RSPDIF_DATA & RSPDIF_DATA_F0_U) >> RSPDIF_DATA_F0_U_OFFSET);
|
||||
/* validity bit */
|
||||
data_struct->validity = (uint32_t)((RSPDIF_DATA & RSPDIF_DATA_F0_V) >> RSPDIF_DATA_F0_V_OFFSET);
|
||||
/* parity error bit */
|
||||
data_struct->parity_err = (uint32_t)((RSPDIF_DATA & RSPDIF_DATA_F0_P) >> RSPDIF_DATA_F0_P_OFFSET);
|
||||
/* data value 0 */
|
||||
data_struct->data0 = (uint32_t)(RSPDIF_DATA & RSPDIF_DATA_F0_DATA0);
|
||||
/* data value 1 */
|
||||
data_struct->data1 = 0U;
|
||||
break;
|
||||
/* data format 1 */
|
||||
case RSPDIF_DATAFORMAT_MSB:
|
||||
/* the preamble type */
|
||||
data_struct->preamble = (uint32_t)((RSPDIF_DATA & RSPDIF_DATA_F1_PREF) >> RSPDIF_DATA_F1_PREF_OFFSET);
|
||||
/* channel status bit */
|
||||
data_struct->channel_status = (uint32_t)((RSPDIF_DATA & RSPDIF_DATA_F1_C) >> RSPDIF_DATA_F1_C_OFFSET);
|
||||
/* user bit */
|
||||
data_struct->user_bit = (uint32_t)((RSPDIF_DATA & RSPDIF_DATA_F1_U) >> RSPDIF_DATA_F1_U_OFFSET);
|
||||
/* validity bit */
|
||||
data_struct->validity = (uint32_t)((RSPDIF_DATA & RSPDIF_DATA_F1_V) >> RSPDIF_DATA_F1_V_OFFSET);
|
||||
/* parity error bit */
|
||||
data_struct->parity_err = (uint32_t)(RSPDIF_DATA & RSPDIF_DATA_F1_P);
|
||||
/* data value 0 */
|
||||
data_struct->data0 = (uint32_t)((RSPDIF_DATA & RSPDIF_DATA_F1_DATA0) >> RSPDIF_DATA_F1_DATA_OFFSET);
|
||||
/* data value 1 */
|
||||
data_struct->data1 = 0U;
|
||||
break;
|
||||
/* data format 2 */
|
||||
case RSPDIF_DATAFORMAT_32BITS:
|
||||
/* the preamble type */
|
||||
data_struct->preamble = 0U;
|
||||
/* channel status bit */
|
||||
data_struct->channel_status = 0U;
|
||||
/* user bit */
|
||||
data_struct->user_bit = 0U;
|
||||
/* validity bit */
|
||||
data_struct->validity = 0U;
|
||||
/* parity error bit */
|
||||
data_struct->parity_err = 0U;
|
||||
/* data value 0 */
|
||||
data_struct->data0 = (uint32_t)(RSPDIF_DATA & RSPDIF_DATA_F2_DATA1);
|
||||
/* data value 1 */
|
||||
data_struct->data1 = (uint32_t)(RSPDIF_DATA & RSPDIF_DATA_F2_DATA2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get duration of 5 symbols counted using rspdif_ck
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval duration of 5 symbols counted using rspdif_ck
|
||||
*/
|
||||
uint32_t rspdif_duration_of_symbols_get(void)
|
||||
{
|
||||
return ((uint32_t)((RSPDIF_STAT & RSPDIF_STAT_CKCNT5) >> RSPDIF_CKCNT5_OFFSET));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get user data information
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval user data information
|
||||
*/
|
||||
uint32_t rspdif_user_data_get(void)
|
||||
{
|
||||
return ((uint32_t)(RSPDIF_CHSTAT & RSPDIF_CHSTAT_USER));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get channel status information
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval channel status information
|
||||
*/
|
||||
uint32_t rspdif_channel_status_get(void)
|
||||
{
|
||||
return ((uint32_t)((RSPDIF_CHSTAT & RSPDIF_CHSTAT_CHS) >> 16U));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get start of block
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus rspdif_start_block_status_get(void)
|
||||
{
|
||||
if(RESET != (RSPDIF_CHSTAT & RSPDIF_CHSTAT_SOB)) {
|
||||
return SET;
|
||||
} else {
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get threshold low estimation
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval low threshold value
|
||||
*/
|
||||
uint32_t rspdif_low_threshold_get(void)
|
||||
{
|
||||
return ((uint32_t)((RSPDIF_DTH & RSPDIF_DTH_THLO) >> 16U));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get threshold high estimation
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval high threshold value
|
||||
*/
|
||||
uint32_t rspdif_high_threshold_get(void)
|
||||
{
|
||||
return ((uint32_t)(RSPDIF_DTH & RSPDIF_DTH_THHI));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get RSPDIF flag status
|
||||
\param[in] flag: RSPDIF flag status
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg RSPDIF_FLAG_RBNE : RSPDIF RX buffer is not empty
|
||||
\arg RSPDIF_FLAG_CBNE : RSPDIF RX control buffer is not empty
|
||||
\arg RSPDIF_FLAG_PERR : RSPDIF parity error
|
||||
\arg RSPDIF_FLAG_RXORERR : RSPDIF RX overrun error
|
||||
\arg RSPDIF_FLAG_SYNDB : RSPDIF synchronization block detected
|
||||
\arg RSPDIF_FLAG_SYNDO : RSPDIF synchronization done
|
||||
\arg RSPDIF_FLAG_FRERR : RSPDIF frame error
|
||||
\arg RSPDIF_FLAG_SYNERR : RSPDIF synchronization error
|
||||
\arg RSPDIF_FLAG_TMOUTERR : RSPDIF time out error
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus rspdif_flag_get(uint16_t flag)
|
||||
{
|
||||
if(RESET != (RSPDIF_STAT & flag)) {
|
||||
return SET;
|
||||
} else {
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear RSPDIF flag
|
||||
\param[in] flag: RSPDIF flag status
|
||||
one or more parameters can be selected which is shown as below:
|
||||
\arg RSPDIF_FLAG_PERR : RSPDIF parity error
|
||||
\arg RSPDIF_FLAG_RXORERR : RSPDIF RX overrun error
|
||||
\arg RSPDIF_FLAG_SYNDB : RSPDIF synchronization block detected
|
||||
\arg RSPDIF_FLAG_SYNDO : RSPDIF synchronization done
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rspdif_flag_clear(uint16_t flag)
|
||||
{
|
||||
RSPDIF_STATC |= flag;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable RSPDIF interrupt
|
||||
\param[in] interrupt: RSPDIF interrupt
|
||||
one or more parameters can be selected which is shown as below:
|
||||
\arg RSPDIF_INT_RBNE : RSPDIF RX buffer is not empty interrupt
|
||||
\arg RSPDIF_INT_CBNE : RSPDIF RX control buffer is not empty interrupt
|
||||
\arg RSPDIF_INT_PERR : RSPDIF parity error interrupt
|
||||
\arg RSPDIF_INT_RXORERR: RSPDIF RX overrun error interrupt
|
||||
\arg RSPDIF_INT_SYNDB : RSPDIF synchronization block detected interrupt
|
||||
\arg RSPDIF_INT_SYNDO : RSPDIF synchronization done interrupt
|
||||
\arg RSPDIF_INT_RXDCERR: RSPDIF data decoding error interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rspdif_interrupt_enable(uint8_t interrupt)
|
||||
{
|
||||
RSPDIF_INTEN |= (uint32_t)interrupt;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable RSPDIF interrupt
|
||||
\param[in] interrupt: RSPDIF interrupt
|
||||
one or more parameters can be selected which is shown as below:
|
||||
\arg RSPDIF_INT_RBNE : RSPDIF RX buffer is not empty interrupt
|
||||
\arg RSPDIF_INT_CBNE : RSPDIF RX control buffer is not empty interrupt
|
||||
\arg RSPDIF_INT_PERR : RSPDIF parity error interrupt
|
||||
\arg RSPDIF_INT_RXORERR: RSPDIF RX overrun error interrupt
|
||||
\arg RSPDIF_INT_SYNDB : RSPDIF synchronization block detected interrupt
|
||||
\arg RSPDIF_INT_SYNDO : RSPDIF synchronization done interrupt
|
||||
\arg RSPDIF_INT_RXDCERR: RSPDIF data decoding error interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rspdif_interrupt_disable(uint8_t interrupt)
|
||||
{
|
||||
RSPDIF_INTEN &= ~(uint32_t)interrupt;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get RSPDIF interrupt flag status
|
||||
\param[in] int_flag: RSPDIF interrupt flag status
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg RSPDIF_INT_FLAG_RBNE : RSPDIF RX buffer is not empty interrupt flag
|
||||
\arg RSPDIF_INT_FLAG_CBNE : RSPDIF RX control buffer is not empty interrupt flag
|
||||
\arg RSPDIF_INT_FLAG_PERR : RSPDIF parity error interrupt flag
|
||||
\arg RSPDIF_INT_FLAG_RXORERR : RSPDIF RX overrun error interrupt flag
|
||||
\arg RSPDIF_INT_FLAG_SYNDB : RSPDIF synchronization block detected interrupt flag
|
||||
\arg RSPDIF_INT_FLAG_SYNDO : RSPDIF synchronization done interrupt flag
|
||||
\arg RSPDIF_INT_FLAG_FRERR : RSPDIF frame error interrupt flag
|
||||
\arg RSPDIF_INT_FLAG_SYNERR : RSPDIF synchronization error interrupt flag
|
||||
\arg RSPDIF_INT_FLAG_TMOUTERR : RSPDIF time out error interrupt flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus rspdif_interrupt_flag_get(uint16_t int_flag)
|
||||
{
|
||||
uint32_t reg1 = RSPDIF_STAT;
|
||||
uint32_t reg2 = RSPDIF_INTEN;
|
||||
|
||||
switch(int_flag) {
|
||||
/* RSPDIF RX buffer is not empty interrupt */
|
||||
case RSPDIF_INT_FLAG_RBNE:
|
||||
reg1 = reg1 & RSPDIF_STAT_RBNE;
|
||||
reg2 = reg2 & RSPDIF_INTEN_RBNEIE;
|
||||
break;
|
||||
/* RSPDIF RX control buffer is not empty interrupt */
|
||||
case RSPDIF_INT_FLAG_CBNE:
|
||||
reg1 = reg1 & RSPDIF_STAT_CBNE;
|
||||
reg2 = reg2 & RSPDIF_INTEN_CBNEIE;
|
||||
break;
|
||||
/* RSPDIF parity error interrupt */
|
||||
case RSPDIF_INT_FLAG_PERR:
|
||||
reg1 = reg1 & RSPDIF_STAT_PERR;
|
||||
reg2 = reg2 & RSPDIF_INTEN_PERRIE;
|
||||
break;
|
||||
/* RSPDIF RX overrun error interrupt */
|
||||
case RSPDIF_INT_FLAG_RXORERR:
|
||||
reg1 = reg1 & RSPDIF_STAT_RXORERR;
|
||||
reg2 = reg2 & RSPDIF_INTEN_RXORERRIE;
|
||||
break;
|
||||
/* RSPDIF synchronization block detected interrupt */
|
||||
case RSPDIF_INT_FLAG_SYNDB:
|
||||
reg1 = reg1 & RSPDIF_STAT_SYNDB;
|
||||
reg2 = reg2 & RSPDIF_INTEN_SYNDBIE;
|
||||
break;
|
||||
/* RSPDIF synchronization done interrupt */
|
||||
case RSPDIF_INT_FLAG_SYNDO:
|
||||
reg1 = reg1 & RSPDIF_STAT_SYNDO;
|
||||
reg2 = reg2 & RSPDIF_INTEN_SYNDOIE;
|
||||
break;
|
||||
/* RSPDIF frame error interrupt */
|
||||
case RSPDIF_INT_FLAG_FRERR:
|
||||
reg1 = reg1 & RSPDIF_STAT_FRERR;
|
||||
reg2 = reg2 & RSPDIF_INTEN_RXDCERRIE;
|
||||
break;
|
||||
/* RSPDIF synchronization error interrupt */
|
||||
case RSPDIF_INT_FLAG_SYNERR:
|
||||
reg1 = reg1 & RSPDIF_STAT_SYNERR;
|
||||
reg2 = reg2 & RSPDIF_INTEN_RXDCERRIE;
|
||||
break;
|
||||
/* RSPDIF time out error interrupt */
|
||||
case RSPDIF_INT_FLAG_TMOUTERR:
|
||||
reg1 = reg1 & RSPDIF_STAT_TMOUTERR;
|
||||
reg2 = reg2 & RSPDIF_INTEN_RXDCERRIE;
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
/*get RSPDIF interrupt flag status */
|
||||
if((0U != reg1) && (0U != reg2)) {
|
||||
return SET;
|
||||
} else {
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear RSPDIF interrupt flag status
|
||||
\param[in] int_flag: RSPDIF interrupt flag status
|
||||
one or more parameters can be selected which is shown as below:
|
||||
\arg RSPDIF_INT_FLAG_PERR : RSPDIF parity error interrupt flag
|
||||
\arg RSPDIF_INT_FLAG_RXORERR : RSPDIF RX overrun error interrupt flag
|
||||
\arg RSPDIF_INT_FLAG_SYNDB : RSPDIF synchronization block detected interrupt flag
|
||||
\arg RSPDIF_INT_FLAG_SYNDO : RSPDIF synchronization done interrupt flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rspdif_interrupt_flag_clear(uint16_t int_flag)
|
||||
{
|
||||
RSPDIF_STATC |= int_flag ;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,384 @@
|
||||
/*!
|
||||
\file gd32h7xx_rtdec.c
|
||||
\brief RTDEC driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_rtdec.h"
|
||||
|
||||
/* RTDEC firmware version offset macro */
|
||||
#define ARE_FMVER_OFFSET (uint32_t)0x00000010U)
|
||||
|
||||
/*!
|
||||
\brief reset RTDEC
|
||||
\param[in] rtdec_periph: RTDECx(x = 0, 1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rtdec_deinit(uint32_t rtdec_periph)
|
||||
{
|
||||
if(RTDEC0 == rtdec_periph){
|
||||
/* reset RTDEC0 */
|
||||
rcu_periph_reset_enable(RCU_RTDEC0RST);
|
||||
rcu_periph_reset_disable(RCU_RTDEC0RST);
|
||||
}
|
||||
if(RTDEC1 == rtdec_periph) {
|
||||
/* reset RTDEC1 */
|
||||
rcu_periph_reset_enable(RCU_RTDEC1RST);
|
||||
rcu_periph_reset_disable(RCU_RTDEC1RST);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the parameters of RTDEC struct with default values
|
||||
\param[in] none
|
||||
\param[out] rtdec_parameter_struct: the initialized struct rtdec_parameter_struct pointer
|
||||
\retval none
|
||||
*/
|
||||
void rtdec_struct_para_init(rtdec_parameter_struct* rtdec_struct)
|
||||
{
|
||||
/* configure the structure with default value */
|
||||
rtdec_struct->access_mode = (uint8_t)RTDEC_MODE_DATA_ACCESS;
|
||||
rtdec_struct->key_crc = 0x00U;
|
||||
rtdec_struct->fw_version = 0x0000U;
|
||||
rtdec_struct->key = 0x00000000U;
|
||||
rtdec_struct->nonce = 0x00000000U;
|
||||
rtdec_struct->start_addr = 0x00000000U;
|
||||
rtdec_struct->end_addr = 0x00000000U;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize RTDEC
|
||||
\param[in] rtdec_periph: RTDECx(x = 0, 1)
|
||||
\param[in] rtdec_area: RTDEC_AREAx(x = 0, 1, 2, 3)
|
||||
\param[in] rtdec_struct: RTDEC parameter initialization stuct members of the structure
|
||||
and the member values are shown as below:
|
||||
access_mode: RTDEC_MODE_CODE_ACCESS, RTDEC_MODE_DATA_ACCESS, RTDEC_MODE_BOTH_ACCESS
|
||||
key_crc: CRC value of area key
|
||||
fw_version: area firmware version
|
||||
key: area key
|
||||
nonce: area nonce
|
||||
start_addr: area start address
|
||||
end_addr: area end address
|
||||
\param[out] none
|
||||
\retval ErrStatus: ERROR or SUCCESS
|
||||
*/
|
||||
ErrStatus rtdec_init(uint32_t rtdec_periph, uint32_t rtdec_area, rtdec_parameter_struct *rtdec_struct)
|
||||
{
|
||||
uint8_t key_crc_reg = 0U;
|
||||
uint32_t key_nonce_addr = 0U;
|
||||
|
||||
/* write the correct MODE[1:0] value and firmware version in ARExCFG register */
|
||||
RTDEC_ARE_CFG(rtdec_periph, rtdec_area) &= ~(uint32_t)(RTDEC_MODE | RTDEC_ARE_FMVER);
|
||||
RTDEC_ARE_CFG(rtdec_periph, rtdec_area) |= ((uint32_t)(rtdec_struct->access_mode)) | (uint32_t)(((uint32_t)(rtdec_struct->fw_version) << ARE_FMVER_OFFSET);
|
||||
|
||||
/* program ARExKEY registers */
|
||||
key_nonce_addr = (uint32_t)rtdec_struct->key;
|
||||
RTDEC_ARE_KEY0(rtdec_periph, rtdec_area) = *(uint32_t *)key_nonce_addr;
|
||||
key_nonce_addr += 4U;
|
||||
RTDEC_ARE_KEY1(rtdec_periph, rtdec_area) = *(uint32_t *)key_nonce_addr;
|
||||
key_nonce_addr += 4U;
|
||||
RTDEC_ARE_KEY2(rtdec_periph, rtdec_area) = *(uint32_t *)key_nonce_addr;
|
||||
key_nonce_addr += 4U;
|
||||
RTDEC_ARE_KEY3(rtdec_periph, rtdec_area) = *(uint32_t *)key_nonce_addr;
|
||||
|
||||
/* check the key CRC */
|
||||
key_crc_reg = (uint8_t)GET_BITS(RTDEC_ARE_CFG(rtdec_periph, rtdec_area), 8U, 15U);
|
||||
|
||||
if(key_crc_reg != rtdec_struct->key_crc){
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* program ARExNONCE registers */
|
||||
key_nonce_addr = (uint32_t)rtdec_struct->nonce;
|
||||
RTDEC_ARE_NONCE0(rtdec_periph, rtdec_area) = *(uint32_t *)key_nonce_addr;
|
||||
key_nonce_addr += 4U;
|
||||
RTDEC_ARE_NONCE1(rtdec_periph, rtdec_area) = *(uint32_t *)key_nonce_addr;
|
||||
|
||||
/* write the start address and end address of area */
|
||||
RTDEC_ARE_SADDR(rtdec_periph, rtdec_area) = rtdec_struct->start_addr;
|
||||
RTDEC_ARE_EADDR(rtdec_periph, rtdec_area) = rtdec_struct->end_addr;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure RTDEC area data attribute
|
||||
\param[in] rtdec_periph: RTDECx(x = 0, 1)
|
||||
\param[in] rtdec_area: RTDEC_AREAx(x = 0, 1, 2, 3)
|
||||
\param[in] access_mode: allowed access mode of data
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg RTDEC_MODE_CODE_ACCESS: code/instruction access only
|
||||
\arg RTDEC_MODE_DATA_ACCESS: data access only
|
||||
\arg RTDEC_MODE_BOTH_ACCESS: code and data access
|
||||
\param[in] firmware_version: 16-bit number, version of data
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rtdec_config(uint32_t rtdec_periph, uint32_t rtdec_area, uint8_t access_mode, uint16_t firmware_version)
|
||||
{
|
||||
/* write the correct MODE[1:0] value and firmware version in ARExCFG register */
|
||||
RTDEC_ARE_CFG(rtdec_periph, rtdec_area) &= ~(uint32_t)(RTDEC_MODE | RTDEC_ARE_FMVER);
|
||||
RTDEC_ARE_CFG(rtdec_periph, rtdec_area) |= ((uint32_t)access_mode) | ((uint32_t)((uint32_t)firmware_version << ARE_FMVER_OFFSET);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure RTDEC key or register lock
|
||||
\param[in] rtdec_periph: RTDECx(x = 0, 1)
|
||||
\param[in] rtdec_area: RTDEC_AREAx(x = 0, 1, 2, 3)
|
||||
\param[in]: lock_type: key lock or register lock
|
||||
\arg: RTDEC_ARE_CFG_LK: register lock
|
||||
\arg: RTDEC_ARE_K_LK: key lock
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rtdec_lock(uint32_t rtdec_periph, uint32_t rtdec_area, uint32_t lock_type)
|
||||
{
|
||||
RTDEC_ARE_CFG(rtdec_periph, rtdec_area) |= lock_type;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize RTDEC area address
|
||||
\param[in] rtdec_periph: RTDECx(x = 0, 1)
|
||||
\param[in] rtdec_area: RTDEC_AREAx(x = 0, 1, 2, 3)
|
||||
\param[in]: saddr: area start address, the 4 MSB bits and the 12 LSB bits are ignored
|
||||
\param[in]: eaddr: area end address, the 4 MSB bits and the 12 LSB bits are ignored
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rtdec_addr_init(uint32_t rtdec_periph, uint32_t rtdec_area, uint32_t saddr, uint32_t eaddr)
|
||||
{
|
||||
/* write the start address and end address of area */
|
||||
RTDEC_ARE_SADDR(rtdec_periph, rtdec_area) = saddr;
|
||||
RTDEC_ARE_EADDR(rtdec_periph, rtdec_area) = eaddr;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize RTDEC nonce, nonce follows little endian format
|
||||
\param[in] rtdec_periph: RTDECx(x = 0, 1)
|
||||
\param[in] rtdec_area: RTDEC_AREAx(x = 0, 1, 2, 3)
|
||||
\param[in]: nonce: an array containing 64-bit nonce data, little endian format
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rtdec_nonce_init(uint32_t rtdec_periph, uint32_t rtdec_area, uint32_t* nonce)
|
||||
{
|
||||
uint32_t nonce_addr = (uint32_t)nonce;
|
||||
|
||||
/* program ARExNONCE registers */
|
||||
RTDEC_ARE_NONCE0(rtdec_periph, rtdec_area) = *(uint32_t *)(nonce_addr);
|
||||
nonce_addr += 4U;
|
||||
RTDEC_ARE_NONCE1(rtdec_periph, rtdec_area) = *(uint32_t *)(nonce_addr);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize RTDEC key, key follows little endian format
|
||||
\param[in] rtdec_periph: RTDECx(x = 0, 1)
|
||||
\param[in] rtdec_area: RTDEC_AREAx(x = 0, 1, 2, 3)
|
||||
\param[in]: key: an array containing 128-bit key data, little endian format
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rtdec_key_init(uint32_t rtdec_periph, uint32_t rtdec_area, uint32_t* key)
|
||||
{
|
||||
uint32_t key_addr = (uint32_t)key;
|
||||
|
||||
/* program ARExKEY registers */
|
||||
RTDEC_ARE_KEY0(rtdec_periph, rtdec_area) = *(uint32_t *)(key_addr);
|
||||
key_addr += 4U;
|
||||
RTDEC_ARE_KEY1(rtdec_periph, rtdec_area) = *(uint32_t *)(key_addr);
|
||||
key_addr += 4U;
|
||||
RTDEC_ARE_KEY2(rtdec_periph, rtdec_area) = *(uint32_t *)(key_addr);
|
||||
key_addr += 4U;
|
||||
RTDEC_ARE_KEY3(rtdec_periph, rtdec_area) = *(uint32_t *)(key_addr);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get CRC value of RTDEC key data
|
||||
\param[in] rtdec_periph: RTDECx(x = 0, 1)
|
||||
\param[in] rtdec_area: RTDEC_AREAx(x = 0, 1, 2, 3)
|
||||
\param[out] none
|
||||
\retval CRC value
|
||||
*/
|
||||
uint8_t rtdec_key_crc_get(uint32_t rtdec_periph, uint32_t rtdec_area)
|
||||
{
|
||||
return (uint8_t)GET_BITS(RTDEC_ARE_CFG(rtdec_periph, rtdec_area), 8U, 15U);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable RTDEC area
|
||||
\param[in] rtdec_periph: RTDECx(x = 0, 1)
|
||||
\param[in] rtdec_area: RTDEC_AREAx(x = 0, 1, 2, 3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rtdec_enable(uint32_t rtdec_periph, uint32_t rtdec_area)
|
||||
{
|
||||
RTDEC_ARE_CFG(rtdec_periph, rtdec_area) |= RTDEC_ARE_EN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable RTDEC area
|
||||
\param[in] rtdec_periph: RTDECx(x = 0, 1)
|
||||
\param[in] rtdec_area: RTDEC_AREAx(x = 0, 1, 2, 3)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rtdec_disable(uint32_t rtdec_periph, uint32_t rtdec_area)
|
||||
{
|
||||
RTDEC_ARE_CFG(rtdec_periph, rtdec_area) &= ~RTDEC_ARE_EN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get RTDEC error flag
|
||||
\param[in] rtdec_periph: RTDECx(x = 0, 1)
|
||||
\param[in]: flag: error flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg RTDEC_FLAG_SEC_ERROR: security error flag
|
||||
\arg RTDEC_FLAG_MODE_ERROR: access mode error flag
|
||||
\arg RTDEC_FLAG_KEY_ERROR: key error flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus rtdec_flag_get(uint32_t rtdec_periph, uint32_t flag)
|
||||
{
|
||||
if(RESET != (RTDEC_INTF(rtdec_periph) & flag)){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear RTDEC error flag
|
||||
\param[in] rtdec_periph: RTDECx(x = 0, 1)
|
||||
\param[in]: flag: error flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg RTDEC_FLAG_SEC_ERROR: security error flag
|
||||
\arg RTDEC_FLAG_MODE_ERROR: access mode error flag
|
||||
\arg RTDEC_FLAG_KEY_ERROR: key error flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rtdec_flag_clear(uint32_t rtdec_periph, uint32_t flag)
|
||||
{
|
||||
RTDEC_INTC(rtdec_periph) |= flag;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable RTDEC interrupt
|
||||
\param[in] rtdec_periph: RTDECx(x = 0, 1)
|
||||
\param[in]: interrupt: interrupt type
|
||||
one or more parameters can be selected which is shown as below:
|
||||
\arg RTDEC_INT_SEC: security error interrupt
|
||||
\arg RTDEC_INT_MODE: access mode error interrupt
|
||||
\arg RTDEC_INT_KEY: key error interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rtdec_interrupt_enable(uint32_t rtdec_periph, uint32_t interrupt)
|
||||
{
|
||||
RTDEC_INTEN(rtdec_periph) |= interrupt;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable RTDEC interrupt
|
||||
\param[in] rtdec_periph: RTDECx(x = 0, 1)
|
||||
\param[in]: interrupt: interrupt type
|
||||
one or more parameters can be selected which is shown as below:
|
||||
\arg RTDEC_INT_SEC: security error interrupt
|
||||
\arg RTDEC_INT_MODE: access mode error interrupt
|
||||
\arg RTDEC_INT_KEY: key error interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rtdec_interrupt_disable(uint32_t rtdec_periph, uint32_t interrupt)
|
||||
{
|
||||
RTDEC_INTEN(rtdec_periph) &= ~interrupt;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get RTDEC interrupt flag
|
||||
\param[in] rtdec_periph: RTDECx(x = 0, 1)
|
||||
\param[in]: int_flag: interrupt flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg RTDEC_INT_FLAG_SEC_ERROR: security error interrupt flag
|
||||
\arg RTDEC_INT_FLAG_MODE_ERROR: access mode error interrupt flag
|
||||
\arg RTDEC_INT_FLAG_KEY_ERROR: key error interrupt flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus rtdec_interrupt_flag_get(uint32_t rtdec_periph, uint32_t int_flag)
|
||||
{
|
||||
uint32_t interrupt_enable = 0U, interrupt_flag = 0U;
|
||||
|
||||
switch(int_flag){
|
||||
/* RTDEC security error interrupt */
|
||||
case RTDEC_INT_FLAG_SEC_ERROR:
|
||||
interrupt_flag = RTDEC_INTF(rtdec_periph) & int_flag;
|
||||
interrupt_enable = RTDEC_INTEN(rtdec_periph) & RTDEC_INT_SEC;
|
||||
break;
|
||||
/* RTDEC execute-only or execute-never error interrupt */
|
||||
case RTDEC_INT_FLAG_MODE_ERROR:
|
||||
interrupt_flag = RTDEC_INTF(rtdec_periph) & int_flag;
|
||||
interrupt_enable = RTDEC_INTEN(rtdec_periph) & RTDEC_INT_MODE;
|
||||
break;
|
||||
/* RTDEC key error interrupt */
|
||||
case RTDEC_INT_FLAG_KEY_ERROR:
|
||||
interrupt_flag = RTDEC_INTF(rtdec_periph) & int_flag;
|
||||
interrupt_enable = RTDEC_INTEN(rtdec_periph) & RTDEC_INT_KEY;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* get RTDEC interrupt flag status */
|
||||
if(interrupt_flag && interrupt_enable){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear RTDEC interrupt flag
|
||||
\param[in] rtdec_periph: RTDECx(x = 0, 1)
|
||||
\param[in]: int_flag: interrupt flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg RTDEC_INT_FLAG_SEC_ERROR: security error interrupt flag
|
||||
\arg RTDEC_INT_FLAG_MODE_ERROR: access mode error interrupt flag
|
||||
\arg RTDEC_INT_FLAG_KEY_ERROR: key error interrupt flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rtdec_interrupt_flag_clear(uint32_t rtdec_periph, uint32_t int_flag)
|
||||
{
|
||||
RTDEC_INTC(rtdec_periph) |= int_flag;
|
||||
}
|
||||
@@ -0,0 +1,792 @@
|
||||
/*!
|
||||
\file gd32h7xx_sai.c
|
||||
\brief SAI driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_sai.h"
|
||||
|
||||
/* SAI pdm mode microphone delay mask */
|
||||
#define PDM_MICROPHONE_DELAY_MASK ((uint32_t)0x00000007U)
|
||||
/*!< bit offset of MTFCNT in SAI_CFG1 */
|
||||
#define CFG1_MTFCNT_OFFSET ((uint32_t)0x00000007U)
|
||||
|
||||
/*!
|
||||
\brief reset SAI
|
||||
\param[in] sai_periph: SAIx(x = 0,1,2)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sai_deinit(uint32_t sai_periph)
|
||||
{
|
||||
switch(sai_periph) {
|
||||
case SAI0:
|
||||
/* reset SAI0 */
|
||||
rcu_periph_reset_enable(RCU_SAI0RST);
|
||||
rcu_periph_reset_disable(RCU_SAI0RST);
|
||||
break;
|
||||
case SAI1:
|
||||
/* reset SAI1 */
|
||||
rcu_periph_reset_enable(RCU_SAI1RST);
|
||||
rcu_periph_reset_disable(RCU_SAI1RST);
|
||||
break;
|
||||
case SAI2:
|
||||
/* reset SAI2 */
|
||||
rcu_periph_reset_enable(RCU_SAI2RST);
|
||||
rcu_periph_reset_disable(RCU_SAI2RST);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the parameter of SAI structure with a default value
|
||||
\param[in] none
|
||||
\param[out] sai_init_stuct: the initialization data needed to initialize SAI
|
||||
\retval none
|
||||
*/
|
||||
void sai_struct_para_init(sai_parameter_struct *sai_init_stuct)
|
||||
{
|
||||
/* initialize the initpara struct member with the default value */
|
||||
sai_init_stuct->operating_mode = SAI_MASTER_TRANSMITTER;
|
||||
sai_init_stuct->protocol = SAI_PROTOCOL_POLYMORPHIC;
|
||||
sai_init_stuct->data_width = SAI_DATAWIDTH_32BIT;
|
||||
sai_init_stuct->shift_dir = SAI_SHIFT_MSB;
|
||||
sai_init_stuct->sample_edge = SAI_SAMPEDGE_FALLING;
|
||||
sai_init_stuct->sync_mode = SAI_SYNCMODE_ASYNC;
|
||||
sai_init_stuct->output_drive = SAI_OUTPUT_WITH_SAIEN;
|
||||
sai_init_stuct->clk_div_bypass = SAI_CLKDIV_BYPASS_OFF;
|
||||
sai_init_stuct->mclk_div = SAI_MCLKDIV_1;
|
||||
sai_init_stuct->mclk_oversampling = SAI_MCLK_OVERSAMP_256;
|
||||
sai_init_stuct->mclk_enable = SAI_MCLK_DISABLE;
|
||||
sai_init_stuct->fifo_threshold = SAI_FIFOTH_EMPTY;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the parameter of SAI frame structure with a default value
|
||||
\param[in] none
|
||||
\param[out] sai_frame_init_struct: the initialization data needed to initialize SAI frame
|
||||
\retval none
|
||||
*/
|
||||
void sai_frame_struct_para_init(sai_frame_parameter_struct *sai_frame_init_struct)
|
||||
{
|
||||
/* initialize the initpara struct member with the default value */
|
||||
sai_frame_init_struct->frame_width = 256U;
|
||||
sai_frame_init_struct->frame_sync_width = 128U;
|
||||
sai_frame_init_struct->frame_sync_function = SAI_FS_FUNC_START;
|
||||
sai_frame_init_struct->frame_sync_polarity = SAI_FS_POLARITY_LOW;
|
||||
sai_frame_init_struct->frame_sync_offset = SAI_FS_OFFSET_BEGINNING;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the parameter of SAI slot structure with a default value
|
||||
\param[in] none
|
||||
\param[out] sai_slot_init_struct: the initialization data needed to initialize SAI slot
|
||||
\retval none
|
||||
*/
|
||||
void sai_slot_struct_para_init(sai_slot_parameter_struct *sai_slot_init_struct)
|
||||
{
|
||||
/* initialize the initpara struct member with the default value */
|
||||
sai_slot_init_struct->slot_number = 16U;
|
||||
sai_slot_init_struct->slot_width = SAI_SLOT_WIDTH_DATA;
|
||||
sai_slot_init_struct->data_offset = 0U;
|
||||
sai_slot_init_struct->slot_active = SAI_SLOT_ACTIVE_NONE;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize SAI
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[in] block: specify which bolck is initialized
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SAI_BLOCKx(x = 0,1)
|
||||
\param[in] sai_struct: SAI parameter initialization stuct members of the structure
|
||||
and the member values are shown as below:
|
||||
operating_mode: SAI_MASTER_TRANSMITTER, SAI_MASTER_RECEIVER, SAI_SLAVE_TRANSMITTER, SAI_SLAVE_RECEIVER;
|
||||
protocol: SAI_PROTOCOL_POLYMORPHIC, SAI_PROTOCOL_SPDIF, SAI_PROTOCOL_AC97
|
||||
data_width: SAI_DATA_WIDTH_xBIT (x = 8, 10, 16, 20, 24, 32)
|
||||
shift_dir: SAI_SHIFT_MSB, SAI_SHIFT_LSB
|
||||
sample_edge: SAI_SAMPEDGE_FALLING, SAI_SAMPEDGE_RISING
|
||||
sync_mode: SAI_SYNCMODE_ASYNC, SAI_SYNCMODE_OTHERBLOCK, SAI_SYNCMODE_EXTERNALSAI
|
||||
output_drive: SAI_OUTPUT_WITH_SAIEN, SAI_OUTPUT_NOW
|
||||
clk_div_bypass: SAI_CLKDIV_BYPASS_OFF, SAI_CLKDIV_BYPASS_ON
|
||||
mck_div: SAI_MCLKDIV_x (x = 1,2,..,63)
|
||||
mck_oversampling: SAI_MASTERCLK_OVERSAMP_256, SAI_MASTERCLK_OVERSAMP_512
|
||||
mck_enable: SAI_MASTERCLK_DISABLE, SAI_MASTERCLK_ENABLE
|
||||
fifo_threshold: SAI_FIFOTH_EMPTY, SAI_FIFOTH_QUARTER, SAI_FIFOTH_HALF, SAI_FIFOTH_THREE_QUARTER, SAI_FIFOTH_FULL
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sai_init(uint32_t sai_periph, uint32_t block, sai_parameter_struct *sai_struct)
|
||||
{
|
||||
uint32_t reg = 0U;
|
||||
|
||||
/* configure the SAI CFGR0 value */
|
||||
reg = SAI_CFG0(sai_periph, block);
|
||||
reg &= ~(SAI_CFG0_OPTMOD | SAI_CFG0_PROT | \
|
||||
SAI_CFG0_DATAWD | SAI_CFG0_SHIFTDIR | \
|
||||
SAI_CFG0_SAMPEDGE | SAI_CFG0_SYNCMOD | \
|
||||
SAI_CFG0_ODRIV | SAI_CFG0_BYPASS | \
|
||||
SAI_CFG0_MDIV | SAI_CFG0_MOSPR | \
|
||||
SAI_CFG0_MCLKEN | SAI_CFG0_SAIEN);
|
||||
|
||||
reg |= (uint32_t)(sai_struct->operating_mode | sai_struct->protocol | \
|
||||
sai_struct->data_width | sai_struct->shift_dir | \
|
||||
sai_struct->sample_edge | sai_struct->sync_mode | \
|
||||
sai_struct->output_drive | sai_struct->clk_div_bypass | \
|
||||
sai_struct->mclk_div | sai_struct->mclk_oversampling | \
|
||||
sai_struct->mclk_enable);
|
||||
SAI_CFG0(sai_periph, block) = reg;
|
||||
|
||||
/* configure the SAI CFGR1 FIFO threshold */
|
||||
reg = SAI_CFG1(sai_periph, block);
|
||||
reg &= ~SAI_CFG1_FFTH;
|
||||
reg |= (uint32_t)(sai_struct->fifo_threshold);
|
||||
SAI_CFG1(sai_periph, block) = reg;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize SAI frame
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[in] block: specify which bolck is initialized
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SAI_BLOCKx(x=0,1)
|
||||
\param[in] sai_frame_struct: SAI frame parameter initialization stuct members of the structure
|
||||
and the member values are shown as below:
|
||||
frame_width: 1~256, frame width
|
||||
frame_sync_width: 1~128, frame synchronization active width
|
||||
frame_sync_function: SAI_FS_FUNC_START, SAI_FS_FUNC_START_CHANNEL
|
||||
frame_sync_polarity: SAI_FS_POLARITY_LOW, SAI_FS_POLARITY_HIGH
|
||||
frame_sync_offset: SAI_FS_OFFSET_BEGINNING, SAI_FS_OFFSET_ONEBITBEFORE
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sai_frame_init(uint32_t sai_periph, uint32_t block, sai_frame_parameter_struct *sai_frame_struct)
|
||||
{
|
||||
uint32_t reg = 0U;
|
||||
reg = SAI_FCFG(sai_periph, block);
|
||||
reg &= ~(SAI_FCFG_FWD | SAI_FCFG_FSAWD | SAI_FCFG_FSFUNC | \
|
||||
SAI_FCFG_FSPL | SAI_FCFG_FSOST);
|
||||
reg |= (uint32_t)(sai_frame_struct->frame_sync_offset | \
|
||||
sai_frame_struct->frame_sync_polarity | \
|
||||
sai_frame_struct->frame_sync_function | \
|
||||
((sai_frame_struct->frame_sync_width - 1U) << 8U) | \
|
||||
(sai_frame_struct->frame_width - 1U));
|
||||
/* config the SAI freame */
|
||||
SAI_FCFG(sai_periph, block) = reg;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize SAI slot
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[in] block: specify which bolck is initialized
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SAI_BLOCKx(x=0,1)
|
||||
\param[in] sai_slot_struct: SAI slot parameter initialization stuct members of the structure
|
||||
and the member values are shown as below:
|
||||
slot_number: 1~16, slot number
|
||||
slot_width: SAI_SLOTWIDTH_DATA, SAI_SLOTWIDTH_16BIT, SAI_SLOTWIDTH_32BIT
|
||||
data_offset: 0~31, data offset
|
||||
slot_active: one or more parameters can be selected, SAI_SLOT_ACTIVE_NONE, SAI_SLOT_ACTIVE_x(x=0..15), SAI_SLOT_ACTIVE_ALL
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sai_slot_init(uint32_t sai_periph, uint32_t block, sai_slot_parameter_struct *sai_slot_struct)
|
||||
{
|
||||
uint32_t reg = 0U;
|
||||
reg = SAI_SCFG(sai_periph, block);
|
||||
reg &= ~(SAI_SCFG_DATAOST | SAI_SCFG_SLOTWD | SAI_SCFG_SLOTNUM | SAI_SCFG_SLOTAV);
|
||||
reg = (uint32_t)(((sai_slot_struct->slot_number - 1U) << 8U) | \
|
||||
sai_slot_struct->slot_width | \
|
||||
sai_slot_struct->data_offset | \
|
||||
sai_slot_struct->slot_active);
|
||||
/* configure the SAI slot */
|
||||
SAI_SCFG(sai_periph, block) = reg;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief SAI enable
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[in] block: specify which bolck is initialized
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SAI_BLOCKx(x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sai_enable(uint32_t sai_periph, uint32_t block)
|
||||
{
|
||||
SAI_CFG0(sai_periph, block) |= SAI_CFG0_SAIEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief SAI disable
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[in] block: specify which bolck is initialized
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SAI_BLOCKx(x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sai_disable(uint32_t sai_periph, uint32_t block)
|
||||
{
|
||||
SAI_CFG0(sai_periph, block) &= ~SAI_CFG0_SAIEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief SAI serial data near inactive slot output management
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[in] block: specify which bolck is initialized
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SAI_BLOCKx(x=0,1)
|
||||
\param[in] sdout: serial data output management
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SAI_SDLINE_DRIVE: SD line output is driven entirely during the audio frame
|
||||
\arg SAI_SDLINE_RELEASE: SD line output is released near inactive slots
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sai_sdoutput_config(uint32_t sai_periph, uint32_t block, uint32_t sdout)
|
||||
{
|
||||
SAI_CFG1(sai_periph, block) &= ~SAI_CFG1_SDOM;
|
||||
SAI_CFG1(sai_periph, block) |= sdout;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure SAI mono mode
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[in] block: specify which bolck is initialized
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SAI_BLOCKx (x=0,1)
|
||||
\param[in] mono: stereo and mono mode selection
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SAI_STEREO_MODE: stereo mode
|
||||
\arg SAI_MONO_MODE: mono mode
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sai_monomode_config(uint32_t sai_periph, uint32_t block, uint32_t mono)
|
||||
{
|
||||
SAI_CFG0(sai_periph, block) &= ~SAI_CFG0_MONO;
|
||||
SAI_CFG0(sai_periph, block) |= mono ;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure SAI companding mode
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[in] block: specify which bolck is initialized
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SAI_BLOCKx (x=0,1)
|
||||
\param[in] compander: compander mode
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SAI_COMPANDER_OFF: no compansion applies
|
||||
\arg SAI_COMPANDER_ULAW: u-law algorithm
|
||||
\arg SAI_COMPANDER_ALAW: A-law algorithm
|
||||
\param[in] complement:complement mode
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SAI_COMPLEMENT_1S: data represented in 1's complement form
|
||||
\arg SAI_COMPLEMENT_2S: data represented in 2's complement form
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sai_companding_config(uint32_t sai_periph, uint32_t block, uint32_t compander,
|
||||
uint32_t complement)
|
||||
{
|
||||
uint32_t reg = 0U;
|
||||
reg = SAI_CFG1(sai_periph, block);
|
||||
reg &= ~(SAI_CFG1_CPLMOD | SAI_CFG1_CPAMOD);
|
||||
reg |= (compander | complement);
|
||||
SAI_CFG1(sai_periph, block) = reg;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief SAI mute detected enable or mute send enable
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[in] block: specify which bolck is initialized
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SAI_BLOCKx (x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sai_mute_enable(uint32_t sai_periph, uint32_t block)
|
||||
{
|
||||
SAI_CFG1(sai_periph, block) |= SAI_CFG1_MT;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief SAI mute detected disable or mute send disable
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[in] block: specify which bolck is initialized
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SAI_BLOCKx (x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sai_mute_disable(uint32_t sai_periph, uint32_t block)
|
||||
{
|
||||
SAI_CFG1(sai_periph, block) &= ~SAI_CFG1_MT;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure SAI mute value
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[in] block: specify which bolck is initialized
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SAI_BLOCKx (x=0,1)
|
||||
\param[in] value: mute value
|
||||
only one parameter can be selected which are shown as below:
|
||||
\arg SAI_MUTESENT_0: 0 is sent via the serial data line when mute is on
|
||||
\arg SAI_MUTESENT_LASTFREAM: If SLOTNUM is less or equals to two, last frame is sent via the serial data line
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sai_mute_value_config(uint32_t sai_periph, uint32_t block, uint32_t value)
|
||||
{
|
||||
SAI_CFG1(sai_periph, block) &= ~SAI_CFG1_MTVAL;
|
||||
SAI_CFG1(sai_periph, block) |= value;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure SAI mute frame count
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[in] block: specify which bolck is initialized
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SAI_BLOCKx (x=0,1)
|
||||
\param[in] count: 0~63, mute frame count
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sai_mute_count_config(uint32_t sai_periph, uint32_t block, uint32_t count)
|
||||
{
|
||||
uint32_t reg = 0U;
|
||||
reg = SAI_CFG1(sai_periph, block);
|
||||
reg &= ~SAI_CFG1_MTFCNT;
|
||||
reg |= count << CFG1_MTFCNT_OFFSET;
|
||||
SAI_CFG1(sai_periph, block) = reg;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief SAI transmit data
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[in] block: specify which bolck is initialized
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SAI_BLOCKx (x=0,1)
|
||||
\param[in] data: 32-bit data
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sai_data_transmit(uint32_t sai_periph, uint32_t block, uint32_t data)
|
||||
{
|
||||
SAI_DATA(sai_periph, block) = data;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief SAI receive data
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[in] block: specify which bolck is initialized
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SAI_BLOCKx (x=0,1)
|
||||
\param[out] none
|
||||
\retval received data
|
||||
*/
|
||||
uint32_t sai_data_receive(uint32_t sai_periph, uint32_t block)
|
||||
{
|
||||
return SAI_DATA(sai_periph, block);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get SAI fifo status
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[in] block: specify which bolck is initialized
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SAI_BLOCKx (x=0,1)
|
||||
\param[out] none
|
||||
\retval state of fifo
|
||||
\arg FIFO_EMPTY: empty
|
||||
\arg FIFO_EMPTY_TO_1_4_FULL: empty < fifo_level <= 1/4_full
|
||||
\arg FIFO_1_4_FULL_TO_1_2_FULL: 1/4_full < fifo_level <= 1/2_full
|
||||
\arg FIFO_1_2_FULL_TO_3_4_FULL: 1/2_full < fifo_level <= 3/4_full
|
||||
\arg FIFO_3_4_FULL_TO_FULL: 3/4_full < fifo_level < full
|
||||
\arg FIFO_FULL: full
|
||||
*/
|
||||
sai_fifo_state_enum sai_fifo_status_get(uint32_t sai_periph, uint32_t block)
|
||||
{
|
||||
sai_fifo_state_enum sai_fifo_state = FIFO_EMPTY;
|
||||
|
||||
if(SAI_FIFO_STAT_EMPTY == (SAI_STAT(sai_periph, block) & SAI_STAT_FFSTAT)) {
|
||||
sai_fifo_state = FIFO_EMPTY;
|
||||
} else if(SAI_FIFO_STAT_QUARTER == (SAI_STAT(sai_periph, block) & SAI_STAT_FFSTAT)) {
|
||||
sai_fifo_state = FIFO_EMPTY_TO_1_4_FULL;
|
||||
} else if(SAI_FIFO_STAT_HALF == (SAI_STAT(sai_periph, block) & SAI_STAT_FFSTAT)) {
|
||||
sai_fifo_state = FIFO_1_4_FULL_TO_1_2_FULL;
|
||||
} else if(SAI_FIFO_STAT_THREE_QUARTER == (SAI_STAT(sai_periph, block) & SAI_STAT_FFSTAT)) {
|
||||
sai_fifo_state = FIFO_1_2_FULL_TO_3_4_FULL;
|
||||
} else if(SAI_FIFO_STAT_NEARFULL == (SAI_STAT(sai_periph, block) & SAI_STAT_FFSTAT)) {
|
||||
sai_fifo_state = FIFO_3_4_FULL_TO_FULL;
|
||||
} else {
|
||||
sai_fifo_state = FIFO_FULL;
|
||||
}
|
||||
|
||||
return sai_fifo_state;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief SAI fifo flush
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[in] block: specify which bolck is initialized
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SAI_BLOCKx (x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sai_fifo_flush(uint32_t sai_periph, uint32_t block)
|
||||
{
|
||||
SAI_CFG1(sai_periph, block) |= SAI_CFG1_FLUSH;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable SAI dma
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[in] block: specify which bolck is initialized
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SAI_BLOCKx (x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sai_dma_enable(uint32_t sai_periph, uint32_t block)
|
||||
{
|
||||
SAI_CFG0(sai_periph, block) |= SAI_CFG0_DMAEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable SAI dma
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[in] block: specify which bolck is initialized
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SAI_BLOCKx (x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sai_dma_disable(uint32_t sai_periph, uint32_t block)
|
||||
{
|
||||
SAI_CFG0(sai_periph, block) &= ~SAI_CFG0_DMAEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief SAI synchronization input select
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[in] input: specify which external SAI to be select for synchronization
|
||||
only one parameter can be selected which are shown as below:
|
||||
\arg SAI_SYNCINPUT_SAI0: SAI1 or SAI2 selects the synchronization coming from SAI0
|
||||
\arg SAI_SYNCINPUT_SAI1: SAI0 or SAI2 selects the synchronization coming from SAI1
|
||||
\arg SAI_SYNCINPUT_SAI2: SAI0 or SAI1 selects the synchronization coming from SAI2
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sai_sync_input_config(uint32_t sai_periph, uint32_t input)
|
||||
{
|
||||
uint32_t reg = 0U;
|
||||
reg = SAI_SYNCFG(sai_periph);
|
||||
reg &= ~SAI_SYNCFG_SYNI;
|
||||
reg |= input;
|
||||
SAI_SYNCFG(sai_periph) = reg;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief SAI synchronization output select
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[in] output: specify which block to be used for further synchronization for others SAI
|
||||
only one parameter can be selected which are shown as below:
|
||||
\arg SAI_SYNCOUTPUT_OFF: no synchronization output signals
|
||||
\arg SAI_SYNCOUTPUT_BLOCK0: block 0 used for further synchronization for others SAI
|
||||
\arg SAI_SYNCOUTPUT_BLOCK1: block 1 used for further synchronization for others SAI
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sai_sync_output_config(uint32_t sai_periph, uint32_t output)
|
||||
{
|
||||
uint32_t reg = 0U;
|
||||
reg = SAI_SYNCFG(sai_periph);
|
||||
reg &= ~SAI_SYNCFG_SYNO;
|
||||
reg |= output;
|
||||
SAI_SYNCFG(sai_periph) = reg;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable SAI pdm mode
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sai_pdm_enable(uint32_t sai_periph)
|
||||
{
|
||||
SAI_PDMCTL(sai_periph) |= SAI_PDMCTL_PDMEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable SAI pdm mode
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sai_pdm_disable(uint32_t sai_periph)
|
||||
{
|
||||
SAI_PDMCTL(sai_periph) &= ~SAI_PDMCTL_PDMEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure SAI pdm mode microphone number
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[in] microphonenum: 2, 4, 6 or 8(not applicable to GD32H7xx), select microphones number
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sai_pdm_microphone_number_config(uint32_t sai_periph, uint32_t microphonenum)
|
||||
{
|
||||
uint32_t temp = SAI_PDMCTL(sai_periph);
|
||||
temp &= ~SAI_PDMCTL_MICNUMSEL;
|
||||
temp |= ((microphonenum / 2U - 1U) << 4U);
|
||||
SAI_PDMCTL(sai_periph) = temp;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure SAI pdm mode microphone delay
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[in] microphone: specify which microphone delay parameter to config
|
||||
only one parameter can be selected which are shown as below:
|
||||
\arg SAI_PDM_MICROPHONE0_L: microphone 0 channel left
|
||||
\arg SAI_PDM_MICROPHONE0_R: microphone 0 channel right
|
||||
\arg SAI_PDM_MICROPHONE1_L: microphone 1 channel left
|
||||
\arg SAI_PDM_MICROPHONE1_R: microphone 1 channel right
|
||||
\arg SAI_PDM_MICROPHONE2_L: microphone 2 channel left
|
||||
\arg SAI_PDM_MICROPHONE2_R: microphone 2 channel right
|
||||
\arg SAI_PDM_MICROPHONE3_L: microphone 3 channel left, (not applicable to GD32H7xx)
|
||||
\arg SAI_PDM_MICROPHONE3_R: microphone 3 channel right, (not applicable to GD32H7xx)
|
||||
\param[in] delay: 0~7, the microphone data flow delay period
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sai_pdm_delay_config(uint32_t sai_periph, uint32_t microphone, uint32_t delay)
|
||||
{
|
||||
uint32_t temp = SAI_PDMCFG(sai_periph);
|
||||
temp &= ~(PDM_MICROPHONE_DELAY_MASK << (microphone * 4U));
|
||||
temp |= (delay << (microphone * 4U));
|
||||
SAI_PDMCFG(sai_periph) = temp;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable SAI pdm mode clock line 0
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sai_pdm_clk0_enable(uint32_t sai_periph)
|
||||
{
|
||||
SAI_PDMCTL(sai_periph) |= SAI_PDMCTL_CLKL0EN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable SAI pdm mode clock line 0
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sai_pdm_clk0_disable(uint32_t sai_periph)
|
||||
{
|
||||
SAI_PDMCTL(sai_periph) &= ~SAI_PDMCTL_CLKL0EN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable SAI pdm mode clock line 1
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sai_pdm_clk1_enable(uint32_t sai_periph)
|
||||
{
|
||||
SAI_PDMCTL(sai_periph) |= SAI_PDMCTL_CLKL1EN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable SAI pdm mode clock line 1
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sai_pdm_clk1_disable(uint32_t sai_periph)
|
||||
{
|
||||
SAI_PDMCTL(sai_periph) &= ~SAI_PDMCTL_CLKL1EN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the SAI interrupt
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[in] block: specify which bolck is initialized
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SAI_BLOCKx(x=0,1)
|
||||
\param[in] interrupt: specify which interrupt to enable
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg SAI_INT_OUERR: FIFO overrun or underrun interrupt enable
|
||||
\arg SAI_INT_MTDET: mute detection interrupt enable
|
||||
\arg SAI_INT_ERRCK: error clock interrupt enable
|
||||
\arg SAI_INT_FFREQ: FIFO request interrupt enable
|
||||
\arg SAI_INT_ACNRDY: audio codec not ready interrupt enable
|
||||
\arg SAI_INT_FSADET: frame synchronization advanced detection interrupt enable
|
||||
\arg SAI_INT_FSPDET: frame synchronization postpone detection interrupt enable
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sai_interrupt_enable(uint32_t sai_periph, uint32_t block, uint32_t interrupt)
|
||||
{
|
||||
SAI_INTEN(sai_periph, block) |= interrupt;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the SAI interrupt
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[in] block: specify which bolck is initialized
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SAI_BLOCKx(x=0,1)
|
||||
\param[in] interrupt: specify which interrupt to disable
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg SAI_INT_OUERR: FIFO overrun or underrun interrupt
|
||||
\arg SAI_INT_MTDET: mute detection interrupt
|
||||
\arg SAI_INT_ERRCK: error clock interrupt
|
||||
\arg SAI_INT_FFREQ: FIFO request interrupt
|
||||
\arg SAI_INT_ACNRDY: audio codec not ready interrupt
|
||||
\arg SAI_INT_FSADET: frame synchronization advanced detection interrupt
|
||||
\arg SAI_INT_FSPDET: frame synchronization postpone detection interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sai_interrupt_disable(uint32_t sai_periph, uint32_t block, uint32_t interrupt)
|
||||
{
|
||||
SAI_INTEN(sai_periph, block) &= ~interrupt;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the SAI interrupt flag
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[in] block: specify which bolck is initialized
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SAI_BLOCKx(x=0,1)
|
||||
\param[in] interrupt: specify which interrupt flag to get
|
||||
only one parameter can be selected which are shown as below:
|
||||
\arg SAI_FLAG_OUERR: FIFO overrun or underrun interrupt flag
|
||||
\arg SAI_FLAG_MTDET: mute detection interrupt flag
|
||||
\arg SAI_FLAG_ERRCK: error clock interrupt flag
|
||||
\arg SAI_FLAG_FFREQ: FIFO request interrupt flag
|
||||
\arg SAI_FLAG_ACNRDY: audio codec not ready interrupt flag
|
||||
\arg SAI_FLAG_FSADET: frame synchronization advanced detection interrupt flag
|
||||
\arg SAI_FLAG_FSPDET: frame synchronization postpone detection interrupt flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus sai_interrupt_flag_get(uint32_t sai_periph, uint32_t block, uint32_t interrupt)
|
||||
{
|
||||
uint32_t inten = 0U;
|
||||
inten = SAI_INTEN(sai_periph, block) & interrupt;
|
||||
if((RESET != (SAI_STAT(sai_periph, block) & interrupt)) && (RESET != inten)) {
|
||||
return SET;
|
||||
} else {
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear the SAI interrupt flag
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[in] block: specify which bolck is initialized
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SAI_BLOCKx(x=0,1)
|
||||
\param[in] interrupt: specify which interrupt flag to clear
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg SAI_FLAG_OUERR: FIFO overrun or underrun interrupt flag
|
||||
\arg SAI_FLAG_MTDET: mute detection interrupt flag
|
||||
\arg SAI_FLAG_ERRCK: error clock interrupt flag
|
||||
\arg SAI_FLAG_ACNRDY: audio codec not ready interrupt flag
|
||||
\arg SAI_FLAG_FSADET: frame synchronization advanced detection interrupt flag
|
||||
\arg SAI_FLAG_FSPDET: frame synchronization postpone detection interrupt flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sai_interrupt_flag_clear(uint32_t sai_periph, uint32_t block, uint32_t interrupt)
|
||||
{
|
||||
SAI_INTC(sai_periph, block) = interrupt;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the SAI flag
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[in] block: specify which bolck is initialized
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SAI_BLOCKx(x=0,1)
|
||||
\param[in] flag: specify which flag to get
|
||||
only one parameter can be selected which are shown as below:
|
||||
\arg SAI_FLAG_OUERR: FIFO overrun or underrun flag
|
||||
\arg SAI_FLAG_MTDET: mute detection flag
|
||||
\arg SAI_FLAG_ERRCK: error clock flag
|
||||
\arg SAI_FLAG_FFREQ: FIFO request flag
|
||||
\arg SAI_FLAG_ACNRDY: audio codec not ready flag
|
||||
\arg SAI_FLAG_FSADET: frame synchronization advanced detection flag
|
||||
\arg SAI_FLAG_FSPDET: frame synchronization postpone detection flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus sai_flag_get(uint32_t sai_periph, uint32_t block, uint32_t flag)
|
||||
{
|
||||
if(RESET != (SAI_STAT(sai_periph, block) & flag)) {
|
||||
return SET;
|
||||
} else {
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear the SAI flag
|
||||
\param[in] sai_periph: SAIx(x=0,1,2)
|
||||
\param[in] block: specify which bolck is initialized
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SAI_BLOCKx(x=0,1)
|
||||
\param[in] flag: specify which flag to clear
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg SAI_FLAG_OUERR: FIFO overrun or underrun flag
|
||||
\arg SAI_FLAG_MTDET: mute detection flag
|
||||
\arg SAI_FLAG_ERRCK: error clock flag
|
||||
\arg SAI_FLAG_ACNRDY: audio codec not ready flag
|
||||
\arg SAI_FLAG_FSADET: frame synchronization advanced detection flag
|
||||
\arg SAI_FLAG_FSPDET: frame synchronization postpone detection flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sai_flag_clear(uint32_t sai_periph, uint32_t block, uint32_t flag)
|
||||
{
|
||||
SAI_INTC(sai_periph, block) = flag;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,646 @@
|
||||
/*!
|
||||
\file gd32h7xx_syscfg.c
|
||||
\brief SYSCFG driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_syscfg.h"
|
||||
/*!
|
||||
\brief reset the SYSCFG registers
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void syscfg_deinit(void)
|
||||
{
|
||||
rcu_periph_reset_enable(RCU_SYSCFGRST);
|
||||
rcu_periph_reset_disable(RCU_SYSCFGRST);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable I2Cx(x=0,1,2,3) fast mode plus or I2C fast mode plus PBx(x=6,7,8,9)
|
||||
\param[in] i2c_fmp
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg SYSCFG_I2C0_FMP: I2C0 fast mode plus
|
||||
\arg SYSCFG_I2C1_FMP: I2C1 fast mode plus
|
||||
\arg SYSCFG_I2C2_FMP: I2C2 fast mode plus
|
||||
\arg SYSCFG_I2C3_FMP: I2C3 fast mode plus
|
||||
\arg SYSCFG_I2C_FMP_PB6: I2C fast mode plus on PB6 pin
|
||||
\arg SYSCFG_I2C_FMP_PB7: I2C fast mode plus on PB7 pin
|
||||
\arg SYSCFG_I2C_FMP_PB8: I2C fast mode plus on PB8 pin
|
||||
\arg SYSCFG_I2C_FMP_PB9: I2C fast mode plus on PB9 pin
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void syscfg_i2c_fast_mode_plus_enable(uint32_t i2c_fmp)
|
||||
{
|
||||
SYSCFG_PMCFG |= i2c_fmp;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable I2Cx(x=0,1,2,3) fast mode plus or I2C fast mode plus PBx(x=6,7,8,9)
|
||||
\param[in] i2c_fmp
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg SYSCFG_I2C0_FMP: I2C0 fast mode plus
|
||||
\arg SYSCFG_I2C1_FMP: I2C1 fast mode plus
|
||||
\arg SYSCFG_I2C2_FMP: I2C2 fast mode plus
|
||||
\arg SYSCFG_I2C3_FMP: I2C3 fast mode plus
|
||||
\arg SYSCFG_I2C_FMP_PB6: I2C fast mode plus on PB6 pin
|
||||
\arg SYSCFG_I2C_FMP_PB7: I2C fast mode plus on PB7 pin
|
||||
\arg SYSCFG_I2C_FMP_PB8: I2C fast mode plus on PB8 pin
|
||||
\arg SYSCFG_I2C_FMP_PB9: I2C fast mode plus on PB9 pin
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void syscfg_i2c_fast_mode_plus_disable(uint32_t i2c_fmp)
|
||||
{
|
||||
SYSCFG_PMCFG &= (uint32_t)(~i2c_fmp);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief open analog switch (Pxy and Pxy_C are separated pads)
|
||||
\param[in] gpio_answ: GPIO analog switch
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg SYSCFG_PA0_ANALOG_SWITCH: PA0 analog switch
|
||||
\arg SYSCFG_PA1_ANALOG_SWITCH: PA1 analog switch
|
||||
\arg SYSCFG_PC2_ANALOG_SWITCH: PC2 analog switch
|
||||
\arg SYSCFG_PC3_ANALOG_SWITCH: PC3 analog switch
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void syscfg_analog_switch_enable(uint32_t gpio_answ)
|
||||
{
|
||||
SYSCFG_PMCFG |= gpio_answ;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief close analog switch (Pxy and Pxy_C are connected through the analog switch)
|
||||
\param[in] gpio_answ: GPIO analog switch
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg SYSCFG_PA0_ANALOG_SWITCH: PA0 analog switch
|
||||
\arg SYSCFG_PA1_ANALOG_SWITCH: PA1 analog switch
|
||||
\arg SYSCFG_PC2_ANALOG_SWITCH: PC2 analog switch
|
||||
\arg SYSCFG_PC3_ANALOG_SWITCH: PC3 analog switch
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void syscfg_analog_switch_disable(uint32_t gpio_answ)
|
||||
{
|
||||
SYSCFG_PMCFG &= (uint32_t)(~gpio_answ);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the PHY interface for the ethernet MAC
|
||||
\param[in] enet_periph: ENETx(x=0,1)
|
||||
\param[in] phy_interface: specifies the media interface mode
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SYSCFG_ENET_PHY_MII: MII mode is selected
|
||||
\arg SYSCFG_ENET_PHY_RMII: RMII mode is selected
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void syscfg_enet_phy_interface_config(uint32_t ethernet, uint32_t phy_interface)
|
||||
{
|
||||
uint32_t reg;
|
||||
/* read the value of SYSCFG_PMCFG register */
|
||||
reg = SYSCFG_PMCFG;
|
||||
/* configure the ENET media interface */
|
||||
if(ENET0 == ethernet) {
|
||||
reg &= ~SYSCFG_PMCFG_ENET0_PHY_SEL;
|
||||
reg |= ENET0_MEDIA_INTERFACE(phy_interface);
|
||||
} else {
|
||||
reg &= ~SYSCFG_PMCFG_ENET1_PHY_SEL;
|
||||
reg |= ENET1_MEDIA_INTERFACE(phy_interface);
|
||||
}
|
||||
SYSCFG_PMCFG = reg;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the GPIO pin as EXTI Line
|
||||
\param[in] exti_port: specify the GPIO port used in EXTI
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXTI_SOURCE_GPIOx(x = A,B,C,D,E,F,G,H,J,K): EXTI GPIO port
|
||||
\param[in] exti_pin: specify the EXTI line
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg EXTI_SOURCE_PINx(GPIOA x = 0..15,GPIOB x = 0..15,GPIOC x = 0..15,GPIOD x = 0..15,GPIOE x = 0..15,
|
||||
GPIOF x = 0..15,GPIOG x = 0..15,GPIOH x = 0..15,GPIOI x = 0..15,GPIOJ x = 8,9,10,11, GPIOK x = 0,1,2,4,5,6): EXTI GPIO pin
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void syscfg_exti_line_config(uint8_t exti_port, uint8_t exti_pin)
|
||||
{
|
||||
uint32_t clear_exti_mask = ~((uint32_t)EXTI_SS_MASK << (EXTI_SS_MSTEP(exti_pin)));
|
||||
uint32_t config_exti_mask = ((uint32_t)exti_port) << (EXTI_SS_MSTEP(exti_pin));
|
||||
|
||||
switch(exti_pin / EXTI_SS_JSTEP) {
|
||||
case EXTISS0:
|
||||
/* clear EXTI source line(0..3) */
|
||||
SYSCFG_EXTISS0 &= clear_exti_mask;
|
||||
/* configure EXTI soure line(0..3) */
|
||||
SYSCFG_EXTISS0 |= config_exti_mask;
|
||||
break;
|
||||
case EXTISS1:
|
||||
/* clear EXTI soure line(4..7) */
|
||||
SYSCFG_EXTISS1 &= clear_exti_mask;
|
||||
/* configure EXTI soure line(4..7) */
|
||||
SYSCFG_EXTISS1 |= config_exti_mask;
|
||||
break;
|
||||
case EXTISS2:
|
||||
/* clear EXTI soure line(8..11) */
|
||||
SYSCFG_EXTISS2 &= clear_exti_mask;
|
||||
/* configure EXTI soure line(8..11) */
|
||||
SYSCFG_EXTISS2 |= config_exti_mask;
|
||||
break;
|
||||
case EXTISS3:
|
||||
/* clear EXTI soure line(12..15) */
|
||||
SYSCFG_EXTISS3 &= clear_exti_mask;
|
||||
/* configure EXTI soure line(12..15) */
|
||||
SYSCFG_EXTISS3 |= config_exti_mask;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable module lockup function (function can be disabled by system reset)
|
||||
\param[in] lockup:
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg SYSCFG_LVD_LOCKUP: LVD signal
|
||||
\arg SYSCFG_CPU_LOCKUP: CPU lockup signal
|
||||
\arg SYSCFG_BKPRAM_LOCKUP: Region 2 backup SRAM ECC double error signal
|
||||
\arg SYSCFG_SRAM1_LOCKUP: Region 1 SRAM1 ECC double error signal
|
||||
\arg SYSCFG_SRAM0_LOCKUP: Region 1 SRAM0 ECC double error signal
|
||||
\arg SYSCFG_DTCM_LOCKUP: Region 0 DTCM ECC double error signal
|
||||
\arg SYSCFG_ITCM_LOCKUP: Region 0 ITCM-RAM ECC double error signal
|
||||
\arg SYSCFG_AXIRAM_LOCKUP: Region 0 AXI-SRAM ECC double error signal
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void syscfg_lockup_enable(uint32_t lockup)
|
||||
{
|
||||
SYSCFG_LKCTL |= lockup;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief select timer channel input source
|
||||
\param[in] timer_input: TIMER channel input select, refer to timer_channel_input_enum
|
||||
\arg TIMER7_CI0_INPUT_TIMER7_CH0: select CMP1 output as TIMER7 CI0
|
||||
\arg TIMER7_CI0_INPUT_CMP1_OUT: select TIMER7 CH0 as TIMER7 CI0
|
||||
\arg TIMER7_CI1_INPUT_TIMER7_CH1: select TIMER7 CH1 as TIMER7 CI1
|
||||
\arg TIMER7_CI2_INPUT_TIMER7_CH2: select TIMER7 CH2 as TIMER7 CI2
|
||||
\arg TIMER7_CI3_INPUT_TIMER7_CH3: select TIMER7 CH3 as TIMER7 CI3
|
||||
\arg TIMER0_CI0_INPUT_TIMER0_CH0: select CMP0 output as TIMER0 CI0
|
||||
\arg TIMER0_CI0_INPUT_CMP0_OUT: select TIMER0 CH0 as TIMER0 CI0
|
||||
\arg TIMER0_CI1_INPUT_TIMER0_CH1: select TIMER0 CH1 as TIMER0 CI1
|
||||
\arg TIMER0_CI2_INPUT_TIMER0_CH2: select TIMER0 CH2 as TIMER0 CI2
|
||||
\arg TIMER0_CI3_INPUT_TIMER0_CH3: select TIMER0 CH3 as TIMER0 CI3
|
||||
\arg TIMER2_CI0_INPUT_TIMER2_CH0: select TIMER2 CH0 as TIMER2 CI0
|
||||
\arg TIMER2_CI0_INPUT_CMP0_OUT: select CMP0 as TIMER2 CI0
|
||||
\arg TIMER2_CI0_INPUT_CMP1_OUT: select CMP1 as TIMER2 CI0
|
||||
\arg TIMER2_CI0_INPUT_CMP0_OR_CMP1_OUT: select CMP0 or CMP1 as TIMER2 CI0
|
||||
\arg TIMER2_CI1_INPUT_TIMER2_CH1: select TIMER2 CH1 as TIMER2 CI1
|
||||
\arg TIMER2_CI2_INPUT_TIMER2_CH2: select TIMER2 CH2 as TIMER2 CI2
|
||||
\arg TIMER2_CI3_INPUT_TIMER2_CH3: select TIMER2 CH3 as TIMER2 CI3
|
||||
\arg TIMER1_CI0_INPUT_TIMER1_CH0: select TIMER1 CH0 as TIMER1 CI0
|
||||
\arg TIMER1_CI1_INPUT_TIMER1_CH1: select TIMER1 CH1 as TIMER1 CI1
|
||||
\arg TIMER1_CI2_INPUT_TIMER1_CH2: select TIMER1 CH2 as TIMER1 CI2
|
||||
\arg TIMER1_CI3_INPUT_TIMER1_CH3: select TIMER1 CH3 as TIMER1 CI3
|
||||
\arg TIMER1_CI3_INPUT_CMP0_OUT: select CMP0 output as TIMER1 CI3
|
||||
\arg TIMER1_CI3_INPUT_CMP1_OUT: select CMP1 output as TIMER1 CI3
|
||||
\arg TIMER1_CI3_INPUT_CMP0_OR_CMP1_OUT: select CMP0 or CMP1 output as TIMER1 CI3
|
||||
\arg TIMER4_CI0_INPUT_TIMER4_CH0: select TIMER4 CH0 as TIMER4 CI0
|
||||
\arg TIMER4_CI1_INPUT_TIMER4_CH1: select TIMER4 CH1 as TIMER4 CI1
|
||||
\arg TIMER4_CI2_INPUT_TIMER4_CH2: select TIMER4 CH2 as TIMER4 CI2
|
||||
\arg TIMER4_CI3_INPUT_TIMER4_CH3: select TIMER4 CH3 as TIMER4 CI3
|
||||
\arg TIMER3_CI0_INPUT_TIMER3_CH0: select TIMER3 CH0 as TIMER3 CI0
|
||||
\arg TIMER3_CI1_INPUT_TIMER3_CH1: select TIMER3 CH1 as TIMER3 CI1
|
||||
\arg TIMER3_CI2_INPUT_TIMER3_CH2: select TIMER3 CH2 as TIMER3 CI2
|
||||
\arg TIMER3_CI3_INPUT_TIMER3_CH3: select TIMER3 CH3 as TIMER3 CI3
|
||||
\arg TIMER23_CI0_INPUT_TIMER23_CH0: select TIMER23 CH0 as TIMER23 CI0
|
||||
\arg TIMER23_CI1_INPUT_TIMER23_CH1: select TIMER23 CH1 as TIMER23 CI1
|
||||
\arg TIMER23_CI2_INPUT_TIMER23_CH2: select TIMER23 CH2 as TIMER23 CI2
|
||||
\arg TIMER23_CI3_INPUT_TIMER23_CH3: select TIMER23 CH3 as TIMER23 CI3
|
||||
\arg TIMER22_CI0_INPUT_TIMER22_CH0: select TIMER22 CH0 as TIMER22 CI0
|
||||
\arg TIMER22_CI1_INPUT_TIMER22_CH1: select TIMER22 CH1 as TIMER22 CI1
|
||||
\arg TIMER22_CI2_INPUT_TIMER22_CH2: select TIMER22 CH2 as TIMER22 CI2
|
||||
\arg TIMER22_CI3_INPUT_TIMER22_CH3: select TIMER22 CH3 as TIMER22 CI3
|
||||
\arg TIMER22_CI3_INPUT_CMP0_OUT: select CMP0 output as TIMER22 CI3
|
||||
\arg TIMER22_CI3_INPUT_CMP1_OUT: select CMP1 output as TIMER22 CI3
|
||||
\arg TIMER22_CI3_INPUT_CMP0_OR_CMP1_OUT: select CMP0 or CMP1 output as TIMER22 CI3
|
||||
\arg TIMER31_CI0_INPUT_TIMER31_CH0: select TIMER31 CH0 as TIMER31 CI0
|
||||
\arg TIMER31_CI0_INPUT_CMP0_OUT: select CMP0 output as TIMER31 CI0
|
||||
\arg TIMER31_CI0_INPUT_CMP1_OUT: select CMP1 output as TIMER31 CI0
|
||||
\arg TIMER31_CI0_INPUT_CMP0_OR_CMP1_OUT: select CMP0 or CMP1 output as TIMER31 CI0
|
||||
\arg TIMER31_CI1_INPUT_TIMER31_CH1: select TIMER31 CH1 as TIMER31 CI1
|
||||
\arg TIMER31_CI2_INPUT_TIMER31_CH2: select TIMER31 CH2 as TIMER31 CI2
|
||||
\arg TIMER31_CI3_INPUT_TIMER31_CH3: select TIMER31 CH3 as TIMER31 CI3
|
||||
\arg TIMER30_CI0_INPUT_TIMER30_CH0: select TIMER30 CH0 as TIMER30 CI0
|
||||
\arg TIMER30_CI0_INPUT_CMP0_OUT: select CMP0 output as TIMER30 CI0
|
||||
\arg TIMER30_CI0_INPUT_CMP1_OUT: select CMP1 output as TIMER30 CI0
|
||||
\arg TIMER30_CI0_INPUT_CMP0_OR_CMP1_OUT: select CMP0 or CMP1 output as TIMER30 CI0
|
||||
\arg TIMER30_CI1_INPUT_TIMER30_CH1: select TIMER30 CH1 as TIMER30 CI1
|
||||
\arg TIMER30_CI2_INPUT_TIMER30_CH2: select TIMER30 CH2 as TIMER30 CI2
|
||||
\arg TIMER30_CI3_INPUT_TIMER30_CH3: select TIMER30 CH3 as TIMER30 CI3
|
||||
\arg TIMER14_CI0_INPUT_TIMER14_CH0: select TIMER14 CH0 as TIMER14 CI0
|
||||
\arg TIMER14_CI0_INPUT_TIMER1_CH0: select TIMER1 CH0 as TIMER14 CI0
|
||||
\arg TIMER14_CI0_INPUT_TIMER2_CH0: select TIMER2 CH0 as TIMER14 CI0
|
||||
\arg TIMER14_CI0_INPUT_TIMER3_CH0: select TIMER3 CH0 as TIMER14 CI0
|
||||
\arg TIMER14_CI0_INPUT_LXTAL: select LXTAL as TIMER14 CI0
|
||||
\arg TIMER14_CI0_INPUT_LPIRC4M: select LPIRC4M as TIMER14 CI0
|
||||
\arg TIMER14_CI0_INPUT_CKOUT1: select CKOUT1 as TIMER14 CI0
|
||||
\arg TIMER14_CI1_INPUT_TIMER14_CH1: select TIMER14 CH1 as TIMER14 CI1
|
||||
\arg TIMER14_CI1_INPUT_TIMER1_CH1: select TIMER1 CH1 as TIMER14 CI1
|
||||
\arg TIMER14_CI1_INPUT_TIMER2_CH1: select TIMER2 CH1 as TIMER14 CI1
|
||||
\arg TIMER14_CI1_INPUT_TIMER3_CH1: select TIMER3 CH1 as TIMER14 CI1
|
||||
\arg TIMER40_CI0_INPUT_TIMER40_CH0: select TIMER40 CH0 as TIMER40 CI0
|
||||
\arg TIMER40_CI0_INPUT_TIMER2_CH0: select TIMER2 CH0 as TIMER40 CI0
|
||||
\arg TIMER40_CI0_INPUT_TIMER3_CH0: select TIMER3 CH0 as TIMER40 CI0
|
||||
\arg TIMER40_CI0_INPUT_TIMER4_CH0: select TIMER4 CH0 as TIMER40 CI0
|
||||
\arg TIMER40_CI0_INPUT_LXTAL: select LXTAL as TIMER40 CI0
|
||||
\arg TIMER40_CI0_INPUT_LPIRC4M: select LPIRC4M as TIMER40 CI0
|
||||
\arg TIMER40_CI0_INPUT_CKOUT1: select CKOUT1 as TIMER40 CI0
|
||||
\arg TIMER40_CI1_INPUT_TIMER40_CH1: select TIMER40 CH1 as TIMER40 CI0
|
||||
\arg TIMER40_CI1_INPUT_TIMER2_CH1: select TIMER2 CH1 as TIMER40 CI0
|
||||
\arg TIMER40_CI1_INPUT_TIMER3_CH1: select TIMER3 CH1 as TIMER40 CI0
|
||||
\arg TIMER40_CI1_INPUT_TIMER4_CH1: select TIMER4 CH1 as TIMER40 CI0
|
||||
\arg TIMER41_CI0_INPUT_TIMER41_CH0: select TIMER41 CH0 as TIMER41 CI0
|
||||
\arg TIMER41_CI0_INPUT_TIMER3_CH0: select TIMER3 CH0 as TIMER41 CI0
|
||||
\arg TIMER41_CI0_INPUT_TIMER4_CH0: select TIMER4 CH0 as TIMER41 CI0
|
||||
\arg TIMER41_CI0_INPUT_TIMER22_CH0: select TIMER22 CH0 as TIMER41 CI0
|
||||
\arg TIMER41_CI0_INPUT_LXTAL: select LXTAL as TIMER41 CI0
|
||||
\arg TIMER41_CI0_INPUT_LPIRC4M: select LPIRC4M as TIMER41 CI0
|
||||
\arg TIMER41_CI0_INPUT_CKOUT1: select CKOUT1 as TIMER41 CI0
|
||||
\arg TIMER41_CI1_INPUT_TIMER41_CH1: select TIMER41 CH1 as TIMER41 CI1
|
||||
\arg TIMER41_CI1_INPUT_TIMER3_CH1: select TIMER3 CH1 as TIMER41 CI1
|
||||
\arg TIMER41_CI1_INPUT_TIMER4_CH1: select TIMER4 CH1 as TIMER41 CI1
|
||||
\arg TIMER41_CI1_INPUT_TIMER22_CH1: select TIMER22 CH1 as TIMER41 CI1
|
||||
\arg TIMER42_CI0_INPUT_TIMER42_CH0: select TIMER42 CH0 as TIMER42 CI0
|
||||
\arg TIMER42_CI0_INPUT_TIMER4_CH0: select TIMER4 CH0 as TIMER42 CI0
|
||||
\arg TIMER42_CI0_INPUT_TIMER22_CH0: select TIMER22 CH0 as TIMER42 CI0
|
||||
\arg TIMER42_CI0_INPUT_TIMER23_CH0: select TIMER23 CH0 as TIMER42 CI0
|
||||
\arg TIMER42_CI0_INPUT_LXTAL: select LXTAL as TIMER42 CI0
|
||||
\arg TIMER42_CI0_INPUT_LPIRC4M: select LPIRC4M as TIMER42 CI0
|
||||
\arg TIMER42_CI0_INPUT_CKOUT1: select CKOUT1 as TIMER42 CI0
|
||||
\arg TIMER42_CI1_INPUT_TIMER42_CH1: select TIMER42 CH1 as TIMER42 CI1
|
||||
\arg TIMER42_CI1_INPUT_TIMER4_CH1: select TIMER4 CH1 as TIMER42 CI1
|
||||
\arg TIMER42_CI1_INPUT_TIMER22_CH1: select TIMER22 CH1 as TIMER42 CI1
|
||||
\arg TIMER42_CI1_INPUT_TIMER23_CH1: select TIMER23 CH1 as TIMER42 CI1
|
||||
\arg TIMER15_CI0_INPUT_TIMER15_CH0: select TIMER15 CH0 as TIMER15 CI0
|
||||
\arg TIMER15_CI0_INPUT_IRC32K: select IRC32K as TIMER15 CI0
|
||||
\arg TIMER15_CI0_INPUT_LXTAL: select LXTAL as TIMER15 CI0
|
||||
\arg TIMER15_CI0_INPUT_WKUP_IT: select WKUP IT as TIMER15 CI0
|
||||
\arg TIMER16_CI0_INPUT_TIMER16_CH0: select TIMER16 CH0 as TIMER16 CI0
|
||||
\arg TIMER16_CI0_INPUT_RSPDIF: select RSPDIF symbol ck as TIMER16 CI0
|
||||
\arg TIMER16_CI0_INPUT_HXTAL_RTCDIV: select HXTAL/RTCDIV 1M as TIMER16 CI0
|
||||
\arg TIMER16_CI0_INPUT_CKOUT0: select CKOUT0 as TIMER16 CI0
|
||||
\arg TIMER43_CI0_INPUT_TIMER43_CH0: select TIMER43 CH0 as TIMER43 CI0
|
||||
\arg TIMER43_CI0_INPUT_TIMER22_CH0: select TIMER22 CH0 as TIMER43 CI0
|
||||
\arg TIMER43_CI0_INPUT_TIMER23_CH0: select TIMER23 CH0 as TIMER43 CI0
|
||||
\arg TIMER43_CI0_INPUT_TIMER30_CH0: select TIMER30 CH0 as TIMER43 CI0
|
||||
\arg TIMER43_CI0_INPUT_LXTAL: select LXTAL as TIMER43 CI0
|
||||
\arg TIMER43_CI0_INPUT_LPIRC4M: select LPIRC4M as TIMER43 CI0
|
||||
\arg TIMER43_CI0_INPUT_CKOUT1: select CKOUT1 as TIMER43 CI0
|
||||
\arg TIMER43_CI1_INPUT_TIMER43_CH1: select TIMER43 CH1 as TIMER43 CI1
|
||||
\arg TIMER43_CI1_INPUT_TIMER22_CH1: select TIMER22 CH1 as TIMER43 CI1
|
||||
\arg TIMER43_CI1_INPUT_TIMER23_CH1: select TIMER23 CH1 as TIMER43 CI1
|
||||
\arg TIMER43_CI1_INPUT_TIMER30_CH1: select TIMER30 CH1 as TIMER43 CI1
|
||||
\arg TIMER44_CI0_INPUT_TIMER44_CH0: select TIMER44 CH0 as TIMER44 CI0
|
||||
\arg TIMER44_CI0_INPUT_TIMER23_CH0: select TIMER23 CH0 as TIMER44 CI0
|
||||
\arg TIMER44_CI0_INPUT_TIMER30_CH0: select TIMER30 CH0 as TIMER44 CI0
|
||||
\arg TIMER44_CI0_INPUT_TIMER31_CH0: select TIMER31 CH0 as TIMER44 CI0
|
||||
\arg TIMER44_CI0_INPUT_LXTAL: select LXTAL as TIMER44 CI0
|
||||
\arg TIMER44_CI0_INPUT_LPIRC4M: select LPIRC4M as TIMER44 CI0
|
||||
\arg TIMER44_CI0_INPUT_CKOUT1: select CKOUT1 as TIMER44 CI0
|
||||
\arg TIMER44_CI1_INPUT_TIMER44_CH1: select TIMER44 CH1 as TIMER44 CI1
|
||||
\arg TIMER44_CI1_INPUT_TIMER23_CH1: select TIMER23 CH1 as TIMER44 CI1
|
||||
\arg TIMER44_CI1_INPUT_TIMER30_CH1: select TIMER30 CH1 as TIMER44 CI1
|
||||
\arg TIMER44_CI1_INPUT_TIMER31_CH1: select TIMER31 CH1 as TIMER44 CI1
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void syscfg_timer_input_source_select(timer_channel_input_enum timer_input)
|
||||
{
|
||||
uint32_t clear_timer_mask = ~((uint32_t)TIMER_IS_MASK << (TIMER_BIT_POS(timer_input)));
|
||||
uint32_t config_timer_mask = (TIMER_SEL_VAL(timer_input) << TIMER_BIT_POS(timer_input));
|
||||
|
||||
switch(TIMER_REG_INDEX(timer_input)) {
|
||||
case TIMERCISEL0:
|
||||
/* clear TIMER channel input select */
|
||||
SYSCFG_TIMERCISEL0 &= clear_timer_mask;
|
||||
/* config TIMER channel input */
|
||||
SYSCFG_TIMERCISEL0 |= config_timer_mask;
|
||||
break;
|
||||
case TIMERCISEL1:
|
||||
/* clear TIMER channel input select */
|
||||
SYSCFG_TIMERCISEL1 &= clear_timer_mask;
|
||||
/* config TIMER channel input */
|
||||
SYSCFG_TIMERCISEL1 |= config_timer_mask;
|
||||
break;
|
||||
case TIMERCISEL2:
|
||||
/* clear TIMER channel input select */
|
||||
SYSCFG_TIMERCISEL2 &= clear_timer_mask;
|
||||
/* config TIMER channel input */
|
||||
SYSCFG_TIMERCISEL2 |= config_timer_mask;
|
||||
break;
|
||||
case TIMERCISEL3:
|
||||
/* clear TIMER channel input select */
|
||||
SYSCFG_TIMERCISEL3 &= clear_timer_mask;
|
||||
/* config TIMER channel input */
|
||||
SYSCFG_TIMERCISEL3 |= config_timer_mask;
|
||||
break;
|
||||
case TIMERCISEL4:
|
||||
/* clear TIMER channel input select */
|
||||
SYSCFG_TIMERCISEL4 &= clear_timer_mask;
|
||||
/* config TIMER channel input */
|
||||
SYSCFG_TIMERCISEL4 |= config_timer_mask;
|
||||
break;
|
||||
case TIMERCISEL5:
|
||||
/* clear TIMER channel input select */
|
||||
SYSCFG_TIMERCISEL5 &= clear_timer_mask;
|
||||
/* config TIMER channel input */
|
||||
SYSCFG_TIMERCISEL5 |= config_timer_mask;
|
||||
break;
|
||||
case TIMERCISEL6:
|
||||
/* clear TIMER channel input select */
|
||||
SYSCFG_TIMERCISEL6 &= clear_timer_mask;
|
||||
/* config TIMER channel input */
|
||||
SYSCFG_TIMERCISEL6 |= config_timer_mask;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the I/O compensation cell
|
||||
\param[in] syscfg_cps: specifies the I/O compensation cell mode
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SYSCFG_IO_COMPENSATION_ENABLE: I/O compensation cell is enabled
|
||||
\arg SYSCFG_IO_COMPENSATION_DISABLE: I/O compensation cell is disabled
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void syscfg_io_compensation_config(uint32_t syscfg_cps)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
reg = SYSCFG_CPSCTL;
|
||||
/* reset the SYSCFG_CPSCTL_CPS_EN bit and set according to syscfg_compensation */
|
||||
reg &= ~SYSCFG_CPSCTL_CPS_EN;
|
||||
SYSCFG_CPSCTL = (reg | syscfg_cps);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable I/O speed optimization, high-speed at low-voltage
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void syscfg_io_low_voltage_speed_optimization_enable(void)
|
||||
{
|
||||
SYSCFG_CPSCTL |= SYSCFG_CPSCTL_IOSPDOP;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable I/O speed optimization, high-speed at low-voltage
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void syscfg_io_low_voltage_speed_optimization_disable(void)
|
||||
{
|
||||
SYSCFG_CPSCTL &= ~SYSCFG_CPSCTL_IOSPDOP;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set P/N MOS compensation value
|
||||
\param[in] mos
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg NMOS_COMPENSATION: NMOS
|
||||
\arg PMOS_COMPENSATION: PMOS
|
||||
\param[in] code: P/N MOS compensation value
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void syscfg_pnmos_compensation_code_set(uint32_t mos, uint32_t code)
|
||||
{
|
||||
uint32_t value;
|
||||
value = SYSCFG_CPSCCCFG;
|
||||
if(NMOS_COMPENSATION == mos) {
|
||||
value &= ~SYSCFG_CPSCCCFG_NCPSCC;
|
||||
value |= (code & 0x0FU);
|
||||
} else {
|
||||
value &= ~SYSCFG_CPSCCCFG_PCPSCC;
|
||||
value |= ((code & 0x0FU) << 4U);
|
||||
}
|
||||
SYSCFG_CPSCCCFG = value;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set secure SRAM size
|
||||
\param[in] SRAM size
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SECURE_SRAM_SIZE_0KB: secure SRAM size is 0KB
|
||||
\arg SECURE_SRAM_SIZE_32KB: secure SRAM size is 32KB
|
||||
\arg SECURE_SRAM_SIZE_64KB: secure SRAM size is 64KB
|
||||
\arg SECURE_SRAM_SIZE_128KB: secure SRAM size is 128KB
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void syscfg_secure_sram_size_set(uint32_t size)
|
||||
{
|
||||
SYSCFG_SRAMCFG0 &= (uint32_t)(~SYSCFG_SRAMCFG0_SECURE_SRAM_SIZE);
|
||||
SYSCFG_SRAMCFG0 |= size;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get secure SRAM size
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval SRAM size
|
||||
\arg SECURE_SRAM_SIZE_0KB: secure SRAM size is 0KB
|
||||
\arg SECURE_SRAM_SIZE_32KB: secure SRAM size is 32KB
|
||||
\arg SECURE_SRAM_SIZE_64KB: secure SRAM size is 64KB
|
||||
\arg SECURE_SRAM_SIZE_128KB: secure SRAM size is 128KB
|
||||
*/
|
||||
uint32_t syscfg_secure_sram_size_get(void)
|
||||
{
|
||||
return (SYSCFG_SRAMCFG0 & SYSCFG_SRAMCFG0_SECURE_SRAM_SIZE);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get BOOT mode
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval boot mode
|
||||
\arg BOOT_SRAM: BOOT from SRAM (ITCM/DTCM/RAM shared/AXI SRAM)
|
||||
\arg BOOT_SECURITY: BOOT from Security
|
||||
\arg BOOT_SYSTEM: BOOT_SYS (BootLoader)
|
||||
\arg BOOT_USER_FLASH: BOOT_USER (User flash OSPI0/1)
|
||||
*/
|
||||
uint32_t syscfg_bootmode_get(void)
|
||||
{
|
||||
return ((SYSCFG_USERCFG & SYSCFG_USERCFG_BOOT_MODE) >> 4U);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable TCM wait state
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void syscfg_tcm_wait_state_enable(void)
|
||||
{
|
||||
SYSCFG_SRAMCFG1 |= SYSCFG_SRAMCFG1_TCM_WAITSTATE;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable TCM wait state
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void syscfg_tcm_wait_state_disable(void)
|
||||
{
|
||||
SYSCFG_SRAMCFG1 &= ~SYSCFG_SRAMCFG1_TCM_WAITSTATE;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable FPU interrupt
|
||||
\param[in] fpu_int: FPU interrupt
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg SYSCFG_FPUINT_INEXACT: inexact interrupt
|
||||
\arg SYSCFG_FPUINT_INPUT_ABNORMAL: input abnormal interrupt
|
||||
\arg SYSCFG_FPUINT_OVERFLOW: overflow interrupt
|
||||
\arg SYSCFG_FPUINT_UNDERFLOW: underflow interrupt
|
||||
\arg SYSCFG_FPUINT_DIV0: divide-by-zero interrupt
|
||||
\arg SYSCFG_FPUINT_INVALID_OPERATION: invalid operation interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void syscfg_fpu_interrupt_enable(uint32_t fpu_int)
|
||||
{
|
||||
SYSCFG_FPUINTEN |= fpu_int;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable FPU interrupt
|
||||
\param[in] fpu_int: FPU interrupt
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg SYSCFG_FPUINT_INEXACT: inexact interrupt
|
||||
\arg SYSCFG_FPUINT_INPUT_ABNORMAL: input abnormal interrupt
|
||||
\arg SYSCFG_FPUINT_OVERFLOW: overflow interrupt
|
||||
\arg SYSCFG_FPUINT_UNDERFLOW: underflow interrupt
|
||||
\arg SYSCFG_FPUINT_DIV0: divide-by-zero interrupt
|
||||
\arg SYSCFG_FPUINT_INVALID_OPERATION: invalid operation interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void syscfg_fpu_interrupt_disable(uint32_t fpu_int)
|
||||
{
|
||||
SYSCFG_FPUINTEN &= (uint32_t)(~fpu_int);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get compensation cell flags
|
||||
\param[in] cps_flag: compensation flag
|
||||
\arg SYSCFG_FLAG_IO_LOW_VOLTAGE: I/O in low voltage state flag, product supply voltage is working below 2.5V
|
||||
\arg SYSCFG_FLAG_COMPENSATION_READY: I/O compensation cell ready flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus syscfg_compensation_flag_get(uint32_t cps_flag)
|
||||
{
|
||||
if(SYSCFG_CPSCTL & cps_flag) {
|
||||
return SET;
|
||||
} else {
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the ICACHE or DCACHE detection and error information
|
||||
\param[in] cache:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg ICACHE_STATUS: select ICACHE
|
||||
\arg DCACHE_STATUS: select DCACHE
|
||||
\param[in] status:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CPU_CACHE_ERROR_DETECTION: select detection information
|
||||
\arg CPU_CACHE_ERROR_BANK: select error information
|
||||
\param[out] none
|
||||
\retval value
|
||||
*/
|
||||
uint32_t syscfg_cpu_cache_status_get(uint32_t cache, uint32_t status)
|
||||
{
|
||||
uint32_t value = 0U;
|
||||
switch(cache) {
|
||||
/* get ICACHE information */
|
||||
case ICACHE_STATUS:
|
||||
if(CPU_CACHE_ERROR_DETECTION == status) {
|
||||
/* return detection information */
|
||||
value = (uint32_t)((SYSCFG_CPUICAC & SYSCFG_CPUICAC_CPU_ICDET) >> 28U);
|
||||
} else {
|
||||
/* return error bank information */
|
||||
value = (uint32_t)((SYSCFG_CPUICAC & SYSCFG_CPUICAC_CPU_ICERR) >> 6U);
|
||||
}
|
||||
break;
|
||||
/* get DCACHE information */
|
||||
case DCACHE_STATUS:
|
||||
if(CPU_CACHE_ERROR_DETECTION == status) {
|
||||
/* return detection information */
|
||||
value = (uint32_t)((SYSCFG_CPUDCAC & SYSCFG_CPUICAC_CPU_ICDET) >> 28U);
|
||||
} else {
|
||||
/* return error bank information */
|
||||
value = (uint32_t)((SYSCFG_CPUDCAC & SYSCFG_CPUICAC_CPU_ICERR) >> 6U);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get brownout reset threshold level
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval BOR level
|
||||
\arg BOR_OFF: no BOR function
|
||||
\arg BOR_THRESHOLD_VAL1: BOR threshold value 1
|
||||
\arg BOR_THRESHOLD_VAL2: BOR threshold value 2
|
||||
\arg BOR_THRESHOLD_VAL3: BOR threshold value 3
|
||||
*/
|
||||
uint32_t syscfg_brownout_reset_threshold_level_get(void)
|
||||
{
|
||||
return (SYSCFG_USERCFG & SYSCFG_USERCFG_BOR_TH);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,598 @@
|
||||
/*!
|
||||
\file gd32h7xx_tli.c
|
||||
\brief TLI driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_tli.h"
|
||||
|
||||
/* TLI default value */
|
||||
#define TLI_DEFAULT_VALUE 0x00000000U
|
||||
#define TLI_OPAQUE_VALUE 0x000000FFU
|
||||
|
||||
/*!
|
||||
\brief deinitialize TLI registers
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tli_deinit(void)
|
||||
{
|
||||
rcu_periph_reset_enable(RCU_TLIRST);
|
||||
rcu_periph_reset_disable(RCU_TLIRST);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the parameters of TLI parameter structure with the default values, it is suggested
|
||||
that call this function after a tli_parameter_struct structure is defined
|
||||
\param[in] none
|
||||
\param[out] tli_struct: the data needed to initialize TLI
|
||||
synpsz_vpsz: size of the vertical synchronous pulse
|
||||
synpsz_hpsz: size of the horizontal synchronous pulse
|
||||
backpsz_vbpsz: size of the vertical back porch plus synchronous pulse
|
||||
backpsz_hbpsz: size of the horizontal back porch plus synchronous pulse
|
||||
activesz_vasz: size of the vertical active area width plus back porch and synchronous pulse
|
||||
activesz_hasz: size of the horizontal active area width plus back porch and synchronous pulse
|
||||
totalsz_vtsz: vertical total size of the display, including active area, back porch, synchronous
|
||||
totalsz_htsz: vorizontal total size of the display, including active area, back porch, synchronous
|
||||
backcolor_red: background value red
|
||||
backcolor_green: background value green
|
||||
backcolor_blue: background value blue
|
||||
signalpolarity_hs: TLI_HSYN_ACTLIVE_LOW,TLI_HSYN_ACTLIVE_HIGH
|
||||
signalpolarity_vs: TLI_VSYN_ACTLIVE_LOW,TLI_VSYN_ACTLIVE_HIGH
|
||||
signalpolarity_de: TLI_DE_ACTLIVE_LOW,TLI_DE_ACTLIVE_HIGHT
|
||||
signalpolarity_pixelck: TLI_PIXEL_CLOCK_TLI,TLI_PIXEL_CLOCK_INVERTEDTLI
|
||||
\retval none
|
||||
*/
|
||||
void tli_struct_para_init(tli_parameter_struct *tli_struct)
|
||||
{
|
||||
/* initialize the struct parameters with default values */
|
||||
tli_struct->synpsz_vpsz = TLI_DEFAULT_VALUE;
|
||||
tli_struct->synpsz_hpsz = TLI_DEFAULT_VALUE;
|
||||
tli_struct->backpsz_vbpsz = TLI_DEFAULT_VALUE;
|
||||
tli_struct->backpsz_hbpsz = TLI_DEFAULT_VALUE;
|
||||
tli_struct->activesz_vasz = TLI_DEFAULT_VALUE;
|
||||
tli_struct->activesz_hasz = TLI_DEFAULT_VALUE;
|
||||
tli_struct->totalsz_vtsz = TLI_DEFAULT_VALUE;
|
||||
tli_struct->totalsz_htsz = TLI_DEFAULT_VALUE;
|
||||
tli_struct->backcolor_red = TLI_DEFAULT_VALUE;
|
||||
tli_struct->backcolor_green = TLI_DEFAULT_VALUE;
|
||||
tli_struct->backcolor_blue = TLI_DEFAULT_VALUE;
|
||||
tli_struct->signalpolarity_hs = TLI_HSYN_ACTLIVE_LOW;
|
||||
tli_struct->signalpolarity_vs = TLI_VSYN_ACTLIVE_LOW;
|
||||
tli_struct->signalpolarity_de = TLI_DE_ACTLIVE_LOW;
|
||||
tli_struct->signalpolarity_pixelck = TLI_PIXEL_CLOCK_TLI;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize TLI display timing parameters
|
||||
\param[in] tli_struct: the data needed to initialize TLI
|
||||
synpsz_vpsz: size of the vertical synchronous pulse
|
||||
synpsz_hpsz: size of the horizontal synchronous pulse
|
||||
backpsz_vbpsz: size of the vertical back porch plus synchronous pulse
|
||||
backpsz_hbpsz: size of the horizontal back porch plus synchronous pulse
|
||||
activesz_vasz: size of the vertical active area width plus back porch and synchronous pulse
|
||||
activesz_hasz: size of the horizontal active area width plus back porch and synchronous pulse
|
||||
totalsz_vtsz: vertical total size of the display, including active area, back porch, synchronous
|
||||
totalsz_htsz: vorizontal total size of the display, including active area, back porch, synchronous
|
||||
backcolor_red: background value red
|
||||
backcolor_green: background value green
|
||||
backcolor_blue: background value blue
|
||||
signalpolarity_hs: TLI_HSYN_ACTLIVE_LOW,TLI_HSYN_ACTLIVE_HIGH
|
||||
signalpolarity_vs: TLI_VSYN_ACTLIVE_LOW,TLI_VSYN_ACTLIVE_HIGH
|
||||
signalpolarity_de: TLI_DE_ACTLIVE_LOW,TLI_DE_ACTLIVE_HIGH
|
||||
signalpolarity_pixelck: TLI_PIXEL_CLOCK_TLI,TLI_PIXEL_CLOCK_INVERTEDTLI
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tli_init(tli_parameter_struct *tli_struct)
|
||||
{
|
||||
/* synchronous pulse size configuration */
|
||||
TLI_SPSZ &= ~(TLI_SPSZ_VPSZ | TLI_SPSZ_HPSZ);
|
||||
TLI_SPSZ = (uint32_t)((uint32_t)tli_struct->synpsz_vpsz | ((uint32_t)tli_struct->synpsz_hpsz << 16U));
|
||||
/* back-porch size configuration */
|
||||
TLI_BPSZ &= ~(TLI_BPSZ_VBPSZ | TLI_BPSZ_HBPSZ);
|
||||
TLI_BPSZ = (uint32_t)((uint32_t)tli_struct->backpsz_vbpsz | ((uint32_t)tli_struct->backpsz_hbpsz << 16U));
|
||||
/* active size configuration */
|
||||
TLI_ASZ &= ~(TLI_ASZ_VASZ | TLI_ASZ_HASZ);
|
||||
TLI_ASZ = (tli_struct->activesz_vasz | (tli_struct->activesz_hasz << 16U));
|
||||
/* total size configuration */
|
||||
TLI_TSZ &= ~(TLI_TSZ_VTSZ | TLI_TSZ_HTSZ);
|
||||
TLI_TSZ = (tli_struct->totalsz_vtsz | (tli_struct->totalsz_htsz << 16U));
|
||||
/* background color configuration */
|
||||
TLI_BGC &= ~(TLI_BGC_BVB | (TLI_BGC_BVG) | (TLI_BGC_BVR));
|
||||
TLI_BGC = (tli_struct->backcolor_blue | (tli_struct->backcolor_green << 8U) | (tli_struct->backcolor_red << 16U));
|
||||
TLI_CTL &= ~(TLI_CTL_HPPS|TLI_CTL_VPPS | TLI_CTL_DEPS|TLI_CTL_CLKPS);
|
||||
TLI_CTL |= (tli_struct->signalpolarity_hs | tli_struct->signalpolarity_vs | \
|
||||
tli_struct->signalpolarity_de | tli_struct->signalpolarity_pixelck);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure TLI dither function
|
||||
\param[in] dither_stat
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg TLI_DITHER_ENABLE
|
||||
\arg TLI_DITHER_DISABLE
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tli_dither_config(uint8_t dither_stat)
|
||||
{
|
||||
if(TLI_DITHER_ENABLE == dither_stat){
|
||||
TLI_CTL |= TLI_CTL_DFEN;
|
||||
} else {
|
||||
TLI_CTL &= ~(TLI_CTL_DFEN);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable TLI
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tli_enable(void)
|
||||
{
|
||||
TLI_CTL |= TLI_CTL_TLIEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable TLI
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tli_disable(void)
|
||||
{
|
||||
TLI_CTL &= ~(TLI_CTL_TLIEN);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure TLI reload mode
|
||||
\param[in] reload_mod
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg TLI_FRAME_BLANK_RELOAD_EN
|
||||
\arg TLI_REQUEST_RELOAD_EN
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tli_reload_config(uint8_t reload_mod)
|
||||
{
|
||||
if(TLI_FRAME_BLANK_RELOAD_EN == reload_mod){
|
||||
/* the layer configuration will be reloaded at frame blank */
|
||||
TLI_RL |= TLI_RL_FBR;
|
||||
} else {
|
||||
/* the layer configuration will be reloaded after this bit sets */
|
||||
TLI_RL |= TLI_RL_RQR;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the parameters of TLI layer structure with the default values, it is suggested
|
||||
that call this function after a tli_layer_parameter_struct structure is defined
|
||||
\param[in] none
|
||||
\param[out] layer_struct: TLI Layer parameter struct
|
||||
layer_window_rightpos: window right position
|
||||
layer_window_leftpos: window left position
|
||||
layer_window_bottompos: window bottom position
|
||||
layer_window_toppos: window top position
|
||||
layer_ppf: LAYER_PPF_ARGB8888,LAYER_PPF_RGB888,LAYER_PPF_RGB565,
|
||||
LAYER_PPF_ARG1555,LAYER_PPF_ARGB4444,LAYER_PPF_L8,
|
||||
LAYER_PPF_AL44,LAYER_PPF_AL88
|
||||
layer_sa: specified alpha
|
||||
layer_default_alpha: the default color alpha
|
||||
layer_default_red: the default color red
|
||||
layer_default_green: the default color green
|
||||
layer_default_blue: the default color blue
|
||||
layer_acf1: LAYER_ACF1_SA,LAYER_ACF1_PASA
|
||||
layer_acf2: LAYER_ACF2_SA,LAYER_ACF2_PASA
|
||||
layer_frame_bufaddr: frame buffer base address
|
||||
layer_frame_buf_stride_offset: frame buffer stride offset
|
||||
layer_frame_line_length: frame line length
|
||||
layer_frame_total_line_number: frame total line number
|
||||
\retval none
|
||||
*/
|
||||
void tli_layer_struct_para_init(tli_layer_parameter_struct *layer_struct)
|
||||
{
|
||||
/* initialize the struct parameters with default values */
|
||||
layer_struct->layer_window_rightpos = TLI_DEFAULT_VALUE;
|
||||
layer_struct->layer_window_leftpos = TLI_DEFAULT_VALUE;
|
||||
layer_struct->layer_window_bottompos = TLI_DEFAULT_VALUE;
|
||||
layer_struct->layer_window_toppos = TLI_DEFAULT_VALUE;
|
||||
layer_struct->layer_ppf = LAYER_PPF_ARGB8888;
|
||||
layer_struct->layer_sa = TLI_OPAQUE_VALUE;
|
||||
layer_struct->layer_default_alpha = TLI_DEFAULT_VALUE;
|
||||
layer_struct->layer_default_red = TLI_DEFAULT_VALUE;
|
||||
layer_struct->layer_default_green = TLI_DEFAULT_VALUE;
|
||||
layer_struct->layer_default_blue = TLI_DEFAULT_VALUE;
|
||||
layer_struct->layer_acf1 = LAYER_ACF1_PASA;
|
||||
layer_struct->layer_acf2 = LAYER_ACF2_PASA;
|
||||
layer_struct->layer_frame_bufaddr = TLI_DEFAULT_VALUE;
|
||||
layer_struct->layer_frame_buf_stride_offset = TLI_DEFAULT_VALUE;
|
||||
layer_struct->layer_frame_line_length = TLI_DEFAULT_VALUE;
|
||||
layer_struct->layer_frame_total_line_number = TLI_DEFAULT_VALUE;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize TLI layer
|
||||
\param[in] layerx: LAYERx(x=0,1)
|
||||
\param[in] layer_struct: TLI Layer parameter struct
|
||||
layer_window_rightpos: window right position
|
||||
layer_window_leftpos: window left position
|
||||
layer_window_bottompos: window bottom position
|
||||
layer_window_toppos: window top position
|
||||
layer_ppf: LAYER_PPF_ARGB8888,LAYER_PPF_RGB888,LAYER_PPF_RGB565,
|
||||
LAYER_PPF_ARG1555,LAYER_PPF_ARGB4444,LAYER_PPF_L8,
|
||||
LAYER_PPF_AL44,LAYER_PPF_AL88
|
||||
layer_sa: specified alpha
|
||||
layer_default_alpha: the default color alpha
|
||||
layer_default_red: the default color red
|
||||
layer_default_green: the default color green
|
||||
layer_default_blue: the default color blue
|
||||
layer_acf1: LAYER_ACF1_SA,LAYER_ACF1_PASA
|
||||
layer_acf2: LAYER_ACF2_SA,LAYER_ACF2_PASA
|
||||
layer_frame_bufaddr: frame buffer base address
|
||||
layer_frame_buf_stride_offset: frame buffer stride offset
|
||||
layer_frame_line_length: frame line length
|
||||
layer_frame_total_line_number: frame total line number
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tli_layer_init(uint32_t layerx,tli_layer_parameter_struct *layer_struct)
|
||||
{
|
||||
/* configure layer window horizontal position */
|
||||
TLI_LXHPOS(layerx) &= ~(TLI_LXHPOS_WLP | (TLI_LXHPOS_WRP));
|
||||
TLI_LXHPOS(layerx) = (uint32_t)((uint32_t)layer_struct->layer_window_leftpos | ((uint32_t)layer_struct->layer_window_rightpos << 16U));
|
||||
/* configure layer window vertical position */
|
||||
TLI_LXVPOS(layerx) &= ~(TLI_LXVPOS_WTP | (TLI_LXVPOS_WBP));
|
||||
TLI_LXVPOS(layerx) = (uint32_t)((uint32_t)layer_struct->layer_window_toppos | ((uint32_t)layer_struct->layer_window_bottompos << 16U));
|
||||
/* configure layer packeted pixel format */
|
||||
TLI_LXPPF(layerx) &= ~(TLI_LXPPF_PPF);
|
||||
TLI_LXPPF(layerx) = layer_struct->layer_ppf;
|
||||
/* configure layer specified alpha */
|
||||
TLI_LXSA(layerx) &= ~(TLI_LXSA_SA);
|
||||
TLI_LXSA(layerx) = layer_struct->layer_sa;
|
||||
/* configure layer default color */
|
||||
TLI_LXDC(layerx) &= ~(TLI_LXDC_DCB | (TLI_LXDC_DCG) | (TLI_LXDC_DCR) | (TLI_LXDC_DCA));
|
||||
TLI_LXDC(layerx) = (uint32_t)((uint32_t)layer_struct->layer_default_blue |
|
||||
((uint32_t)layer_struct->layer_default_green << 8U) |
|
||||
((uint32_t)layer_struct->layer_default_red << 16U) |
|
||||
((uint32_t)layer_struct->layer_default_alpha << 24U));
|
||||
|
||||
/* configure layer alpha calculation factors */
|
||||
TLI_LXBLEND(layerx) &= ~(TLI_LXBLEND_ACF2 | (TLI_LXBLEND_ACF1));
|
||||
TLI_LXBLEND(layerx) = ((layer_struct->layer_acf2) | (layer_struct->layer_acf1));
|
||||
/* configure layer frame buffer base address */
|
||||
TLI_LXFBADDR(layerx) &= ~(TLI_LXFBADDR_FBADD);
|
||||
TLI_LXFBADDR(layerx) = (layer_struct->layer_frame_bufaddr);
|
||||
/* configure layer frame line length */
|
||||
TLI_LXFLLEN(layerx) &= ~(TLI_LXFLLEN_FLL | (TLI_LXFLLEN_STDOFF));
|
||||
TLI_LXFLLEN(layerx) = (uint32_t)((uint32_t)layer_struct->layer_frame_line_length | ((uint32_t)layer_struct->layer_frame_buf_stride_offset << 16U));
|
||||
/* configure layer frame total line number */
|
||||
TLI_LXFTLN(layerx) &= ~(TLI_LXFTLN_FTLN);
|
||||
TLI_LXFTLN(layerx) = (uint32_t)(layer_struct->layer_frame_total_line_number);
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief reconfigure window position
|
||||
\param[in] layerx: LAYERx(x=0,1)
|
||||
\param[in] offset_x: new horizontal offset
|
||||
\param[in] offset_y: new vertical offset
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tli_layer_window_offset_modify(uint32_t layerx,uint16_t offset_x,uint16_t offset_y)
|
||||
{
|
||||
/* configure window start position */
|
||||
uint32_t layer_ppf, line_num, hstart, vstart;
|
||||
uint32_t line_length = 0U;
|
||||
TLI_LXHPOS(layerx) &= ~(TLI_LXHPOS_WLP | (TLI_LXHPOS_WRP));
|
||||
TLI_LXVPOS(layerx) &= ~(TLI_LXVPOS_WTP | (TLI_LXVPOS_WBP));
|
||||
hstart = (uint32_t)offset_x + (((TLI_BPSZ & TLI_BPSZ_HBPSZ) >> 16U) + 1U);
|
||||
vstart = (uint32_t)offset_y + ((TLI_BPSZ & TLI_BPSZ_VBPSZ) + 1U);
|
||||
line_num = (TLI_LXFTLN(layerx) & TLI_LXFTLN_FTLN);
|
||||
layer_ppf = (TLI_LXPPF(layerx) & TLI_LXPPF_PPF);
|
||||
/* the bytes of a line equal TLI_LXFLLEN_FLL bits value minus 3 */
|
||||
switch(layer_ppf){
|
||||
case LAYER_PPF_ARGB8888:
|
||||
/* each pixel includes 4bytes, when pixel format is ARGB8888 */
|
||||
line_length = (((TLI_LXFLLEN(layerx) & TLI_LXFLLEN_FLL) -3U) / 4U);
|
||||
break;
|
||||
case LAYER_PPF_RGB888:
|
||||
/* each pixel includes 3bytes, when pixel format is RGB888 */
|
||||
line_length = (((TLI_LXFLLEN(layerx) & TLI_LXFLLEN_FLL) - 3U) / 3U);
|
||||
break;
|
||||
case LAYER_PPF_RGB565:
|
||||
case LAYER_PPF_ARGB1555:
|
||||
case LAYER_PPF_ARGB4444:
|
||||
case LAYER_PPF_AL88:
|
||||
/* each pixel includes 2bytes, when pixel format is RGB565,ARG1555,ARGB4444 or AL88 */
|
||||
line_length = (((TLI_LXFLLEN(layerx) & TLI_LXFLLEN_FLL) - 3U) / 2U);
|
||||
break;
|
||||
case LAYER_PPF_L8:
|
||||
case LAYER_PPF_AL44:
|
||||
/* each pixel includes 1byte, when pixel format is L8 or AL44 */
|
||||
line_length = (((TLI_LXFLLEN(layerx) & TLI_LXFLLEN_FLL) - 3U));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* reconfigure window position */
|
||||
TLI_LXHPOS(layerx) = (hstart | ((hstart+line_length - 1U) << 16U));
|
||||
TLI_LXVPOS(layerx) = (vstart | ((vstart+line_num - 1U) << 16U));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the parameters of TLI layer LUT structure with the default values, it is suggested
|
||||
that call this function after a tli_layer_lut_parameter_struct structure is defined
|
||||
\param[in] none
|
||||
\param[out] lut_struct: TLI layer LUT parameter struct
|
||||
layer_table_addr: look up table write address
|
||||
layer_lut_channel_red: red channel of a LUT entry
|
||||
layer_lut_channel_green: green channel of a LUT entry
|
||||
layer_lut_channel_blue: blue channel of a LUT entry
|
||||
\retval none
|
||||
*/
|
||||
void tli_lut_struct_para_init(tli_layer_lut_parameter_struct *lut_struct)
|
||||
{
|
||||
/* initialize the struct parameters with default values */
|
||||
lut_struct->layer_table_addr = TLI_DEFAULT_VALUE;
|
||||
lut_struct->layer_lut_channel_red = TLI_DEFAULT_VALUE;
|
||||
lut_struct->layer_lut_channel_green = TLI_DEFAULT_VALUE;
|
||||
lut_struct->layer_lut_channel_blue = TLI_DEFAULT_VALUE;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize TLI layer LUT
|
||||
\param[in] layerx: LAYERx(x=0,1)
|
||||
\param[in] lut_struct: TLI layer LUT parameter struct
|
||||
layer_table_addr: look up table write address
|
||||
layer_lut_channel_red: red channel of a LUT entry
|
||||
layer_lut_channel_green: green channel of a LUT entry
|
||||
layer_lut_channel_blue: blue channel of a LUT entry
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tli_lut_init(uint32_t layerx,tli_layer_lut_parameter_struct *lut_struct)
|
||||
{
|
||||
TLI_LXLUT(layerx) = (uint32_t)(((uint32_t)lut_struct->layer_lut_channel_blue) |
|
||||
((uint32_t)lut_struct->layer_lut_channel_green << 8U) |
|
||||
((uint32_t)lut_struct->layer_lut_channel_red << 16U) |
|
||||
((uint32_t)lut_struct->layer_table_addr << 24U));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize TLI layer color key
|
||||
\param[in] layerx: LAYERx(x=0,1)
|
||||
\param[in] redkey: color key red
|
||||
\param[in] greenkey: color key green
|
||||
\param[in] bluekey: color key blue
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tli_color_key_init(uint32_t layerx,uint8_t redkey,uint8_t greenkey,uint8_t bluekey)
|
||||
{
|
||||
TLI_LXCKEY(layerx) = (((uint32_t)bluekey) | ((uint32_t)greenkey << 8U) | ((uint32_t)redkey << 16U));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable TLI layer
|
||||
\param[in] layerx: LAYERx(x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tli_layer_enable(uint32_t layerx)
|
||||
{
|
||||
TLI_LXCTL(layerx) |= TLI_LXCTL_LEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable TLI layer
|
||||
\param[in] layerx: LAYERx(x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tli_layer_disable(uint32_t layerx)
|
||||
{
|
||||
TLI_LXCTL(layerx) &= ~(TLI_LXCTL_LEN);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable TLI layer color keying
|
||||
\param[in] layerx: LAYERx(x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tli_color_key_enable(uint32_t layerx)
|
||||
{
|
||||
TLI_LXCTL(layerx) |= TLI_LXCTL_CKEYEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable TLI layer color keying
|
||||
\param[in] layerx: LAYERx(x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tli_color_key_disable(uint32_t layerx)
|
||||
{
|
||||
TLI_LXCTL(layerx) &= ~(TLI_LXCTL_CKEYEN);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable TLI layer LUT
|
||||
\param[in] layerx: LAYERx(x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tli_lut_enable(uint32_t layerx)
|
||||
{
|
||||
TLI_LXCTL(layerx) |= TLI_LXCTL_LUTEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable TLI layer LUT
|
||||
\param[in] layerx: LAYERx(x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tli_lut_disable(uint32_t layerx)
|
||||
{
|
||||
TLI_LXCTL(layerx) &= ~(TLI_LXCTL_LUTEN);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set line mark value
|
||||
\param[in] line_num: line number
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tli_line_mark_set(uint16_t line_num)
|
||||
{
|
||||
TLI_LM &= ~(TLI_LM_LM);
|
||||
TLI_LM = (uint32_t)line_num;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get current displayed position
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval position of current pixel
|
||||
*/
|
||||
uint32_t tli_current_pos_get(void)
|
||||
{
|
||||
return TLI_CPPOS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable TLI interrupt
|
||||
\param[in] int_flag: TLI interrupt flags
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg TLI_INT_LM: line mark interrupt
|
||||
\arg TLI_INT_FE: FIFO error interrupt
|
||||
\arg TLI_INT_TE: transaction error interrupt
|
||||
\arg TLI_INT_LCR: layer configuration reloaded interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tli_interrupt_enable(uint32_t int_flag)
|
||||
{
|
||||
TLI_INTEN |= (int_flag);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable TLI interrupt
|
||||
\param[in] int_flag: TLI interrupt flags
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg TLI_INT_LM: line mark interrupt
|
||||
\arg TLI_INT_FE: FIFO error interrupt
|
||||
\arg TLI_INT_TE: transaction error interrupt
|
||||
\arg TLI_INT_LCR: layer configuration reloaded interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tli_interrupt_disable(uint32_t int_flag)
|
||||
{
|
||||
TLI_INTEN &= ~(int_flag);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get TLI interrupt flag
|
||||
\param[in] int_flag: TLI interrupt flags
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg TLI_INT_FLAG_LM: line mark interrupt flag
|
||||
\arg TLI_INT_FLAG_FE: FIFO error interrupt flag
|
||||
\arg TLI_INT_FLAG_TE: transaction error interrupt flag
|
||||
\arg TLI_INT_FLAG_LCR: layer configuration reloaded interrupt flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus tli_interrupt_flag_get(uint32_t int_flag)
|
||||
{
|
||||
uint32_t state;
|
||||
state = TLI_INTF;
|
||||
if(state & int_flag){
|
||||
state = TLI_INTEN;
|
||||
if(state & int_flag){
|
||||
return SET;
|
||||
}
|
||||
}
|
||||
return RESET;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear TLI interrupt flag
|
||||
\param[in] int_flag: TLI interrupt flags
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg TLI_INT_FLAG_LM: line mark interrupt flag
|
||||
\arg TLI_INT_FLAG_FE: FIFO error interrupt flag
|
||||
\arg TLI_INT_FLAG_TE: transaction error interrupt flag
|
||||
\arg TLI_INT_FLAG_LCR: layer configuration reloaded interrupt flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tli_interrupt_flag_clear(uint32_t int_flag)
|
||||
{
|
||||
TLI_INTC |= (int_flag);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get TLI flag or state in TLI_INTF register or TLI_STAT register
|
||||
\param[in] flag: TLI flags or states
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg TLI_FLAG_VDE: current VDE state
|
||||
\arg TLI_FLAG_HDE: current HDE state
|
||||
\arg TLI_FLAG_VS: current VS status of the TLI
|
||||
\arg TLI_FLAG_HS: current HS status of the TLI
|
||||
\arg TLI_FLAG_LM: line mark interrupt flag
|
||||
\arg TLI_FLAG_FE: FIFO error interrupt flag
|
||||
\arg TLI_FLAG_TE: transaction error interrupt flag
|
||||
\arg TLI_FLAG_LCR: layer configuration reloaded interrupt flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus tli_flag_get(uint32_t flag)
|
||||
{
|
||||
uint32_t stat;
|
||||
/* choose which register to get flag or state */
|
||||
if(flag >> 31U){
|
||||
stat = TLI_INTF;
|
||||
}else{
|
||||
stat = TLI_STAT;
|
||||
}
|
||||
if(flag & stat){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,236 @@
|
||||
/*!
|
||||
\file gd32h7xx_tmu.c
|
||||
\brief TMU driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_tmu.h"
|
||||
|
||||
#define MASK_LOW_HALFWORD ((uint32_t)0xFFFF0000U)
|
||||
#define MASK_HIGH_HALFWORD ((uint32_t)0x0000FFFFU)
|
||||
|
||||
/*!
|
||||
\brief reset the TMU registers
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tmu_deinit(void)
|
||||
{
|
||||
rcu_periph_reset_enable(RCU_TMURST);
|
||||
rcu_periph_reset_disable(RCU_TMURST);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the parameters of TMU struct with the default values
|
||||
\param[in] init_struct: pointer to init parameter struct
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tmu_struct_para_init(tmu_parameter_struct* init_struct)
|
||||
{
|
||||
/* set the struct with the default values */
|
||||
init_struct->mode = TMU_MODE_COS;
|
||||
init_struct->iterations_number = TMU_ITERATION_STEPS_20;
|
||||
init_struct->scale = TMU_SCALING_FACTOR_1;
|
||||
init_struct->dma_read = TMU_READ_DMA_DISABLE;
|
||||
init_struct->dma_write = TMU_WRITE_DMA_DISABLE;
|
||||
init_struct->read_times = TMU_READ_TIMES_1;
|
||||
init_struct->write_times = TMU_WRITE_TIMES_1;
|
||||
init_struct->output_width = TMU_OUTPUT_WIDTH_32;
|
||||
init_struct->input_width = TMU_INPUT_WIDTH_32;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize TMU
|
||||
\param[in] init_struct: pointer to init parameter struct
|
||||
mode: TMU_MODE_COS,TMU_MODE_SIN,TMU_MODE_ATAN2,TMU_MODE_MODULUS,TMU_MODE_ATAN,
|
||||
TMU_MODE_COSH,TMU_MODE_SINH,TMU_MODE_ATANH,TMU_MODE_LN,TMU_MODE_SQRT
|
||||
iterations_number: TMU_ITERATION_STEPS_x(x=4,8,12,..24)
|
||||
scale: TMU_SCALING_FACTOR_x(x=1,2,4,8,16,32,64,128)
|
||||
dma_read: TMU_READ_DMA_DISABLE, TMU_READ_DMA_ENABLE
|
||||
dma_write: TMU_WRITE_DMA_DISABLE, TMU_WRITE_DMA_ENABLE
|
||||
read_times: TMU_READ_TIMES_1, TMU_READ_TIMES_2
|
||||
write_times: TMU_WRITE_TIMES_1, TMU_WRITE_TIMES_2
|
||||
output_width: TMU_OUTPUT_WIDTH_32, TMU_OUTPUT_WIDTH_16
|
||||
input_width: TMU_INPUT_WIDTH_32, TMU_INPUT_WIDTH_16
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tmu_init(tmu_parameter_struct* init_struct)
|
||||
{
|
||||
uint32_t reg = 0U;
|
||||
reg |= ( init_struct->mode | init_struct->iterations_number | init_struct->scale |\
|
||||
init_struct->dma_read | init_struct->dma_write | init_struct->read_times |\
|
||||
init_struct->write_times | init_struct->output_width | init_struct->input_width);
|
||||
TMU_CS = reg;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable TMU read interrupt
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tmu_read_interrupt_enable(void)
|
||||
{
|
||||
TMU_CS |= TMU_CS_RIE;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable TMU read interrupt
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tmu_read_interrupt_disable(void)
|
||||
{
|
||||
TMU_CS &= ~TMU_CS_RIE;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable TMU DMA read request
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tmu_dma_read_enable(void)
|
||||
{
|
||||
TMU_CS |= TMU_CS_RDEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable TMU DMA read request
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tmu_dma_read_disable(void)
|
||||
{
|
||||
TMU_CS &= ~TMU_CS_RDEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable TMU DMA write request
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tmu_dma_write_enable(void)
|
||||
{
|
||||
TMU_CS |= TMU_CS_WDEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable TMU DMA write request
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tmu_dma_write_disable(void)
|
||||
{
|
||||
TMU_CS &= ~TMU_CS_WDEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief write one data in q1.31 format
|
||||
\param[in] data: the first input data only
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tmu_one_q31_write(uint32_t data)
|
||||
{
|
||||
TMU_IDATA = data;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief write two data in q1.31 format
|
||||
\param[in] data1: the first input data
|
||||
\param[in] data2: the second input data
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tmu_two_q31_write(uint32_t data1, uint32_t data2)
|
||||
{
|
||||
TMU_IDATA = data1;
|
||||
TMU_IDATA = data2;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief write two data in q1.15 format
|
||||
\param[in] data1: the first input data
|
||||
\param[in] data2: the second input data (this data is meaningless in mode4 ~ mode9)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tmu_two_q15_write(uint16_t data1, uint16_t data2)
|
||||
{
|
||||
TMU_IDATA = ((((uint32_t)data1) & MASK_HIGH_HALFWORD)| (((uint32_t)data2 << 16U) & MASK_LOW_HALFWORD));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief read one data in q1.31 format
|
||||
\param[in] none
|
||||
\param[out] p: pointer to the first output data only
|
||||
\retval none
|
||||
*/
|
||||
void tmu_one_q31_read(uint32_t* p)
|
||||
{
|
||||
*p = TMU_ODATA;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief read two data in q1.31 format
|
||||
\param[in] none
|
||||
\param[out] p1: pointer to the first output data
|
||||
\param[out] p2: pointer to the second output data
|
||||
\retval none
|
||||
*/
|
||||
void tmu_two_q31_read(uint32_t* p1, uint32_t* p2)
|
||||
{
|
||||
*p1 = TMU_ODATA;
|
||||
*p2 = TMU_ODATA;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief read two data in q1.15 format
|
||||
\param[in] none
|
||||
\param[out] p1: pointer to the first output data
|
||||
\param[out] p2: pointer to the second output data (this data is meaningless in mode4, mode7 ~ mode9)
|
||||
\retval none
|
||||
*/
|
||||
void tmu_two_q15_read(uint16_t* p1, uint16_t* p2)
|
||||
{
|
||||
uint32_t data;
|
||||
data = TMU_ODATA;
|
||||
*p1 = (uint16_t)data;
|
||||
*p2 = (uint16_t)(data >> 16U);
|
||||
}
|
||||
@@ -0,0 +1,513 @@
|
||||
/*!
|
||||
\file gd32h7xx_trigsel.c
|
||||
\brief TRIGSEL driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_trigsel.h"
|
||||
|
||||
/* TRIGSEL target register redefine */
|
||||
#define TRIGSEL_TARGET_REG(target_periph) (REG32(TRIGSEL + ((uint32_t)(target_periph) & BITS(2,31)))) /*!< target peripheral register */
|
||||
#define TRIGSEL_TARGET_PERIPH_SHIFT(target_periph) (((uint32_t)(target_periph) & BITS(0,1)) << 3U) /*!< bit offset in target peripheral register */
|
||||
#define TRIGSEL_TARGET_PERIPH_MASK(target_periph) ((uint32_t)(BITS(0,7) << TRIGSEL_TARGET_PERIPH_SHIFT(target_periph))) /*!< bit mask in target peripheral register */
|
||||
|
||||
/*!
|
||||
\brief deinitialize TRIGSEL
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void trigsel_deinit(void)
|
||||
{
|
||||
rcu_periph_reset_enable(RCU_TRIGSELRST);
|
||||
rcu_periph_reset_disable(RCU_TRIGSELRST);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set the trigger input signal for target peripheral
|
||||
\param[in] target_periph: target peripheral value
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg TRIGSEL_OUTPUT_TRIGSEL_OUT0: output target peripheral TRIGSEL_OUT0 pin
|
||||
\arg TRIGSEL_OUTPUT_TRIGSEL_OUT1: output target peripheral TRIGSEL_OUT1 pin
|
||||
\arg TRIGSEL_OUTPUT_TRIGSEL_OUT2: output target peripheral TRIGSEL_OUT2 pin
|
||||
\arg TRIGSEL_OUTPUT_TRIGSEL_OUT3: output target peripheral TRIGSEL_OUT3 pin
|
||||
\arg TRIGSEL_OUTPUT_TRIGSEL_OUT4: output target peripheral TRIGSEL_OUT4 pin
|
||||
\arg TRIGSEL_OUTPUT_TRIGSEL_OUT5: output target peripheral TRIGSEL_OUT5 pin
|
||||
\arg TRIGSEL_OUTPUT_TRIGSEL_OUT6: output target peripheral TRIGSEL_OUT6 pin
|
||||
\arg TRIGSEL_OUTPUT_TRIGSEL_OUT7: output target peripheral TRIGSEL_OUT7 pin
|
||||
\arg TRIGSEL_OUTPUT_ADC0_REGTRG: output target peripheral ADC0_REGTRG
|
||||
\arg TRIGSEL_OUTPUT_ADC0_INSTRG: output target peripheral ADC0_INSTRG
|
||||
\arg TRIGSEL_OUTPUT_ADC1_REGTRG: output target peripheral ADC1_REGTRG
|
||||
\arg TRIGSEL_OUTPUT_ADC1_INSTRG: output target peripheral ADC1_INSTRG
|
||||
\arg TRIGSEL_OUTPUT_ADC2_REGTRG: output target peripheral ADC2_REGTRG
|
||||
\arg TRIGSEL_OUTPUT_ADC2_INSTRG: output target peripheral ADC2_INSTRG
|
||||
\arg TRIGSEL_OUTPUT_DAC0_OUT0_EXTRG: output target peripheral DAC0_OUT0_EXTRG
|
||||
\arg TRIGSEL_OUTPUT_DAC0_OUT1_EXTRG: output target peripheral DAC0_OUT1_EXTRG
|
||||
\arg TRIGSEL_OUTPUT_TIMER0_BRKIN0: output target peripheral TIMER0_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER0_BRKIN1: output target peripheral TIMER0_BRKIN1
|
||||
\arg TRIGSEL_OUTPUT_TIMER0_BRKIN2: output target peripheral TIMER0_BRKIN2
|
||||
\arg TRIGSEL_OUTPUT_TIMER7_BRKIN0: output target peripheral TIMER7_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER7_BRKIN1: output target peripheral TIMER7_BRKIN1
|
||||
\arg TRIGSEL_OUTPUT_TIMER7_BRKIN2: output target peripheral TIMER7_BRKIN2
|
||||
\arg TRIGSEL_OUTPUT_TIMER14_BRKIN0: output target peripheral TIMER14_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER15_BRKIN0: output target peripheral TIMER15_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER16_BRKIN0: output target peripheral TIMER16_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER40_BRKIN0: output target peripheral TIMER40_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER41_BRKIN0: output target peripheral TIMER41_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER42_BRKIN0: output target peripheral TIMER42_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER43_BRKIN0: output target peripheral TIMER43_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER44_BRKIN0: output target peripheral TIMER44_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_CAN0_EX_TIME_TICK: output target peripheral CAN0_EX_TIME_TICK
|
||||
\arg TRIGSEL_OUTPUT_CAN1_EX_TIME_TICK: output target peripheral CAN1_EX_TIME_TICK
|
||||
\arg TRIGSEL_OUTPUT_CAN2_EX_TIME_TICK: output target peripheral CAN2_EX_TIME_TICK
|
||||
\arg TRIGSEL_OUTPUT_LPDTS_TRG: output target peripheral LPDTS_TRG
|
||||
\arg TRIGSEL_OUTPUT_TIMER0_ETI: output target peripheral TIMER0_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER1_ETI: output target peripheral TIMER1_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER2_ETI: output target peripheral TIMER2_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER3_ETI: output target peripheral TIMER3_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER4_ETI: output target peripheral TIMER4_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER7_ETI: output target peripheral TIMER7_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER22_ETI: output target peripheral TIMER22_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER23_ETI: output target peripheral TIMER23_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER30_ETI: output target peripheral TIMER30_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER31_ETI: output target peripheral TIMER31_ETI
|
||||
\arg TRIGSEL_OUTPUT_EDOUT_TRG: output target peripheral EDOUT_TRG
|
||||
\arg TRIGSEL_OUTPUT_HPDF_ITRG: output target peripheral HPDF_ITR
|
||||
\arg TRIGSEL_OUTPUT_TIMER0_ITI14: output target peripheral TIMER0_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER1_ITI14: output target peripheral TIMER1_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER2_ITI14: output target peripheral TIMER2_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER3_ITI14: output target peripheral TIMER3_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER4_ITI14: output target peripheral TIMER4_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER7_ITI14: output target peripheral TIMER7_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER14_ITI14: output target peripheral TIMER14_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER22_ITI14: output target peripheral TIMER22_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER23_ITI14: output target peripheral TIMER23_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER30_ITI14: output target peripheral TIMER30_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER31_ITI14: output target peripheral TIMER31_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER40_ITI14: output target peripheral TIMER40_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER41_ITI14: output target peripheral TIMER41_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER42_ITI14: output target peripheral TIMER42_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER43_ITI14: output target peripheral TIMER43_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER44_ITI14: output target peripheral TIMER44_ITI14
|
||||
\param[in] trigger_source: trigger source value
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg TRIGSEL_INPUT_0: trigger input source 0
|
||||
\arg TRIGSEL_INPUT_1: trigger input source 1
|
||||
\arg TRIGSEL_INPUT_TRIGSEL_IN0: trigger input source TRIGSEL_IN0 pin
|
||||
\arg TRIGSEL_INPUT_TRIGSEL_IN1: trigger input source TRIGSEL_IN1 pin
|
||||
\arg TRIGSEL_INPUT_TRIGSEL_IN2: trigger input source TRIGSEL_IN2 pin
|
||||
\arg TRIGSEL_INPUT_TRIGSEL_IN3: trigger input source TRIGSEL_IN3 pin
|
||||
\arg TRIGSEL_INPUT_TRIGSEL_IN4: trigger input source TRIGSEL_IN4 pin
|
||||
\arg TRIGSEL_INPUT_TRIGSEL_IN5: trigger input source TRIGSEL_IN5 pin
|
||||
\arg TRIGSEL_INPUT_TRIGSEL_IN6: trigger input source TRIGSEL_IN6 pin
|
||||
\arg TRIGSEL_INPUT_TRIGSEL_IN7: trigger input source TRIGSEL_IN7 pin
|
||||
\arg TRIGSEL_INPUT_TRIGSEL_IN8: trigger input source TRIGSEL_IN8 pin
|
||||
\arg TRIGSEL_INPUT_TRIGSEL_IN9: trigger input source TRIGSEL_IN9 pin
|
||||
\arg TRIGSEL_INPUT_TRIGSEL_IN10: trigger input source TRIGSEL_IN10 pin
|
||||
\arg TRIGSEL_INPUT_TRIGSEL_IN11: trigger input source TRIGSEL_IN11 pin
|
||||
\arg TRIGSEL_INPUT_TRIGSEL_IN12: trigger input source TRIGSEL_IN12 pin
|
||||
\arg TRIGSEL_INPUT_TRIGSEL_IN13: trigger input source TRIGSEL_IN13 pin
|
||||
\arg TRIGSEL_INPUT_LXTAL_TRG: trigger input source LXTAL_TRG
|
||||
\arg TRIGSEL_INPUT_TIMER0_TRGO0: trigger input source TIMER0 TRGO0
|
||||
\arg TRIGSEL_INPUT_TIMER0_TRGO1: trigger input source TIMER0 TRGO1
|
||||
\arg TRIGSEL_INPUT_TIMER0_CH0: trigger input source TIMER0 CH0
|
||||
\arg TRIGSEL_INPUT_TIMER0_CH1: trigger input source TIMER0 CH1
|
||||
\arg TRIGSEL_INPUT_TIMER0_CH2: trigger input source TIMER0 CH2
|
||||
\arg TRIGSEL_INPUT_TIMER0_CH3: trigger input source TIMER0 CH3
|
||||
\arg TRIGSEL_INPUT_TIMER0_MCH0: trigger input source TIMER0 MCH0
|
||||
\arg TRIGSEL_INPUT_TIMER0_MCH1: trigger input source TIMER0 MCH1
|
||||
\arg TRIGSEL_INPUT_TIMER0_MCH2: trigger input source TIMER0 MCH2
|
||||
\arg TRIGSEL_INPUT_TIMER0_MCH3: trigger input source TIMER0 MCH3
|
||||
\arg TRIGSEL_INPUT_TIMER0_BRKIN0: trigger input source TIMER0 BRKIN0
|
||||
\arg TRIGSEL_INPUT_TIMER0_BRKIN1: trigger input source TIMER0 BRKIN1
|
||||
\arg TRIGSEL_INPUT_TIMER0_BRKIN2: trigger input source TIMER0 BRKIN2
|
||||
\arg TRIGSEL_INPUT_TIMER0_ETI: trigger input source TIMER0 ETI
|
||||
\arg TRIGSEL_INPUT_TIMER1_TRGO0: trigger input source TIMER1 TRGO0
|
||||
\arg TRIGSEL_INPUT_TIMER1_CH0: trigger input source TIMER1 CH0
|
||||
\arg TRIGSEL_INPUT_TIMER1_CH1: trigger input source TIMER1 CH1
|
||||
\arg TRIGSEL_INPUT_TIMER1_CH2: trigger input source TIMER1 CH2
|
||||
\arg TRIGSEL_INPUT_TIMER1_CH3: trigger input source TIMER1 CH2
|
||||
\arg TRIGSEL_INPUT_TIMER1_ETI: trigger input source TIMER1 ETI
|
||||
\arg TRIGSEL_INPUT_TIMER2_TRGO0: trigger input source TIMER2 TRGO0
|
||||
\arg TRIGSEL_INPUT_TIMER2_CH0: trigger input source TIMER2 CH0
|
||||
\arg TRIGSEL_INPUT_TIMER2_CH1: trigger input source TIMER2 CH1
|
||||
\arg TRIGSEL_INPUT_TIMER2_CH2: trigger input source TIMER2 CH2
|
||||
\arg TRIGSEL_INPUT_TIMER2_CH3: trigger input source TIMER2 CH3
|
||||
\arg TRIGSEL_INPUT_TIMER2_ETI: trigger input source TIMER2 ETI
|
||||
\arg TRIGSEL_INPUT_TIMER3_TRGO0: trigger input source TIMER3 TRGO0
|
||||
\arg TRIGSEL_INPUT_TIMER3_CH0: trigger input source TIMER3 CH0
|
||||
\arg TRIGSEL_INPUT_TIMER3_CH1: trigger input source TIMER3 CH1
|
||||
\arg TRIGSEL_INPUT_TIMER3_CH2: trigger input source TIMER3 CH2
|
||||
\arg TRIGSEL_INPUT_TIMER3_CH3: trigger input source TIMER3 CH3
|
||||
\arg TRIGSEL_INPUT_TIMER3_ETI: trigger input source TIMER3 ETI
|
||||
\arg TRIGSEL_INPUT_TIMER4_TRGO0: trigger input source TIMER4 TRGO0
|
||||
\arg TRIGSEL_INPUT_TIMER4_CH0: trigger input source TIMER4 CH0
|
||||
\arg TRIGSEL_INPUT_TIMER4_CH1: trigger input source TIMER4 CH1
|
||||
\arg TRIGSEL_INPUT_TIMER4_CH2: trigger input source TIMER4 CH2
|
||||
\arg TRIGSEL_INPUT_TIMER4_CH3: trigger input source TIMER4 CH3
|
||||
\arg TRIGSEL_INPUT_TIMER4_ETI: trigger input source TIMER4 ETI
|
||||
\arg TRIGSEL_INPUT_TIMER5_TRGO0: trigger input source TIMER5 TRGO0
|
||||
\arg TRIGSEL_INPUT_TIMER6_TRGO0: trigger input source TIMER6 TRGO0
|
||||
\arg TRIGSEL_INPUT_TIMER7_TRGO0: trigger input source TIMER7 TRGO0
|
||||
\arg TRIGSEL_INPUT_TIMER7_TRGO1: trigger input source TIMER7 TRGO1
|
||||
\arg TRIGSEL_INPUT_TIMER7_CH0: trigger input source TIMER7 CH0
|
||||
\arg TRIGSEL_INPUT_TIMER7_CH1: trigger input source TIMER7 CH1
|
||||
\arg TRIGSEL_INPUT_TIMER7_CH2: trigger input source TIMER7 CH2
|
||||
\arg TRIGSEL_INPUT_TIMER7_CH3: trigger input source TIMER7 CH3
|
||||
\arg TRIGSEL_INPUT_TIMER7_MCH0: trigger input source TIMER7 MCH0
|
||||
\arg TRIGSEL_INPUT_TIMER7_MCH1: trigger input source TIMER7 MCH1
|
||||
\arg TRIGSEL_INPUT_TIMER7_MCH2: trigger input source TIMER7 MCH2
|
||||
\arg TRIGSEL_INPUT_TIMER7_MCH3: trigger input source TIMER7 MCH3
|
||||
\arg TRIGSEL_INPUT_TIMER7_BRKIN0: trigger input source TIMER7 BRKIN0
|
||||
\arg TRIGSEL_INPUT_TIMER7_BRKIN1: trigger input source TIMER7 BRKIN1
|
||||
\arg TRIGSEL_INPUT_TIMER7_BRKIN2: trigger input source TIMER7 BRKIN2
|
||||
\arg TRIGSEL_INPUT_TIMER7_ETI: trigger input source TIMER7 ETI
|
||||
\arg TRIGSEL_INPUT_TIMER14_TRGO0: trigger input source TIMER14 TRGO0
|
||||
\arg TRIGSEL_INPUT_TIMER14_CH0: trigger input source TIMER14 CH0
|
||||
\arg TRIGSEL_INPUT_TIMER14_CH1: trigger input source TIMER14 CH1
|
||||
\arg TRIGSEL_INPUT_TIMER14_MCH0: trigger input source TIMER14 MCH0
|
||||
\arg TRIGSEL_INPUT_TIMER14_BRKIN0: trigger input source TIMER14 BRKIN0
|
||||
\arg TRIGSEL_INPUT_TIMER15_CH0: trigger input source TIMER15 CH0
|
||||
\arg TRIGSEL_INPUT_TIMER15_MCH0: trigger input source TIMER15 MCH0
|
||||
\arg TRIGSEL_INPUT_TIMER15_BRKIN0: trigger input source TIMER15 BRKIN0
|
||||
\arg TRIGSEL_INPUT_TIMER16_CH0: trigger input source TIMER16 CH0
|
||||
\arg TRIGSEL_INPUT_TIMER16_MCH0: trigger input source TIMER16 MCH0
|
||||
\arg TRIGSEL_INPUT_TIMER16_BRKIN0: trigger input source TIMER16 BRKIN0
|
||||
\arg TRIGSEL_INPUT_TIMER22_TRGO0: trigger input source TIMER22 TRGO0
|
||||
\arg TRIGSEL_INPUT_TIMER22_CH0: trigger input source TIMER22 CH0
|
||||
\arg TRIGSEL_INPUT_TIMER22_CH1: trigger input source TIMER22 CH1
|
||||
\arg TRIGSEL_INPUT_TIMER22_CH2: trigger input source TIMER22 CH2
|
||||
\arg TRIGSEL_INPUT_TIMER22_CH3: trigger input source TIMER22 CH3
|
||||
\arg TRIGSEL_INPUT_TIMER22_ETI: trigger input source TIMER22 ETI
|
||||
\arg TRIGSEL_INPUT_TIMER23_TRGO0: trigger input source TIMER23 TRGO0
|
||||
\arg TRIGSEL_INPUT_TIMER23_CH0: trigger input source TIMER23 CH0
|
||||
\arg TRIGSEL_INPUT_TIMER23_CH1: trigger input source TIMER23 CH1
|
||||
\arg TRIGSEL_INPUT_TIMER23_CH2: trigger input source TIMER23 CH2
|
||||
\arg TRIGSEL_INPUT_TIMER23_CH3: trigger input source TIMER23 CH3
|
||||
\arg TRIGSEL_INPUT_TIMER23_ETI: trigger input source TIMER23 ETI
|
||||
\arg TRIGSEL_INPUT_TIMER30_TRGO0: trigger input source TIMER30 TRGO0
|
||||
\arg TRIGSEL_INPUT_TIMER30_CH0: trigger input source TIMER30 CH0
|
||||
\arg TRIGSEL_INPUT_TIMER30_CH1: trigger input source TIMER30 CH1
|
||||
\arg TRIGSEL_INPUT_TIMER30_CH2: trigger input source TIMER30 CH2
|
||||
\arg TRIGSEL_INPUT_TIMER30_CH3: trigger input source TIMER30 CH3
|
||||
\arg TRIGSEL_INPUT_TIMER30_ETI: trigger input source TIMER30 ETI
|
||||
\arg TRIGSEL_INPUT_TIMER31_TRGO0: trigger input source TIMER31 TRGO0
|
||||
\arg TRIGSEL_INPUT_TIMER31_CH0: trigger input source TIMER31 CH0
|
||||
\arg TRIGSEL_INPUT_TIMER31_CH1: trigger input source TIMER31 CH1
|
||||
\arg TRIGSEL_INPUT_TIMER31_CH2: trigger input source TIMER31 CH2
|
||||
\arg TRIGSEL_INPUT_TIMER31_CH3: trigger input source TIMER31 CH3
|
||||
\arg TRIGSEL_INPUT_TIMER31_ETI: trigger input source TIMER31 ETI
|
||||
\arg TRIGSEL_INPUT_TIMER40_TRGO0: trigger input source TIMER40 TRGO0
|
||||
\arg TRIGSEL_INPUT_TIMER40_CH0: trigger input source TIMER40 CH0
|
||||
\arg TRIGSEL_INPUT_TIMER40_CH1: trigger input source TIMER40 CH1
|
||||
\arg TRIGSEL_INPUT_TIMER40_MCH0: trigger input source TIMER40 MCH0
|
||||
\arg TRIGSEL_INPUT_TIMER40_BRKIN0: trigger input source TIMER40 BRKIN0
|
||||
\arg TRIGSEL_INPUT_TIMER41_TRGO0: trigger input source TIMER41 TRGO0
|
||||
\arg TRIGSEL_INPUT_TIMER41_CH0: trigger input source TIMER41 CH0
|
||||
\arg TRIGSEL_INPUT_TIMER41_CH1: trigger input source TIMER41 CH1
|
||||
\arg TRIGSEL_INPUT_TIMER41_MCH0: trigger input source TIMER41 MCH0
|
||||
\arg TRIGSEL_INPUT_TIMER41_BRKIN0: trigger input source TIMER41 BRKIN0
|
||||
\arg TRIGSEL_INPUT_TIMER42_TRGO0: trigger input source TIMER42 TRGO0
|
||||
\arg TRIGSEL_INPUT_TIMER42_CH0: trigger input source TIMER42 CH0
|
||||
\arg TRIGSEL_INPUT_TIMER42_CH1: trigger input source TIMER42 CH1
|
||||
\arg TRIGSEL_INPUT_TIMER42_MCH0: trigger input source TIMER42 MCH0
|
||||
\arg TRIGSEL_INPUT_TIMER42_BRKIN0: trigger input source TIMER42 BRKIN0
|
||||
\arg TRIGSEL_INPUT_TIMER43_TRGO0: trigger input source TIMER43 TRGO0
|
||||
\arg TRIGSEL_INPUT_TIMER43_CH0: trigger input source TIMER43 CH0
|
||||
\arg TRIGSEL_INPUT_TIMER43_CH1: trigger input source TIMER43 CH1
|
||||
\arg TRIGSEL_INPUT_TIMER43_MCH0: trigger input source TIMER43 MCH0
|
||||
\arg TRIGSEL_INPUT_TIMER43_BRKIN0: trigger input source TIMER43 BRKIN0
|
||||
\arg TRIGSEL_INPUT_TIMER44_TRGO0: trigger input source TIMER44 TRGO0
|
||||
\arg TRIGSEL_INPUT_TIMER44_CH0: trigger input source TIMER44 CH0
|
||||
\arg TRIGSEL_INPUT_TIMER44_CH1: trigger input source TIMER44 CH1
|
||||
\arg TRIGSEL_INPUT_TIMER44_MCH0: trigger input source TIMER44 MCH0
|
||||
\arg TRIGSEL_INPUT_TIMER44_BRKIN0: trigger input source TIMER44 BRKIN0
|
||||
\arg TRIGSEL_INPUT_TIMER50_TRGO0: trigger input source TIMER50 TRGO0
|
||||
\arg TRIGSEL_INPUT_TIMER51_TRGO0: trigger input source TIMER51 TRGO0
|
||||
\arg TRIGSEL_INPUT_RTC_ALARM: trigger input source RTC alarm
|
||||
\arg TRIGSEL_INPUT_RTC_TPTS: trigger input source RTC tamper and time-stamp
|
||||
\arg TRIGSEL_INPUT_ADC0_WD0_OUT: trigger input source ADC0 watchdog0 output
|
||||
\arg TRIGSEL_INPUT_ADC0_WD1_OUT: trigger input source ADC0 watchdog1 output
|
||||
\arg TRIGSEL_INPUT_ADC0_WD2_OUT: trigger input source ADC0 watchdog2 output
|
||||
\arg TRIGSEL_INPUT_ADC1_WD0_OUT: trigger input source ADC1 watchdog0 output
|
||||
\arg TRIGSEL_INPUT_ADC1_WD1_OUT: trigger input source ADC1 watchdog1 output
|
||||
\arg TRIGSEL_INPUT_ADC1_WD2_OUT: trigger input source ADC1 watchdog2 output
|
||||
\arg TRIGSEL_INPUT_ADC2_WD0_OUT: trigger input source ADC2 watchdog0 output
|
||||
\arg TRIGSEL_INPUT_ADC2_WD1_OUT: trigger input source ADC2 watchdog1 output
|
||||
\arg TRIGSEL_INPUT_ADC2_WD2_OUT: trigger input source ADC2 watchdog2 output
|
||||
\arg TRIGSEL_INPUT_CMP0_OUT: trigger input source CMP0_OUT
|
||||
\arg TRIGSEL_INPUT_CMP1_OUT: trigger input source CMP1_OUT
|
||||
\arg TRIGSEL_INPUT_SAI0_FS0: trigger input source SAI0_FS0
|
||||
\arg TRIGSEL_INPUT_SAI0_FS1: trigger input source SAI0_FS1
|
||||
\arg TRIGSEL_INPUT_SAI2_FS0: trigger input source SAI2_FS0
|
||||
\arg TRIGSEL_INPUT_SAI2_FS1: trigger input source SAI2_FS1
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void trigsel_init(trigsel_periph_enum target_periph, trigsel_source_enum trigger_source)
|
||||
{
|
||||
/* if register write is enabled, set trigger source to target peripheral */
|
||||
if (RESET == trigsel_register_lock_get(target_periph)){
|
||||
TRIGSEL_TARGET_REG(target_periph) &= ~TRIGSEL_TARGET_PERIPH_MASK(target_periph);
|
||||
TRIGSEL_TARGET_REG(target_periph) |= ((uint32_t)trigger_source << TRIGSEL_TARGET_PERIPH_SHIFT(target_periph)) & TRIGSEL_TARGET_PERIPH_MASK(target_periph);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the trigger input signal for target peripheral
|
||||
\param[in] target_periph: target peripheral value
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg TRIGSEL_OUTPUT_TRIGSEL_OUT0: output target peripheral TRIGSEL_OUT0 pin
|
||||
\arg TRIGSEL_OUTPUT_TRIGSEL_OUT1: output target peripheral TRIGSEL_OUT1 pin
|
||||
\arg TRIGSEL_OUTPUT_TRIGSEL_OUT2: output target peripheral TRIGSEL_OUT2 pin
|
||||
\arg TRIGSEL_OUTPUT_TRIGSEL_OUT3: output target peripheral TRIGSEL_OUT3 pin
|
||||
\arg TRIGSEL_OUTPUT_TRIGSEL_OUT4: output target peripheral TRIGSEL_OUT4 pin
|
||||
\arg TRIGSEL_OUTPUT_TRIGSEL_OUT5: output target peripheral TRIGSEL_OUT5 pin
|
||||
\arg TRIGSEL_OUTPUT_TRIGSEL_OUT6: output target peripheral TRIGSEL_OUT6 pin
|
||||
\arg TRIGSEL_OUTPUT_TRIGSEL_OUT7: output target peripheral TRIGSEL_OUT7 pin
|
||||
\arg TRIGSEL_OUTPUT_ADC0_REGTRG: output target peripheral ADC0_REGTRG
|
||||
\arg TRIGSEL_OUTPUT_ADC0_INSTRG: output target peripheral ADC0_INSTRG
|
||||
\arg TRIGSEL_OUTPUT_ADC1_REGTRG: output target peripheral ADC1_REGTRG
|
||||
\arg TRIGSEL_OUTPUT_ADC1_INSTRG: output target peripheral ADC1_INSTRG
|
||||
\arg TRIGSEL_OUTPUT_ADC2_REGTRG: output target peripheral ADC2_REGTRG
|
||||
\arg TRIGSEL_OUTPUT_ADC2_INSTRG: output target peripheral ADC2_INSTRG
|
||||
\arg TRIGSEL_OUTPUT_DAC0_OUT0_EXTRG: output target peripheral DAC0_OUT0_EXTRG
|
||||
\arg TRIGSEL_OUTPUT_DAC0_OUT1_EXTRG: output target peripheral DAC0_OUT1_EXTRG
|
||||
\arg TRIGSEL_OUTPUT_TIMER0_BRKIN0: output target peripheral TIMER0_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER0_BRKIN1: output target peripheral TIMER0_BRKIN1
|
||||
\arg TRIGSEL_OUTPUT_TIMER0_BRKIN2: output target peripheral TIMER0_BRKIN2
|
||||
\arg TRIGSEL_OUTPUT_TIMER7_BRKIN0: output target peripheral TIMER7_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER7_BRKIN1: output target peripheral TIMER7_BRKIN1
|
||||
\arg TRIGSEL_OUTPUT_TIMER7_BRKIN2: output target peripheral TIMER7_BRKIN2
|
||||
\arg TRIGSEL_OUTPUT_TIMER14_BRKIN0: output target peripheral TIMER14_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER15_BRKIN0: output target peripheral TIMER15_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER16_BRKIN0: output target peripheral TIMER16_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER40_BRKIN0: output target peripheral TIMER40_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER41_BRKIN0: output target peripheral TIMER41_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER42_BRKIN0: output target peripheral TIMER42_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER43_BRKIN0: output target peripheral TIMER43_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER44_BRKIN0: output target peripheral TIMER44_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_CAN0_EX_TIME_TICK: output target peripheral CAN0_EX_TIME_TICK
|
||||
\arg TRIGSEL_OUTPUT_CAN1_EX_TIME_TICK: output target peripheral CAN1_EX_TIME_TICK
|
||||
\arg TRIGSEL_OUTPUT_CAN2_EX_TIME_TICK: output target peripheral CAN2_EX_TIME_TICK
|
||||
\arg TRIGSEL_OUTPUT_LPDTS_TRG: output target peripheral LPDTS_TRG
|
||||
\arg TRIGSEL_OUTPUT_TIMER0_ETI: output target peripheral TIMER0_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER1_ETI: output target peripheral TIMER1_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER2_ETI: output target peripheral TIMER2_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER3_ETI: output target peripheral TIMER3_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER4_ETI: output target peripheral TIMER4_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER7_ETI: output target peripheral TIMER7_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER22_ETI: output target peripheral TIMER22_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER23_ETI: output target peripheral TIMER23_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER30_ETI: output target peripheral TIMER30_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER31_ETI: output target peripheral TIMER31_ETI
|
||||
\arg TRIGSEL_OUTPUT_EDOUT_TRG: output target peripheral EDOUT_TRG
|
||||
\arg TRIGSEL_OUTPUT_HPDF_ITRG: output target peripheral HPDF_ITR
|
||||
\arg TRIGSEL_OUTPUT_TIMER0_ITI14: output target peripheral TIMER0_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER1_ITI14: output target peripheral TIMER1_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER2_ITI14: output target peripheral TIMER2_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER3_ITI14: output target peripheral TIMER3_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER4_ITI14: output target peripheral TIMER4_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER7_ITI14: output target peripheral TIMER7_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER14_ITI14: output target peripheral TIMER14_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER22_ITI14: output target peripheral TIMER22_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER23_ITI14: output target peripheral TIMER23_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER30_ITI14: output target peripheral TIMER30_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER31_ITI14: output target peripheral TIMER31_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER40_ITI14: output target peripheral TIMER40_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER41_ITI14: output target peripheral TIMER41_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER42_ITI14: output target peripheral TIMER42_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER43_ITI14: output target peripheral TIMER43_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER44_ITI14: output target peripheral TIMER44_ITI14
|
||||
\param[out] none
|
||||
\retval trigger_source: trigger source value(0~177)
|
||||
*/
|
||||
trigsel_source_enum trigsel_trigger_source_get(trigsel_periph_enum target_periph)
|
||||
{
|
||||
trigsel_source_enum trigger_source;
|
||||
|
||||
trigger_source = (trigsel_source_enum)((TRIGSEL_TARGET_REG(target_periph) & TRIGSEL_TARGET_PERIPH_MASK(target_periph)) >> TRIGSEL_TARGET_PERIPH_SHIFT(target_periph));
|
||||
|
||||
return trigger_source;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief lock the trigger register
|
||||
\param[in] target_periph: target peripheral value
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg TRIGSEL_OUTPUT_TRIGSEL_OUT0: output target peripheral TRIGSEL_OUT0 pin
|
||||
\arg TRIGSEL_OUTPUT_TRIGSEL_OUT1: output target peripheral TRIGSEL_OUT1 pin
|
||||
\arg TRIGSEL_OUTPUT_TRIGSEL_OUT2: output target peripheral TRIGSEL_OUT2 pin
|
||||
\arg TRIGSEL_OUTPUT_TRIGSEL_OUT3: output target peripheral TRIGSEL_OUT3 pin
|
||||
\arg TRIGSEL_OUTPUT_TRIGSEL_OUT4: output target peripheral TRIGSEL_OUT4 pin
|
||||
\arg TRIGSEL_OUTPUT_TRIGSEL_OUT5: output target peripheral TRIGSEL_OUT5 pin
|
||||
\arg TRIGSEL_OUTPUT_TRIGSEL_OUT6: output target peripheral TRIGSEL_OUT6 pin
|
||||
\arg TRIGSEL_OUTPUT_TRIGSEL_OUT7: output target peripheral TRIGSEL_OUT7 pin
|
||||
\arg TRIGSEL_OUTPUT_ADC0_REGTRG: output target peripheral ADC0_REGTRG
|
||||
\arg TRIGSEL_OUTPUT_ADC0_INSTRG: output target peripheral ADC0_INSTRG
|
||||
\arg TRIGSEL_OUTPUT_ADC1_REGTRG: output target peripheral ADC1_REGTRG
|
||||
\arg TRIGSEL_OUTPUT_ADC1_INSTRG: output target peripheral ADC1_INSTRG
|
||||
\arg TRIGSEL_OUTPUT_ADC2_REGTRG: output target peripheral ADC2_REGTRG
|
||||
\arg TRIGSEL_OUTPUT_ADC2_INSTRG: output target peripheral ADC2_INSTRG
|
||||
\arg TRIGSEL_OUTPUT_DAC0_OUT0_EXTRG: output target peripheral DAC0_OUT0_EXTRG
|
||||
\arg TRIGSEL_OUTPUT_DAC0_OUT1_EXTRG: output target peripheral DAC0_OUT1_EXTRG
|
||||
\arg TRIGSEL_OUTPUT_TIMER0_BRKIN0: output target peripheral TIMER0_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER0_BRKIN1: output target peripheral TIMER0_BRKIN1
|
||||
\arg TRIGSEL_OUTPUT_TIMER0_BRKIN2: output target peripheral TIMER0_BRKIN2
|
||||
\arg TRIGSEL_OUTPUT_TIMER7_BRKIN0: output target peripheral TIMER7_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER7_BRKIN1: output target peripheral TIMER7_BRKIN1
|
||||
\arg TRIGSEL_OUTPUT_TIMER7_BRKIN2: output target peripheral TIMER7_BRKIN2
|
||||
\arg TRIGSEL_OUTPUT_TIMER14_BRKIN0: output target peripheral TIMER14_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER15_BRKIN0: output target peripheral TIMER15_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER16_BRKIN0: output target peripheral TIMER16_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER40_BRKIN0: output target peripheral TIMER40_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER41_BRKIN0: output target peripheral TIMER41_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER42_BRKIN0: output target peripheral TIMER42_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER43_BRKIN0: output target peripheral TIMER43_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER44_BRKIN0: output target peripheral TIMER44_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_CAN0_EX_TIME_TICK: output target peripheral CAN0_EX_TIME_TICK
|
||||
\arg TRIGSEL_OUTPUT_CAN1_EX_TIME_TICK: output target peripheral CAN1_EX_TIME_TICK
|
||||
\arg TRIGSEL_OUTPUT_CAN2_EX_TIME_TICK: output target peripheral CAN2_EX_TIME_TICK
|
||||
\arg TRIGSEL_OUTPUT_LPDTS_TRG: output target peripheral LPDTS_TRG
|
||||
\arg TRIGSEL_OUTPUT_TIMER0_ETI: output target peripheral TIMER0_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER1_ETI: output target peripheral TIMER1_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER2_ETI: output target peripheral TIMER2_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER3_ETI: output target peripheral TIMER3_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER4_ETI: output target peripheral TIMER4_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER7_ETI: output target peripheral TIMER7_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER22_ETI: output target peripheral TIMER22_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER23_ETI: output target peripheral TIMER23_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER30_ETI: output target peripheral TIMER30_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER31_ETI: output target peripheral TIMER31_ETI
|
||||
\arg TRIGSEL_OUTPUT_EDOUT_TRG: output target peripheral EDOUT_TRG
|
||||
\arg TRIGSEL_OUTPUT_HPDF_ITRG: output target peripheral HPDF_ITR
|
||||
\arg TRIGSEL_OUTPUT_TIMER0_ITI14: output target peripheral TIMER0_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER1_ITI14: output target peripheral TIMER1_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER2_ITI14: output target peripheral TIMER2_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER3_ITI14: output target peripheral TIMER3_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER4_ITI14: output target peripheral TIMER4_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER7_ITI14: output target peripheral TIMER7_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER14_ITI14: output target peripheral TIMER14_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER22_ITI14: output target peripheral TIMER22_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER23_ITI14: output target peripheral TIMER23_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER30_ITI14: output target peripheral TIMER30_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER31_ITI14: output target peripheral TIMER31_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER40_ITI14: output target peripheral TIMER40_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER41_ITI14: output target peripheral TIMER41_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER42_ITI14: output target peripheral TIMER42_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER43_ITI14: output target peripheral TIMER43_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER44_ITI14: output target peripheral TIMER44_ITI14
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void trigsel_register_lock_set(trigsel_periph_enum target_periph)
|
||||
{
|
||||
/*!< lock target peripheral register */
|
||||
TRIGSEL_TARGET_REG(target_periph) |= TRIGSEL_TARGET_LK;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the trigger register lock status
|
||||
\param[in] target_periph: target peripheral value
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg TRIGSEL_OUTPUT_TRIGSEL_OUT0: output target peripheral TRIGSEL_OUT0 pin
|
||||
\arg TRIGSEL_OUTPUT_TRIGSEL_OUT1: output target peripheral TRIGSEL_OUT1 pin
|
||||
\arg TRIGSEL_OUTPUT_TRIGSEL_OUT2: output target peripheral TRIGSEL_OUT2 pin
|
||||
\arg TRIGSEL_OUTPUT_TRIGSEL_OUT3: output target peripheral TRIGSEL_OUT3 pin
|
||||
\arg TRIGSEL_OUTPUT_TRIGSEL_OUT4: output target peripheral TRIGSEL_OUT4 pin
|
||||
\arg TRIGSEL_OUTPUT_TRIGSEL_OUT5: output target peripheral TRIGSEL_OUT5 pin
|
||||
\arg TRIGSEL_OUTPUT_TRIGSEL_OUT6: output target peripheral TRIGSEL_OUT6 pin
|
||||
\arg TRIGSEL_OUTPUT_TRIGSEL_OUT7: output target peripheral TRIGSEL_OUT7 pin
|
||||
\arg TRIGSEL_OUTPUT_ADC0_REGTRG: output target peripheral ADC0_REGTRG
|
||||
\arg TRIGSEL_OUTPUT_ADC0_INSTRG: output target peripheral ADC0_INSTRG
|
||||
\arg TRIGSEL_OUTPUT_ADC1_REGTRG: output target peripheral ADC1_REGTRG
|
||||
\arg TRIGSEL_OUTPUT_ADC1_INSTRG: output target peripheral ADC1_INSTRG
|
||||
\arg TRIGSEL_OUTPUT_ADC2_REGTRG: output target peripheral ADC2_REGTRG
|
||||
\arg TRIGSEL_OUTPUT_ADC2_INSTRG: output target peripheral ADC2_INSTRG
|
||||
\arg TRIGSEL_OUTPUT_DAC0_OUT0_EXTRG: output target peripheral DAC0_OUT0_EXTRG
|
||||
\arg TRIGSEL_OUTPUT_DAC0_OUT1_EXTRG: output target peripheral DAC0_OUT1_EXTRG
|
||||
\arg TRIGSEL_OUTPUT_TIMER0_BRKIN0: output target peripheral TIMER0_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER0_BRKIN1: output target peripheral TIMER0_BRKIN1
|
||||
\arg TRIGSEL_OUTPUT_TIMER0_BRKIN2: output target peripheral TIMER0_BRKIN2
|
||||
\arg TRIGSEL_OUTPUT_TIMER7_BRKIN0: output target peripheral TIMER7_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER7_BRKIN1: output target peripheral TIMER7_BRKIN1
|
||||
\arg TRIGSEL_OUTPUT_TIMER7_BRKIN2: output target peripheral TIMER7_BRKIN2
|
||||
\arg TRIGSEL_OUTPUT_TIMER14_BRKIN0: output target peripheral TIMER14_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER15_BRKIN0: output target peripheral TIMER15_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER16_BRKIN0: output target peripheral TIMER16_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER40_BRKIN0: output target peripheral TIMER40_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER41_BRKIN0: output target peripheral TIMER41_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER42_BRKIN0: output target peripheral TIMER42_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER43_BRKIN0: output target peripheral TIMER43_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_TIMER44_BRKIN0: output target peripheral TIMER44_BRKIN0
|
||||
\arg TRIGSEL_OUTPUT_CAN0_EX_TIME_TICK: output target peripheral CAN0_EX_TIME_TICK
|
||||
\arg TRIGSEL_OUTPUT_CAN1_EX_TIME_TICK: output target peripheral CAN1_EX_TIME_TICK
|
||||
\arg TRIGSEL_OUTPUT_CAN2_EX_TIME_TICK: output target peripheral CAN2_EX_TIME_TICK
|
||||
\arg TRIGSEL_OUTPUT_LPDTS_TRG: output target peripheral LPDTS_TRG
|
||||
\arg TRIGSEL_OUTPUT_TIMER0_ETI: output target peripheral TIMER0_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER1_ETI: output target peripheral TIMER1_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER2_ETI: output target peripheral TIMER2_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER3_ETI: output target peripheral TIMER3_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER4_ETI: output target peripheral TIMER4_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER7_ETI: output target peripheral TIMER7_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER22_ETI: output target peripheral TIMER22_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER23_ETI: output target peripheral TIMER23_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER30_ETI: output target peripheral TIMER30_ETI
|
||||
\arg TRIGSEL_OUTPUT_TIMER31_ETI: output target peripheral TIMER31_ETI
|
||||
\arg TRIGSEL_OUTPUT_EDOUT_TRG: output target peripheral EDOUT_TRG
|
||||
\arg TRIGSEL_OUTPUT_HPDF_ITRG: output target peripheral HPDF_ITR
|
||||
\arg TRIGSEL_OUTPUT_TIMER0_ITI14: output target peripheral TIMER0_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER1_ITI14: output target peripheral TIMER1_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER2_ITI14: output target peripheral TIMER2_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER3_ITI14: output target peripheral TIMER3_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER4_ITI14: output target peripheral TIMER4_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER7_ITI14: output target peripheral TIMER7_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER14_ITI14: output target peripheral TIMER14_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER22_ITI14: output target peripheral TIMER22_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER23_ITI14: output target peripheral TIMER23_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER30_ITI14: output target peripheral TIMER30_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER31_ITI14: output target peripheral TIMER31_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER40_ITI14: output target peripheral TIMER40_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER41_ITI14: output target peripheral TIMER41_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER42_ITI14: output target peripheral TIMER42_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER43_ITI14: output target peripheral TIMER43_ITI14
|
||||
\arg TRIGSEL_OUTPUT_TIMER44_ITI14: output target peripheral TIMER44_ITI14
|
||||
\param[out] none
|
||||
\retval SET or RESET
|
||||
*/
|
||||
FlagStatus trigsel_register_lock_get(trigsel_periph_enum target_periph)
|
||||
{
|
||||
if(RESET != (TRIGSEL_TARGET_REG(target_periph) & TRIGSEL_TARGET_LK)){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,426 @@
|
||||
/*!
|
||||
\file gd32h7xx_trng.c
|
||||
\brief TRNG driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_trng.h"
|
||||
|
||||
/*!
|
||||
\brief deinitialize the TRNG
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void trng_deinit(void)
|
||||
{
|
||||
rcu_periph_reset_enable(RCU_TRNGRST);
|
||||
rcu_periph_reset_disable(RCU_TRNGRST);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the TRNG interface
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void trng_enable(void)
|
||||
{
|
||||
uint32_t trng_config = TRNG_CTL;
|
||||
trng_config &= ~TRNG_CTL_CONDRST;
|
||||
trng_config |= TRNG_CTL_TRNGEN;
|
||||
TRNG_CTL = trng_config;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the TRNG interface
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void trng_disable(void)
|
||||
{
|
||||
TRNG_CTL &= ~TRNG_CTL_TRNGEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief lock the TRNG control bits
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void trng_lock(void)
|
||||
{
|
||||
TRNG_CTL |= TRNG_CTL_LK;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure TRNG working mode
|
||||
\param[in] mode_select: the TRNG working mode
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg TRNG_MODSEL_LFSR: TRNG working in LFSR mode
|
||||
\arg TRNG_MODSEL_NIST: TRNG working in NIST mode
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void trng_mode_config(trng_modsel_enum mode_select)
|
||||
{
|
||||
uint32_t trng_config = TRNG_CTL;
|
||||
|
||||
trng_config &= ~TRNG_CTL_MODSEL;
|
||||
trng_config |= mode_select;
|
||||
TRNG_CTL = trng_config;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the TRNG post-processing module
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void trng_postprocessing_enable(void)
|
||||
{
|
||||
TRNG_CTL |= TRNG_CTL_PPEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the TRNG post-processing module
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void trng_postprocessing_disable(void)
|
||||
{
|
||||
TRNG_CTL &= ~TRNG_CTL_PPEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the TRNG conditioning module
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void trng_conditioning_enable(void)
|
||||
{
|
||||
TRNG_CTL |= TRNG_CTL_CONDEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the TRNG conditioning module
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void trng_conditioning_disable(void)
|
||||
{
|
||||
TRNG_CTL &= ~TRNG_CTL_CONDEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure TRNG conditioning module input bitwidth
|
||||
\param[in] input_bitwidth: the input bit width
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg TRNG_INMOD_256BIT: conditioning module input bitwidth 256bits
|
||||
\arg TRNG_INMOD_440BIT: conditioning module input bitwidth 440bits
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void trng_conditioning_input_bitwidth(trng_inmod_enum input_bitwidth)
|
||||
{
|
||||
uint32_t trng_config = TRNG_CTL;
|
||||
|
||||
trng_config &= ~TRNG_CTL_INMOD;
|
||||
trng_config |= input_bitwidth;
|
||||
TRNG_CTL = trng_config;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure TRNG conditioning module output bitwidth
|
||||
\param[in] output_bitwidth:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg TRNG_OUTMOD_128BIT: conditioning module output bitwidth 128bits
|
||||
\arg TRNG_OUTMOD_256BIT: conditioning module output bitwidth 256bits
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void trng_conditioning_output_bitwidth(trng_outmod_enum output_bitwidth)
|
||||
{
|
||||
uint32_t trng_config = TRNG_CTL;
|
||||
|
||||
trng_config &= ~TRNG_CTL_OUTMOD;
|
||||
trng_config |= (uint32_t)output_bitwidth;
|
||||
TRNG_CTL = trng_config;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable TRNG replace test
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void trng_replace_test_enable(void)
|
||||
{
|
||||
TRNG_CTL |= TRNG_CTL_RTEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable TRNG replace test
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void trng_replace_test_disable(void)
|
||||
{
|
||||
TRNG_CTL &= ~TRNG_CTL_RTEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable hash algorithm init when conditioning module enabled
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void trng_hash_init_enable(void)
|
||||
{
|
||||
TRNG_CTL |= TRNG_CTL_INIT;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable hash algorithm init when conditioning module enabled
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void trng_hash_init_disable(void)
|
||||
{
|
||||
TRNG_CTL &= ~TRNG_CTL_INIT;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure TRNG analog power mode
|
||||
\param[in] powermode: the power mode selection
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg TRNG_NR_ULTRALOW: TRNG analog power mode ultralow
|
||||
\arg TRNG_NR_LOW: TRNG analog power mode low
|
||||
\arg TRNG_NR_MEDIUM: TRNG analog power mode medium
|
||||
\arg TRNG_NR_HIGH: TRNG analog power mode high
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void trng_powermode_config(uint32_t powermode)
|
||||
{
|
||||
uint32_t trng_config = TRNG_CTL;
|
||||
|
||||
trng_config &= ~TRNG_CTL_NR;
|
||||
trng_config |= powermode;
|
||||
TRNG_CTL = trng_config;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure TRNG clock divider
|
||||
\param[in] clkdiv: TRNG clock divider
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg TRNG_CLK_DIVx (x=1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void trng_clockdiv_config(uint32_t clkdiv)
|
||||
{
|
||||
uint32_t trng_config = TRNG_CTL;
|
||||
|
||||
trng_config &= ~TRNG_CTL_CLKDIV;
|
||||
trng_config |= clkdiv;
|
||||
TRNG_CTL = trng_config;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the TRNG clock error detection
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void trng_clockerror_detection_enable(void)
|
||||
{
|
||||
TRNG_CTL |= TRNG_CTL_CED;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the TRNG clock error detection
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void trng_clockerror_detection_disable(void)
|
||||
{
|
||||
TRNG_CTL &= ~TRNG_CTL_CED;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the true random data
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval the generated random data
|
||||
*/
|
||||
uint32_t trng_get_true_random_data(void)
|
||||
{
|
||||
return (TRNG_DATA);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the conditioning logic reset
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void trng_conditioning_reset_enable(void)
|
||||
{
|
||||
TRNG_CTL |= TRNG_CTL_CONDRST;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the conditioning logic reset
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void trng_conditioning_reset_disable(void)
|
||||
{
|
||||
TRNG_CTL &= ~TRNG_CTL_CONDRST;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the conditioning module hash algorithm
|
||||
\param[in] module_algo: module hash algorithm
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg TRNG_ALGO_SHA1: TRNG conditioning module hash SHA1
|
||||
\arg TRNG_ALGO_MD5: TRNG conditioning module hash MD5
|
||||
\arg TRNG_ALGO_SHA224: TRNG conditioning module hash SHA224
|
||||
\arg TRNG_ALGO_SHA256: TRNG conditioning module hash SHA256
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void trng_conditioning_algo_config(uint32_t module_algo)
|
||||
{
|
||||
uint32_t tmp = TRNG_CTL;
|
||||
|
||||
tmp &= ~(TRNG_CTL_ALGO);
|
||||
tmp |= module_algo;
|
||||
TRNG_CTL = tmp;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure health tests default value
|
||||
\param[in] adpo_threshold: adaptive proportion test threshold value
|
||||
\param[in] rep_threshold: repetitive (00/11) test threshold value
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void trng_health_tests_config(uint32_t adpo_threshold, uint8_t rep_threshold)
|
||||
{
|
||||
uint32_t tmp = TRNG_HTCFG;
|
||||
|
||||
tmp &= ~(TRNG_HTCFG_APTTH | TRNG_HTCFG_RCTTH);
|
||||
tmp |= (((uint32_t)(adpo_threshold << 16U) & TRNG_HTCFG_APTTH) | (rep_threshold & TRNG_HTCFG_RCTTH));
|
||||
TRNG_HTCFG = tmp;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the TRNG status flags
|
||||
\param[in] flag: TRNG status flag, refer to trng_flag_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg TRNG_FLAG_DRDY: random data ready status
|
||||
\arg TRNG_FLAG_CECS: clock error current status
|
||||
\arg TRNG_FLAG_SECS: seed error current status
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus trng_flag_get(trng_flag_enum flag)
|
||||
{
|
||||
if(RESET != (TRNG_STAT & flag)){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the TRNG interrupt
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void trng_interrupt_enable(void)
|
||||
{
|
||||
TRNG_CTL |= TRNG_CTL_IE;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the TRNG interrupt
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void trng_interrupt_disable(void)
|
||||
{
|
||||
TRNG_CTL &= ~TRNG_CTL_IE;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the TRNG interrupt flags
|
||||
\param[in] int_flag: TRNG interrupt flag, refer to trng_int_flag_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg TRNG_INT_FLAG_CEIF: clock error interrupt flag
|
||||
\arg TRNG_INT_FLAG_SEIF: seed error interrupt flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus trng_interrupt_flag_get(trng_int_flag_enum int_flag)
|
||||
{
|
||||
if(RESET != (TRNG_STAT & int_flag)){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear the TRNG interrupt flags
|
||||
\param[in] int_flag: TRNG interrupt flag, refer to trng_int_flag_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg TRNG_INT_FLAG_CEIF: clock error interrupt flag
|
||||
\arg TRNG_INT_FLAG_SEIF: seed error interrupt flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void trng_interrupt_flag_clear(trng_int_flag_enum int_flag)
|
||||
{
|
||||
TRNG_STAT &= ~(uint32_t)int_flag;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,153 @@
|
||||
/*!
|
||||
\file gd32h7xx_vref.c
|
||||
\brief VREF driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_vref.h"
|
||||
|
||||
/*!
|
||||
\brief deinitialize the VREF
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void vref_deinit(void)
|
||||
{
|
||||
rcu_periph_reset_enable(RCU_VREFRST);
|
||||
rcu_periph_reset_disable(RCU_VREFRST);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable VREF
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void vref_enable(void)
|
||||
{
|
||||
VREF_CS |= VREF_EN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable VREF
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void vref_disable(void)
|
||||
{
|
||||
VREF_CS &= (uint32_t)~VREF_EN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable VREF high impendance mode
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void vref_high_impedance_mode_enable(void)
|
||||
{
|
||||
VREF_CS |= VREF_HIGH_IMPEDANCE_MODE;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable VREF high impendance mode
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void vref_high_impedance_mode_disable(void)
|
||||
{
|
||||
VREF_CS &= (uint32_t)~VREF_HIGH_IMPEDANCE_MODE;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the status of VREF
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval the status of VREF output
|
||||
\arg SET: the VREF output is ready
|
||||
\arg RESET: the VREF output is not ready
|
||||
*/
|
||||
FlagStatus vref_status_get(void)
|
||||
{
|
||||
if(RESET != (VREF_CS & (uint32_t)VREF_CS_VREFRDY)){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief select the VREF voltage reference
|
||||
\param[in] vref_voltage: voltage reference select,
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg VREF_VOLTAGE_SEL_2_5V: VREF voltage reference select 2.5 V
|
||||
\arg VREF_VOLTAGE_SEL_2_048V: VREF voltage reference select 2.048 V
|
||||
\arg VREF_VOLTAGE_SEL_1_8V: VREF voltage reference select 1.8 V
|
||||
\arg VREF_VOLTAGE_SEL_1_5V: VREF voltage reference select 1.5 V
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void vref_voltage_select(uint32_t vref_voltage)
|
||||
{
|
||||
uint32_t temp = VREF_CS;
|
||||
|
||||
/* clear old value */
|
||||
temp &= ~(uint32_t)VREF_VOLTAGE_SEL_1_5V;
|
||||
temp |= (uint32_t)vref_voltage;
|
||||
|
||||
VREF_CS = temp;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set the calibration value of VREF
|
||||
\param[in] value: calibration value (0x00 - 0x3F)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void vref_calib_value_set(uint8_t value)
|
||||
{
|
||||
VREF_CALIB = (uint32_t)(VREF_CALIB_VREFCAL & value);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the calibration value of VREF
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval calibration value (0x00 - 0x3F)
|
||||
*/
|
||||
uint8_t vref_calib_value_get(void)
|
||||
{
|
||||
uint8_t temp = (uint8_t)VREF_CALIB;
|
||||
return temp;
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/*!
|
||||
\file gd32h7xx_wwdgt.c
|
||||
\brief WWDGT driver
|
||||
|
||||
\version 2025-01-24, V1.4.0, firmware for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2025, GigaDevice Semiconductor Inc.
|
||||
|
||||
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 "gd32h7xx_wwdgt.h"
|
||||
|
||||
/* WWDGT_CTL register value */
|
||||
#define CTL_CNT(regval) (BITS(0,6) & ((uint32_t)(regval) << 0U))
|
||||
/* WWDGT_CFG register value */
|
||||
#define CFG_WIN(regval) (BITS(0,6) & ((uint32_t)(regval) << 0U))
|
||||
|
||||
/*!
|
||||
\brief reset the window watchdog timer configuration
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void wwdgt_deinit(void)
|
||||
{
|
||||
rcu_periph_reset_enable(RCU_WWDGTRST);
|
||||
rcu_periph_reset_disable(RCU_WWDGTRST);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief start the WWDGT counter
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void wwdgt_enable(void)
|
||||
{
|
||||
WWDGT_CTL |= WWDGT_CTL_WDGTEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the WWDGT counter value
|
||||
\param[in] counter_value: 0x00 - 0x7F
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void wwdgt_counter_update(uint16_t counter_value)
|
||||
{
|
||||
WWDGT_CTL = (uint32_t)(CTL_CNT(counter_value));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure counter value, window value, and prescaler divider value
|
||||
\param[in] counter: 0x0000 - 0x007F
|
||||
\param[in] window: 0x0000 - 0x007F
|
||||
\param[in] prescaler: WWDGT prescaler value
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg WWDGT_CFG_PSC_DIV1: the time base of window watchdog counter = (PCLK3/4096)/1
|
||||
\arg WWDGT_CFG_PSC_DIV2: the time base of window watchdog counter = (PCLK3/4096)/2
|
||||
\arg WWDGT_CFG_PSC_DIV4: the time base of window watchdog counter = (PCLK3/4096)/4
|
||||
\arg WWDGT_CFG_PSC_DIV8: the time base of window watchdog counter = (PCLK3/4096)/8
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void wwdgt_config(uint16_t counter, uint16_t window, uint32_t prescaler)
|
||||
{
|
||||
WWDGT_CTL = (uint32_t)(CTL_CNT(counter));
|
||||
WWDGT_CFG = (uint32_t)(CFG_WIN(window) | prescaler);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable early wakeup interrupt of WWDGT
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void wwdgt_interrupt_enable(void)
|
||||
{
|
||||
WWDGT_CFG |= WWDGT_CFG_EWIE;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief check early wakeup interrupt state of WWDGT
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus wwdgt_flag_get(void)
|
||||
{
|
||||
if (RESET != (WWDGT_STAT & WWDGT_STAT_EWIF)){
|
||||
return SET;
|
||||
}
|
||||
|
||||
return RESET;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear early wakeup interrupt state of WWDGT
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void wwdgt_flag_clear(void)
|
||||
{
|
||||
WWDGT_STAT = (uint32_t)RESET;
|
||||
}
|
||||
Reference in New Issue
Block a user