Sync betaflight to Gitea
This commit is contained in:
+1200
File diff suppressed because it is too large
Load Diff
+1020
File diff suppressed because it is too large
Load Diff
+127
@@ -0,0 +1,127 @@
|
||||
/*!
|
||||
\file gd32f4xx_crc.c
|
||||
\brief CRC driver
|
||||
|
||||
\version 2024-12-20, V3.3.1, firmware for GD32F4xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2024, 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 "gd32f4xx_crc.h"
|
||||
|
||||
#define CRC_DATA_RESET_VALUE ((uint32_t)0xFFFFFFFFU)
|
||||
#define CRC_FDATA_RESET_VALUE ((uint32_t)0x00000000U)
|
||||
|
||||
/*!
|
||||
\brief deinit CRC calculation unit
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void crc_deinit(void)
|
||||
{
|
||||
CRC_DATA = CRC_DATA_RESET_VALUE;
|
||||
CRC_FDATA = CRC_FDATA_RESET_VALUE;
|
||||
CRC_CTL = (uint32_t)CRC_CTL_RST;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief reset data register(CRC_DATA) to the value of 0xFFFFFFFF
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void crc_data_register_reset(void)
|
||||
{
|
||||
CRC_CTL |= (uint32_t)CRC_CTL_RST;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief read the value of 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 value of 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 data to the free data register
|
||||
\param[in] free_data: specified 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 calculate the CRC value of a 32-bit data
|
||||
\param[in] sdata: specified 32-bit data
|
||||
\param[out] none
|
||||
\retval 32-bit value calculated by CRC
|
||||
*/
|
||||
uint32_t crc_single_data_calculate(uint32_t sdata)
|
||||
{
|
||||
CRC_DATA = sdata;
|
||||
return (CRC_DATA);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief calculate the CRC value of an array of 32-bit values
|
||||
\param[in] array: pointer to an array of 32-bit values
|
||||
\param[in] size: size of the array
|
||||
\param[out] none
|
||||
\retval 32-bit value calculated by CRC
|
||||
*/
|
||||
uint32_t crc_block_data_calculate(uint32_t array[], uint32_t size)
|
||||
{
|
||||
uint32_t index;
|
||||
for(index = 0U; index < size; index++) {
|
||||
CRC_DATA = array[index];
|
||||
}
|
||||
return (CRC_DATA);
|
||||
}
|
||||
+388
@@ -0,0 +1,388 @@
|
||||
/*!
|
||||
\file gd32f4xx_ctc.c
|
||||
\brief CTC driver
|
||||
|
||||
\version 2024-12-20, V3.3.1, firmware for GD32F4xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2024, 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 "gd32f4xx_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] ctc_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:
|
||||
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:
|
||||
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:
|
||||
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 enable the CTC interrupt
|
||||
\param[in] interrupt: CTC interrupt enable
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg CTC_INT_CKOK: clock trim OK interrupt enable
|
||||
\arg CTC_INT_CKWARN: clock trim warning interrupt enable
|
||||
\arg CTC_INT_ERR: error interrupt enable
|
||||
\arg CTC_INT_EREF: expect reference interrupt enable
|
||||
\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 enable source
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg CTC_INT_CKOK: clock trim OK interrupt enable
|
||||
\arg CTC_INT_CKWARN: clock trim warning interrupt enable
|
||||
\arg CTC_INT_ERR: error interrupt enable
|
||||
\arg CTC_INT_EREF: expect reference interrupt enable
|
||||
\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
|
||||
\arg CTC_INT_FLAG_CKWARN: clock trim warning interrupt
|
||||
\arg CTC_INT_FLAG_ERR: error interrupt
|
||||
\arg CTC_INT_FLAG_EREF: expect reference interrupt
|
||||
\arg CTC_INT_FLAG_CKERR: clock trim error bit interrupt
|
||||
\arg CTC_INT_FLAG_REFMISS: reference sync pulse miss interrupt
|
||||
\arg CTC_INT_FLAG_TRIMERR: trim value error interrupt
|
||||
\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
|
||||
\arg CTC_INT_FLAG_CKWARN: clock trim warning interrupt
|
||||
\arg CTC_INT_FLAG_ERR: error interrupt
|
||||
\arg CTC_INT_FLAG_EREF: expect reference interrupt
|
||||
\arg CTC_INT_FLAG_CKERR: clock trim error bit interrupt
|
||||
\arg CTC_INT_FLAG_REFMISS: reference sync pulse miss interrupt
|
||||
\arg CTC_INT_FLAG_TRIMERR: trim value error interrupt
|
||||
\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;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\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 bit
|
||||
\arg CTC_FLAG_REFMISS: reference sync pulse miss
|
||||
\arg CTC_FLAG_TRIMERR: trim value error bit
|
||||
\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 bit
|
||||
\arg CTC_FLAG_REFMISS: reference sync pulse miss
|
||||
\arg CTC_FLAG_TRIMERR: trim value error bit
|
||||
\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;
|
||||
}
|
||||
}
|
||||
+678
@@ -0,0 +1,678 @@
|
||||
/*!
|
||||
\file gd32f4xx_dac.c
|
||||
\brief DAC driver
|
||||
|
||||
\version 2024-12-20, V3.3.1, firmware for GD32F4xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2024, 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 "gd32f4xx_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)
|
||||
#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 enable DAC output buffer
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[in] dac_out: DAC_OUTx(x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_output_buffer_enable(uint32_t dac_periph, uint8_t dac_out)
|
||||
{
|
||||
if(DAC_OUT0 == dac_out){
|
||||
DAC_CTL0(dac_periph) &= (uint32_t)(~DAC_CTL0_DBOFF0);
|
||||
}else if(DAC_OUT1 == dac_out){
|
||||
DAC_CTL0(dac_periph) &= (uint32_t)(~DAC_CTL0_DBOFF1);
|
||||
}else{
|
||||
/* illegal parameters */
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DAC output buffer
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[in] dac_out: DAC_OUTx(x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_output_buffer_disable(uint32_t dac_periph, uint8_t dac_out)
|
||||
{
|
||||
if(DAC_OUT0 == dac_out){
|
||||
DAC_CTL0(dac_periph) |= (uint32_t)DAC_CTL0_DBOFF0;
|
||||
}else if(DAC_OUT1 == dac_out){
|
||||
DAC_CTL0(dac_periph) |= (uint32_t)DAC_CTL0_DBOFF1;
|
||||
}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_T1_TRGO: TIMER1 TRGO
|
||||
\arg DAC_TRIGGER_T3_TRGO: TIMER3 TRGO
|
||||
\arg DAC_TRIGGER_T4_TRGO: TIMER4 TRGO
|
||||
\arg DAC_TRIGGER_T5_TRGO: TIMER5 TRGO
|
||||
\arg DAC_TRIGGER_T6_TRGO: TIMER6 TRGO
|
||||
\arg DAC_TRIGGER_T7_TRGO: TIMER7 TRGO
|
||||
\arg DAC_TRIGGER_EXTI_9: EXTI interrupt line9 event
|
||||
\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 enable DAC concurrent buffer function
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_concurrent_output_buffer_enable(uint32_t dac_periph)
|
||||
{
|
||||
uint32_t ctl = 0U;
|
||||
|
||||
ctl = (uint32_t)(DAC_CTL0_DBOFF0 | DAC_CTL0_DBOFF1);
|
||||
DAC_CTL0(dac_periph) &= (uint32_t)(~ctl);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DAC concurrent buffer function
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_concurrent_output_buffer_disable(uint32_t dac_periph)
|
||||
{
|
||||
uint32_t ctl = 0U;
|
||||
|
||||
ctl = (uint32_t)(DAC_CTL0_DBOFF0 | DAC_CTL0_DBOFF1);
|
||||
DAC_CTL0(dac_periph) |= (uint32_t)ctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\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 get the 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_DDUDR1: DACx_OUT1 DMA underrun 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 the DAC flag
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[in] flag: DAC flag
|
||||
one or more parameter can be selected which are shown as below:
|
||||
\arg DAC_FLAG_DDUDR0: DACx_OUT0 DMA underrun flag
|
||||
\arg DAC_FLAG_DDUDR1: DACx_OUT1 DMA underrun 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(DAC DMA underrun interrupt)
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[in] interrupt: the DAC interrupt
|
||||
one or more parameter can be selected which are 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(DAC DMA underrun interrupt)
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[in] interrupt: the DAC interrupt
|
||||
one and more parameter can be selected which are 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 the DAC interrupt flag(DAC DMA underrun 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 the DAC interrupt flag(DAC DMA underrun interrupt flag)
|
||||
\param[in] dac_periph: DACx(x=0)
|
||||
\param[in] int_flag: DAC interrupt flag
|
||||
one or more parameter can be selected which are 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 & DAC_INT_FLAG_MASK0);
|
||||
}else{
|
||||
/* illegal parameters */
|
||||
}
|
||||
}
|
||||
+180
@@ -0,0 +1,180 @@
|
||||
/*!
|
||||
\file gd32f4xx_dbg.c
|
||||
\brief DBG driver
|
||||
|
||||
\version 2024-12-20, V3.3.1, firmware for GD32F4xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2024, 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 "gd32f4xx_dbg.h"
|
||||
|
||||
#define DBG_RESET_VAL 0x00000000U
|
||||
|
||||
/*!
|
||||
\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;
|
||||
}
|
||||
|
||||
/*!
|
||||
\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:
|
||||
this parameter can be any combination of the following values:
|
||||
\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:
|
||||
this parameter can be any combination of the following values:
|
||||
\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 peripheral behavior when the mcu is in debug mode
|
||||
\param[in] dbg_periph: dbg_periph_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DBG_TIMER1_HOLD: hold TIMER1 counter when core is halted
|
||||
\arg DBG_TIMER2_HOLD: hold TIMER2 counter when core is halted
|
||||
\arg DBG_TIMER3_HOLD: hold TIMER3 counter when core is halted
|
||||
\arg DBG_TIMER4_HOLD: hold TIMER4 counter when core is halted
|
||||
\arg DBG_TIMER5_HOLD: hold TIMER5 counter when core is halted
|
||||
\arg DBG_TIMER6_HOLD: hold TIMER6 counter when core is halted
|
||||
\arg DBG_TIMER11_HOLD: hold TIMER11 counter when core is halted
|
||||
\arg DBG_TIMER12_HOLD: hold TIMER12 counter when core is halted
|
||||
\arg DBG_TIMER13_HOLD: hold TIMER13 counter when core is halted
|
||||
\arg DBG_RTC_HOLD: hold RTC calendar and wakeup counter when core is halted
|
||||
\arg DBG_WWDGT_HOLD: debug WWDGT kept when core is halted
|
||||
\arg DBG_FWDGT_HOLD: debug FWDGT kept when core is halted
|
||||
\arg DBG_I2C0_HOLD: hold I2C0 smbus when core is halted
|
||||
\arg DBG_I2C1_HOLD: hold I2C1 smbus when core is halted
|
||||
\arg DBG_I2C2_HOLD: hold I2C2 smbus when core is halted
|
||||
\arg DBG_CAN0_HOLD: debug CAN0 kept when core is halted
|
||||
\arg DBG_CAN1_HOLD: debug CAN1 kept when core is halted
|
||||
\arg DBG_TIMER0_HOLD: hold TIMER0 counter when core is halted
|
||||
\arg DBG_TIMER7_HOLD: hold TIMER7 counter when core is halted
|
||||
\arg DBG_TIMER8_HOLD: hold TIMER8 counter when core is halted
|
||||
\arg DBG_TIMER9_HOLD: hold TIMER9 counter when core is halted
|
||||
\arg DBG_TIMER10_HOLD: hold TIMER10 counter when core is halted
|
||||
\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: dbg_periph_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DBG_TIMER1_HOLD: hold TIMER1 counter when core is halted
|
||||
\arg DBG_TIMER2_HOLD: hold TIMER2 counter when core is halted
|
||||
\arg DBG_TIMER3_HOLD: hold TIMER3 counter when core is halted
|
||||
\arg DBG_TIMER4_HOLD: hold TIMER4 counter when core is halted
|
||||
\arg DBG_TIMER5_HOLD: hold TIMER5 counter when core is halted
|
||||
\arg DBG_TIMER6_HOLD: hold TIMER6 counter when core is halted
|
||||
\arg DBG_TIMER11_HOLD: hold TIMER11 counter when core is halted
|
||||
\arg DBG_TIMER12_HOLD: hold TIMER12 counter when core is halted
|
||||
\arg DBG_TIMER13_HOLD: hold TIMER13 counter when core is halted
|
||||
\arg DBG_RTC_HOLD: hold RTC calendar and wakeup counter when core is halted
|
||||
\arg DBG_WWDGT_HOLD: debug WWDGT kept when core is halted
|
||||
\arg DBG_FWDGT_HOLD: debug FWDGT kept when core is halted
|
||||
\arg DBG_I2C0_HOLD: hold I2C0 smbus when core is halted
|
||||
\arg DBG_I2C1_HOLD: hold I2C1 smbus when core is halted
|
||||
\arg DBG_I2C2_HOLD: hold I2C2 smbus when core is halted
|
||||
\arg DBG_CAN0_HOLD: debug CAN0 kept when core is halted
|
||||
\arg DBG_CAN1_HOLD: debug CAN1 kept when core is halted
|
||||
\arg DBG_TIMER0_HOLD: hold TIMER0 counter when core is halted
|
||||
\arg DBG_TIMER7_HOLD: hold TIMER7 counter when core is halted
|
||||
\arg DBG_TIMER8_HOLD: hold TIMER8 counter when core is halted
|
||||
\arg DBG_TIMER9_HOLD: hold TIMER9 counter when core is halted
|
||||
\arg DBG_TIMER10_HOLD: hold TIMER10 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));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable trace pin assignment
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dbg_trace_pin_enable(void)
|
||||
{
|
||||
DBG_CTL0 |= DBG_CTL0_TRACE_IOEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable trace pin assignment
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dbg_trace_pin_disable(void)
|
||||
{
|
||||
DBG_CTL0 &= ~DBG_CTL0_TRACE_IOEN;
|
||||
}
|
||||
|
||||
+343
@@ -0,0 +1,343 @@
|
||||
/*!
|
||||
\file gd32f4xx_dci.c
|
||||
\brief DCI driver
|
||||
|
||||
\version 2024-12-20, V3.3.1, firmware for GD32F4xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2024, 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 "gd32f4xx_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
|
||||
clock_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 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 << 16));
|
||||
DCI_CWSZ = ((uint32_t)size_width | ((uint32_t)size_height << 16));
|
||||
}
|
||||
|
||||
/*!
|
||||
\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 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 << 8) | ((uint32_t)line_end << 16) | ((uint32_t)frame_end << 24));
|
||||
}
|
||||
|
||||
/*!
|
||||
\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 << 8) | ((uint32_t)line_end << 16) | ((uint32_t)frame_end << 24));
|
||||
}
|
||||
|
||||
/*!
|
||||
\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:
|
||||
\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 >> 31) {
|
||||
/* 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:
|
||||
\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
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dci_interrupt_enable(uint32_t interrupt)
|
||||
{
|
||||
DCI_INTEN |= interrupt;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable specified DCI interrupt
|
||||
\param[in] interrupt:
|
||||
\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
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dci_interrupt_disable(uint32_t interrupt)
|
||||
{
|
||||
DCI_INTEN &= ~interrupt;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear specified interrupt flag
|
||||
\param[in] int_flag:
|
||||
\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
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dci_interrupt_flag_clear(uint32_t int_flag)
|
||||
{
|
||||
DCI_INTC |= int_flag;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get specified interrupt flag
|
||||
\param[in] int_flag:
|
||||
\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
|
||||
\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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+911
@@ -0,0 +1,911 @@
|
||||
/*!
|
||||
\file gd32f4xx_dma.c
|
||||
\brief DMA driver
|
||||
\version 2024-12-20, V3.3.1, firmware for GD32F4xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2024, 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 "gd32f4xx_dma.h"
|
||||
|
||||
/* DMA register bit offset */
|
||||
#define CHXCTL_PERIEN_OFFSET ((uint32_t)25U)
|
||||
|
||||
/*!
|
||||
\brief deinitialize DMA a channel registers
|
||||
\param[in] dma_periph: DMAx(x=0,1)
|
||||
\arg DMAx(x=0,1)
|
||||
\param[in] channelx: specify which DMA channel is deinitialized
|
||||
\arg DMA_CHx(x=0..7)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_deinit(uint32_t dma_periph, dma_channel_enum channelx)
|
||||
{
|
||||
/* disable DMA a channel */
|
||||
DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_CHEN;
|
||||
/* reset DMA channel registers */
|
||||
DMA_CHCTL(dma_periph, channelx) = DMA_CHCTL_RESET_VALUE;
|
||||
DMA_CHCNT(dma_periph, channelx) = DMA_CHCNT_RESET_VALUE;
|
||||
DMA_CHPADDR(dma_periph, channelx) = DMA_CHPADDR_RESET_VALUE;
|
||||
DMA_CHM0ADDR(dma_periph, channelx) = DMA_CHMADDR_RESET_VALUE;
|
||||
DMA_CHM1ADDR(dma_periph, channelx) = DMA_CHMADDR_RESET_VALUE;
|
||||
DMA_CHFCTL(dma_periph, channelx) = DMA_CHFCTL_RESET_VALUE;
|
||||
if(channelx < DMA_CH4) {
|
||||
DMA_INTC0(dma_periph) |= DMA_FLAG_ADD(DMA_CHINTF_RESET_VALUE, channelx);
|
||||
} else {
|
||||
channelx -= (dma_channel_enum)4;
|
||||
DMA_INTC1(dma_periph) |= DMA_FLAG_ADD(DMA_CHINTF_RESET_VALUE, channelx);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the DMA single data mode parameters struct with the default values
|
||||
\param[in] init_struct: the initialization data needed to initialize DMA channel
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_single_data_para_struct_init(dma_single_data_parameter_struct *init_struct)
|
||||
{
|
||||
/* set the DMA struct with the default values */
|
||||
init_struct->periph_addr = 0U;
|
||||
init_struct->periph_inc = DMA_PERIPH_INCREASE_DISABLE;
|
||||
init_struct->memory0_addr = 0U;
|
||||
init_struct->memory_inc = DMA_MEMORY_INCREASE_DISABLE;
|
||||
init_struct->periph_memory_width = 0U;
|
||||
init_struct->circular_mode = DMA_CIRCULAR_MODE_DISABLE;
|
||||
init_struct->direction = DMA_PERIPH_TO_MEMORY;
|
||||
init_struct->number = 0U;
|
||||
init_struct->priority = DMA_PRIORITY_LOW;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the DMA multi data mode parameters struct with the default values
|
||||
\param[in] init_struct: the initialization data needed to initialize DMA channel
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_multi_data_para_struct_init(dma_multi_data_parameter_struct *init_struct)
|
||||
{
|
||||
/* set the DMA struct with the default values */
|
||||
init_struct->periph_addr = 0U;
|
||||
init_struct->periph_width = 0U;
|
||||
init_struct->periph_inc = DMA_PERIPH_INCREASE_DISABLE;
|
||||
init_struct->memory0_addr = 0U;
|
||||
init_struct->memory_width = 0U;
|
||||
init_struct->memory_inc = DMA_MEMORY_INCREASE_DISABLE;
|
||||
init_struct->memory_burst_width = 0U;
|
||||
init_struct->periph_burst_width = 0U;
|
||||
init_struct->circular_mode = DMA_CIRCULAR_MODE_DISABLE;
|
||||
init_struct->direction = DMA_PERIPH_TO_MEMORY;
|
||||
init_struct->number = 0U;
|
||||
init_struct->priority = DMA_PRIORITY_LOW;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize DMA single data mode
|
||||
\param[in] dma_periph: DMAx(x=0,1)
|
||||
\arg DMAx(x=0,1)
|
||||
\param[in] channelx: specify which DMA channel is initialized
|
||||
\arg DMA_CHx(x=0..7)
|
||||
\param[in] init_struct: the data needed to initialize DMA single data mode
|
||||
periph_addr: peripheral base address
|
||||
periph_inc: DMA_PERIPH_INCREASE_ENABLE,DMA_PERIPH_INCREASE_DISABLE,DMA_PERIPH_INCREASE_FIX
|
||||
memory0_addr: memory base address
|
||||
memory_inc: DMA_MEMORY_INCREASE_ENABLE,DMA_MEMORY_INCREASE_DISABLE
|
||||
periph_memory_width: DMA_PERIPH_WIDTH_8BIT,DMA_PERIPH_WIDTH_16BIT,DMA_PERIPH_WIDTH_32BIT
|
||||
circular_mode: DMA_CIRCULAR_MODE_ENABLE,DMA_CIRCULAR_MODE_DISABLE
|
||||
direction: DMA_PERIPH_TO_MEMORY,DMA_MEMORY_TO_PERIPH,DMA_MEMORY_TO_MEMORY
|
||||
number: the number of remaining data to be transferred by the DMA
|
||||
priority: DMA_PRIORITY_LOW,DMA_PRIORITY_MEDIUM,DMA_PRIORITY_HIGH,DMA_PRIORITY_ULTRA_HIGH
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_single_data_mode_init(uint32_t dma_periph, dma_channel_enum channelx, dma_single_data_parameter_struct *init_struct)
|
||||
{
|
||||
uint32_t ctl;
|
||||
|
||||
/* select single data mode */
|
||||
DMA_CHFCTL(dma_periph, channelx) &= ~DMA_CHXFCTL_MDMEN;
|
||||
|
||||
/* configure peripheral base address */
|
||||
DMA_CHPADDR(dma_periph, channelx) = init_struct->periph_addr;
|
||||
|
||||
/* configure memory base address */
|
||||
DMA_CHM0ADDR(dma_periph, channelx) = init_struct->memory0_addr;
|
||||
|
||||
/* configure the number of remaining data to be transferred */
|
||||
DMA_CHCNT(dma_periph, channelx) = init_struct->number;
|
||||
|
||||
/* configure peripheral and memory transfer width,channel priotity,transfer mode */
|
||||
ctl = DMA_CHCTL(dma_periph, channelx);
|
||||
ctl &= ~(DMA_CHXCTL_PWIDTH | DMA_CHXCTL_MWIDTH | DMA_CHXCTL_PRIO | DMA_CHXCTL_TM);
|
||||
ctl |= (init_struct->periph_memory_width | (init_struct->periph_memory_width << 2) | init_struct->priority | init_struct->direction);
|
||||
DMA_CHCTL(dma_periph, channelx) = ctl;
|
||||
|
||||
/* configure peripheral increasing mode */
|
||||
if(DMA_PERIPH_INCREASE_ENABLE == init_struct->periph_inc) {
|
||||
DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_PNAGA;
|
||||
} else if(DMA_PERIPH_INCREASE_DISABLE == init_struct->periph_inc) {
|
||||
DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_PNAGA;
|
||||
} else {
|
||||
DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_PAIF;
|
||||
}
|
||||
|
||||
/* configure memory increasing mode */
|
||||
if(DMA_MEMORY_INCREASE_ENABLE == init_struct->memory_inc) {
|
||||
DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_MNAGA;
|
||||
} else {
|
||||
DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_MNAGA;
|
||||
}
|
||||
|
||||
/* configure DMA circular mode */
|
||||
if(DMA_CIRCULAR_MODE_ENABLE == init_struct->circular_mode) {
|
||||
DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_CMEN;
|
||||
} else {
|
||||
DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_CMEN;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize DMA multi data mode
|
||||
\param[in] dma_periph: DMAx(x=0,1)
|
||||
\arg DMAx(x=0,1)
|
||||
\param[in] channelx: specify which DMA channel is initialized
|
||||
\arg DMA_CHx(x=0..7)
|
||||
\param[in] dma_multi_data_parameter_struct: the data needed to initialize DMA multi data mode
|
||||
periph_addr: peripheral base address
|
||||
periph_width: DMA_PERIPH_WIDTH_8BIT,DMA_PERIPH_WIDTH_16BIT,DMA_PERIPH_WIDTH_32BIT
|
||||
periph_inc: DMA_PERIPH_INCREASE_ENABLE,DMA_PERIPH_INCREASE_DISABLE,DMA_PERIPH_INCREASE_FIX
|
||||
memory0_addr: memory0 base address
|
||||
memory_width: DMA_MEMORY_WIDTH_8BIT,DMA_MEMORY_WIDTH_16BIT,DMA_MEMORY_WIDTH_32BIT
|
||||
memory_inc: DMA_MEMORY_INCREASE_ENABLE,DMA_MEMORY_INCREASE_DISABLE
|
||||
memory_burst_width: DMA_MEMORY_BURST_SINGLE,DMA_MEMORY_BURST_4_BEAT,DMA_MEMORY_BURST_8_BEAT,DMA_MEMORY_BURST_16_BEAT
|
||||
periph_burst_width: DMA_PERIPH_BURST_SINGLE,DMA_PERIPH_BURST_4_BEAT,DMA_PERIPH_BURST_8_BEAT,DMA_PERIPH_BURST_16_BEAT
|
||||
critical_value: DMA_FIFO_1_WORD,DMA_FIFO_2_WORD,DMA_FIFO_3_WORD,DMA_FIFO_4_WORD
|
||||
circular_mode: DMA_CIRCULAR_MODE_ENABLE,DMA_CIRCULAR_MODE_DISABLE
|
||||
direction: DMA_PERIPH_TO_MEMORY,DMA_MEMORY_TO_PERIPH,DMA_MEMORY_TO_MEMORY
|
||||
number: the number of remaining data to be transferred by the DMA
|
||||
priority: DMA_PRIORITY_LOW,DMA_PRIORITY_MEDIUM,DMA_PRIORITY_HIGH,DMA_PRIORITY_ULTRA_HIGH
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_multi_data_mode_init(uint32_t dma_periph, dma_channel_enum channelx, dma_multi_data_parameter_struct *init_struct)
|
||||
{
|
||||
uint32_t ctl;
|
||||
|
||||
#if 0
|
||||
/* select multi data mode and configure FIFO critical value */
|
||||
DMA_CHFCTL(dma_periph, channelx) |= (DMA_CHXFCTL_MDMEN | init_struct->critical_value);
|
||||
#else
|
||||
// /* select multi data mode and configure FIFO critical value */
|
||||
// DMA_CHFCTL(dma_periph, channelx) |= init_struct->critical_value;
|
||||
// DMA_CHFCTL(dma_periph, channelx)|= DMA_CHXFCTL_MDMEN;
|
||||
ctl = DMA_CHFCTL(dma_periph, channelx);
|
||||
ctl &= ~(DMA_FIFO_4_WORD | DMA_CHXFCTL_MDMEN);
|
||||
ctl |= init_struct->critical_value;
|
||||
DMA_CHFCTL(dma_periph, channelx) = ctl;
|
||||
DMA_CHFCTL(dma_periph, channelx)|= DMA_CHXFCTL_MDMEN;
|
||||
#endif
|
||||
/* configure peripheral base address */
|
||||
DMA_CHPADDR(dma_periph, channelx) = init_struct->periph_addr;
|
||||
|
||||
/* configure memory base address */
|
||||
DMA_CHM0ADDR(dma_periph, channelx) = init_struct->memory0_addr;
|
||||
|
||||
/* configure the number of remaining data to be transferred */
|
||||
DMA_CHCNT(dma_periph, channelx) = init_struct->number;
|
||||
|
||||
/* configure peripheral and memory transfer width,channel priotity,transfer mode,peripheral and memory burst transfer width */
|
||||
ctl = DMA_CHCTL(dma_periph, channelx);
|
||||
ctl &= ~(DMA_CHXCTL_PWIDTH | DMA_CHXCTL_MWIDTH | DMA_CHXCTL_PRIO | DMA_CHXCTL_TM | DMA_CHXCTL_PBURST | DMA_CHXCTL_MBURST);
|
||||
ctl |= (init_struct->periph_width | (init_struct->memory_width) | init_struct->priority | init_struct->direction | init_struct->memory_burst_width |
|
||||
init_struct->periph_burst_width);
|
||||
DMA_CHCTL(dma_periph, channelx) = ctl;
|
||||
|
||||
/* configure peripheral increasing mode */
|
||||
if(DMA_PERIPH_INCREASE_ENABLE == init_struct->periph_inc) {
|
||||
DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_PNAGA;
|
||||
} else if(DMA_PERIPH_INCREASE_DISABLE == init_struct->periph_inc) {
|
||||
DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_PNAGA;
|
||||
} else {
|
||||
DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_PAIF;
|
||||
}
|
||||
|
||||
/* configure memory increasing mode */
|
||||
if(DMA_MEMORY_INCREASE_ENABLE == init_struct->memory_inc) {
|
||||
DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_MNAGA;
|
||||
} else {
|
||||
DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_MNAGA;
|
||||
}
|
||||
|
||||
/* configure DMA circular mode */
|
||||
if(DMA_CIRCULAR_MODE_ENABLE == init_struct->circular_mode) {
|
||||
DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_CMEN;
|
||||
} else {
|
||||
DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_CMEN;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set DMA peripheral base address
|
||||
\param[in] dma_periph: DMAx(x=0,1)
|
||||
\arg DMAx(x=0,1)
|
||||
\param[in] channelx: specify which DMA channel to set peripheral base address
|
||||
\arg DMA_CHx(x=0..7)
|
||||
\param[in] address: peripheral base address
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_periph_address_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t address)
|
||||
{
|
||||
DMA_CHPADDR(dma_periph, channelx) = address;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set DMA Memory0 base address
|
||||
\param[in] dma_periph: DMAx(x=0,1)
|
||||
\arg DMAx(x=0,1)
|
||||
\param[in] channelx: specify which DMA channel to set Memory base address
|
||||
\arg DMA_CHx(x=0..7)
|
||||
\param[in] memory_flag: DMA_MEMORY_x(x=0,1)
|
||||
\param[in] address: Memory base address
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_memory_address_config(uint32_t dma_periph, dma_channel_enum channelx, uint8_t memory_flag, uint32_t address)
|
||||
{
|
||||
if(memory_flag) {
|
||||
DMA_CHM1ADDR(dma_periph, channelx) = address;
|
||||
} else {
|
||||
DMA_CHM0ADDR(dma_periph, channelx) = address;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set the number of remaining data to be transferred by the DMA
|
||||
\param[in] dma_periph: DMAx(x=0,1)
|
||||
\arg DMAx(x=0,1)
|
||||
\param[in] channelx: specify which DMA channel to set number
|
||||
\arg DMA_CHx(x=0..7)
|
||||
\param[in] number: the number of remaining data to be transferred by the DMA
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_transfer_number_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t number)
|
||||
{
|
||||
DMA_CHCNT(dma_periph, channelx) = number;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the number of remaining data to be transferred by the DMA
|
||||
\param[in] dma_periph: DMAx(x=0,1)
|
||||
\arg DMAx(x=0,1)
|
||||
\param[in] channelx: specify which DMA channel to set number
|
||||
\arg DMA_CHx(x=0..7)
|
||||
\param[out] none
|
||||
\retval uint32_t: the number of remaining data to be transferred by the DMA
|
||||
*/
|
||||
uint32_t dma_transfer_number_get(uint32_t dma_periph, dma_channel_enum channelx)
|
||||
{
|
||||
return (uint32_t)DMA_CHCNT(dma_periph, channelx);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure priority level of DMA channel
|
||||
\param[in] dma_periph: DMAx(x=0,1)
|
||||
\arg DMAx(x=0,1)
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..7)
|
||||
\param[in] priority: priority Level of this channel
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DMA_PRIORITY_LOW: low priority
|
||||
\arg DMA_PRIORITY_MEDIUM: medium priority
|
||||
\arg DMA_PRIORITY_HIGH: high priority
|
||||
\arg DMA_PRIORITY_ULTRA_HIGH: ultra high priority
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_priority_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t priority)
|
||||
{
|
||||
uint32_t ctl;
|
||||
/* acquire DMA_CHxCTL register */
|
||||
ctl = DMA_CHCTL(dma_periph, channelx);
|
||||
/* assign regiser */
|
||||
ctl &= ~DMA_CHXCTL_PRIO;
|
||||
ctl |= priority;
|
||||
DMA_CHCTL(dma_periph, channelx) = ctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure transfer burst beats of memory
|
||||
\param[in] dma_periph: DMAx(x=0,1)
|
||||
\arg DMAx(x=0,1)
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..7)
|
||||
\param[in] mbeat: transfer burst beats
|
||||
\arg DMA_MEMORY_BURST_SINGLE: memory transfer single burst
|
||||
\arg DMA_MEMORY_BURST_4_BEAT: memory transfer 4-beat burst
|
||||
\arg DMA_MEMORY_BURST_8_BEAT: memory transfer 8-beat burst
|
||||
\arg DMA_MEMORY_BURST_16_BEAT: memory transfer 16-beat burst
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_memory_burst_beats_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t mbeat)
|
||||
{
|
||||
uint32_t ctl;
|
||||
/* acquire DMA_CHxCTL register */
|
||||
ctl = DMA_CHCTL(dma_periph, channelx);
|
||||
/* assign regiser */
|
||||
ctl &= ~DMA_CHXCTL_MBURST;
|
||||
ctl |= mbeat;
|
||||
DMA_CHCTL(dma_periph, channelx) = ctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure transfer burst beats of peripheral
|
||||
\param[in] dma_periph: DMAx(x=0,1)
|
||||
\arg DMAx(x=0,1)
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..7)
|
||||
\param[in] pbeat: transfer burst beats
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DMA_PERIPH_BURST_SINGLE: peripheral transfer single burst
|
||||
\arg DMA_PERIPH_BURST_4_BEAT: peripheral transfer 4-beat burst
|
||||
\arg DMA_PERIPH_BURST_8_BEAT: peripheral transfer 8-beat burst
|
||||
\arg DMA_PERIPH_BURST_16_BEAT: peripheral transfer 16-beat burst
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_periph_burst_beats_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t pbeat)
|
||||
{
|
||||
uint32_t ctl;
|
||||
/* acquire DMA_CHxCTL register */
|
||||
ctl = DMA_CHCTL(dma_periph, channelx);
|
||||
/* assign regiser */
|
||||
ctl &= ~DMA_CHXCTL_PBURST;
|
||||
ctl |= pbeat;
|
||||
DMA_CHCTL(dma_periph, channelx) = ctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure transfer data size of memory
|
||||
\param[in] dma_periph: DMAx(x=0,1)
|
||||
\arg DMAx(x=0,1)
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..7)
|
||||
\param[in] msize: transfer data size of memory
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DMA_MEMORY_WIDTH_8BIT: transfer data size of memory is 8-bit
|
||||
\arg DMA_MEMORY_WIDTH_16BIT: transfer data size of memory is 16-bit
|
||||
\arg DMA_MEMORY_WIDTH_32BIT: transfer data size of memory is 32-bit
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_memory_width_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t msize)
|
||||
{
|
||||
uint32_t ctl;
|
||||
/* acquire DMA_CHxCTL register */
|
||||
ctl = DMA_CHCTL(dma_periph, channelx);
|
||||
/* assign regiser */
|
||||
ctl &= ~DMA_CHXCTL_MWIDTH;
|
||||
ctl |= msize;
|
||||
DMA_CHCTL(dma_periph, channelx) = ctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure transfer data size of peripheral
|
||||
\param[in] dma_periph: DMAx(x=0,1)
|
||||
\arg DMAx(x=0,1)
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..7)
|
||||
\param[in] msize: transfer data size of peripheral
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DMA_PERIPHERAL_WIDTH_8BIT: transfer data size of peripheral is 8-bit
|
||||
\arg DMA_PERIPHERAL_WIDTH_16BIT: transfer data size of peripheral is 16-bit
|
||||
\arg DMA_PERIPHERAL_WIDTH_32BIT: transfer data size of peripheral is 32-bit
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_periph_width_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t psize)
|
||||
{
|
||||
uint32_t ctl;
|
||||
/* acquire DMA_CHxCTL register */
|
||||
ctl = DMA_CHCTL(dma_periph, channelx);
|
||||
/* assign regiser */
|
||||
ctl &= ~DMA_CHXCTL_PWIDTH;
|
||||
ctl |= psize;
|
||||
DMA_CHCTL(dma_periph, channelx) = ctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure memory address generation generation_algorithm
|
||||
\param[in] dma_periph: DMAx(x=0,1)
|
||||
\arg DMAx(x=0,1)
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..7)
|
||||
\param[in] generation_algorithm: the address generation algorithm
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DMA_MEMORY_INCREASE_ENABLE: next address of memory is increasing address mode
|
||||
\arg DMA_MEMORY_INCREASE_DISABLE: next address of memory is fixed address mode
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_memory_address_generation_config(uint32_t dma_periph, dma_channel_enum channelx, uint8_t generation_algorithm)
|
||||
{
|
||||
if(DMA_MEMORY_INCREASE_ENABLE == generation_algorithm) {
|
||||
DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_MNAGA;
|
||||
} else {
|
||||
DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_MNAGA;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure peripheral address generation_algorithm
|
||||
\param[in] dma_periph: DMAx(x=0,1)
|
||||
\arg DMAx(x=0,1)
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..7)
|
||||
\param[in] generation_algorithm: the address generation algorithm
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DMA_PERIPH_INCREASE_ENABLE: next address of peripheral is increasing address mode
|
||||
\arg DMA_PERIPH_INCREASE_DISABLE: next address of peripheral is fixed address mode
|
||||
\arg DMA_PERIPH_INCREASE_FIX: increasing steps of peripheral address is fixed
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_peripheral_address_generation_config(uint32_t dma_periph, dma_channel_enum channelx, uint8_t generation_algorithm)
|
||||
{
|
||||
if(DMA_PERIPH_INCREASE_ENABLE == generation_algorithm) {
|
||||
DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_PNAGA;
|
||||
} else if(DMA_PERIPH_INCREASE_DISABLE == generation_algorithm) {
|
||||
DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_PNAGA;
|
||||
} else {
|
||||
DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_PNAGA;
|
||||
DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_PAIF;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DMA circulation mode
|
||||
\param[in] dma_periph: DMAx(x=0,1)
|
||||
\arg DMAx(x=0,1)
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..7)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_circulation_enable(uint32_t dma_periph, dma_channel_enum channelx)
|
||||
{
|
||||
DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_CMEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DMA circulation mode
|
||||
\param[in] dma_periph: DMAx(x=0,1)
|
||||
\arg DMAx(x=0,1)
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..7)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_circulation_disable(uint32_t dma_periph, dma_channel_enum channelx)
|
||||
{
|
||||
DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_CMEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DMA channel
|
||||
\param[in] dma_periph: DMAx(x=0,1)
|
||||
\arg DMAx(x=0,1)
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..7)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_channel_enable(uint32_t dma_periph, dma_channel_enum channelx)
|
||||
{
|
||||
DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_CHEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DMA channel
|
||||
\param[in] dma_periph: DMAx(x=0,1)
|
||||
\arg DMAx(x=0,1)
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..7)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_channel_disable(uint32_t dma_periph, dma_channel_enum channelx)
|
||||
{
|
||||
DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_CHEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the direction of data transfer on the channel
|
||||
\param[in] dma_periph: DMAx(x=0,1)
|
||||
\arg DMAx(x=0,1)
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..7)
|
||||
\param[in] direction: specify the direction of data transfer
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DMA_PERIPH_TO_MEMORY: read from peripheral and write to memory
|
||||
\arg DMA_MEMORY_TO_PERIPH: read from memory and write to peripheral
|
||||
\arg DMA_MEMORY_TO_MEMORY: read from memory and write to memory
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_transfer_direction_config(uint32_t dma_periph, dma_channel_enum channelx, uint8_t direction)
|
||||
{
|
||||
uint32_t ctl;
|
||||
/* acquire DMA_CHxCTL register */
|
||||
ctl = DMA_CHCTL(dma_periph, channelx);
|
||||
/* assign regiser */
|
||||
ctl &= ~DMA_CHXCTL_TM;
|
||||
ctl |= direction;
|
||||
|
||||
DMA_CHCTL(dma_periph, channelx) = ctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief DMA switch buffer mode config
|
||||
\param[in] dma_periph: DMAx(x=0,1)
|
||||
\arg DMAx(x=0,1)
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..7)
|
||||
\param[in] memory1_addr: memory1 base address
|
||||
\param[in] memory_select: DMA_MEMORY_0 or DMA_MEMORY_1
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_switch_buffer_mode_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t memory1_addr, uint32_t memory_select)
|
||||
{
|
||||
/* configure memory1 base address */
|
||||
DMA_CHM1ADDR(dma_periph, channelx) = memory1_addr;
|
||||
|
||||
if(DMA_MEMORY_0 == memory_select) {
|
||||
DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_MBS;
|
||||
} else {
|
||||
DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_MBS;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief DMA using memory get
|
||||
\param[in] dma_periph: DMAx(x=0,1)
|
||||
\arg DMAx(x=0,1)
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..7)
|
||||
\param[out] none
|
||||
\retval the using memory
|
||||
*/
|
||||
uint32_t dma_using_memory_get(uint32_t dma_periph, dma_channel_enum channelx)
|
||||
{
|
||||
if((DMA_CHCTL(dma_periph, channelx)) & DMA_CHXCTL_MBS) {
|
||||
return DMA_MEMORY_1;
|
||||
} else {
|
||||
return DMA_MEMORY_0;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief DMA channel peripheral select
|
||||
\param[in] dma_periph: DMAx(x=0,1)
|
||||
\arg DMAx(x=0,1)
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..7)
|
||||
\param[in] sub_periph: specify DMA channel peripheral
|
||||
\arg DMA_SUBPERIx(x=0..7)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_channel_subperipheral_select(uint32_t dma_periph, dma_channel_enum channelx, dma_subperipheral_enum sub_periph)
|
||||
{
|
||||
uint32_t ctl;
|
||||
/* acquire DMA_CHxCTL register */
|
||||
ctl = DMA_CHCTL(dma_periph, channelx);
|
||||
/* assign regiser */
|
||||
ctl &= ~DMA_CHXCTL_PERIEN;
|
||||
ctl |= ((uint32_t)sub_periph << CHXCTL_PERIEN_OFFSET);
|
||||
|
||||
DMA_CHCTL(dma_periph, channelx) = ctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief DMA flow controller configure
|
||||
\param[in] dma_periph: DMAx(x=0,1)
|
||||
\arg DMAx(x=0,1)
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..7)
|
||||
\param[in] controller: specify DMA flow controler
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DMA_FLOW_CONTROLLER_DMA: DMA is the flow controller
|
||||
\arg DMA_FLOW_CONTROLLER_PERI: peripheral is the flow controller
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_flow_controller_config(uint32_t dma_periph, dma_channel_enum channelx, uint32_t controller)
|
||||
{
|
||||
if(DMA_FLOW_CONTROLLER_DMA == controller) {
|
||||
DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_TFCS;
|
||||
} else {
|
||||
DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_TFCS;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief DMA switch buffer mode enable
|
||||
\param[in] dma_periph: DMAx(x=0,1)
|
||||
\arg DMAx(x=0,1)
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..7)
|
||||
\param[in] newvalue: ENABLE or DISABLE
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_switch_buffer_mode_enable(uint32_t dma_periph, dma_channel_enum channelx, ControlStatus newvalue)
|
||||
{
|
||||
if(ENABLE == newvalue) {
|
||||
/* switch buffer mode enable */
|
||||
DMA_CHCTL(dma_periph, channelx) |= DMA_CHXCTL_SBMEN;
|
||||
} else {
|
||||
/* switch buffer mode disable */
|
||||
DMA_CHCTL(dma_periph, channelx) &= ~DMA_CHXCTL_SBMEN;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief DMA FIFO status get
|
||||
\param[in] dma_periph: DMAx(x=0,1)
|
||||
\arg DMAx(x=0,1)
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..7)
|
||||
\param[out] none
|
||||
\retval the using memory
|
||||
*/
|
||||
uint32_t dma_fifo_status_get(uint32_t dma_periph, dma_channel_enum channelx)
|
||||
{
|
||||
return (DMA_CHFCTL(dma_periph, channelx) & DMA_CHXFCTL_FCNT);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get DMA flag is set or not
|
||||
\param[in] dma_periph: DMAx(x=0,1)
|
||||
\arg DMAx(x=0,1)
|
||||
\param[in] channelx: specify which DMA channel to get flag
|
||||
\arg DMA_CHx(x=0..7)
|
||||
\param[in] flag: specify get which flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DMA_FLAG_FEE: FIFO error and exception flag
|
||||
\arg DMA_FLAG_SDE: single data mode exception flag
|
||||
\arg DMA_FLAG_TAE: transfer access error flag
|
||||
\arg DMA_FLAG_HTF: half transfer finish flag
|
||||
\arg DMA_FLAG_FTF: full transger finish flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus dma_flag_get(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag)
|
||||
{
|
||||
if(channelx < DMA_CH4) {
|
||||
if(DMA_INTF0(dma_periph) & DMA_FLAG_ADD(flag, channelx)) {
|
||||
return SET;
|
||||
} else {
|
||||
return RESET;
|
||||
}
|
||||
} else {
|
||||
channelx -= (dma_channel_enum)4;
|
||||
if(DMA_INTF1(dma_periph) & DMA_FLAG_ADD(flag, channelx)) {
|
||||
return SET;
|
||||
} else {
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear DMA a channel flag
|
||||
\param[in] dma_periph: DMAx(x=0,1)
|
||||
\arg DMAx(x=0,1)
|
||||
\param[in] channelx: specify which DMA channel to get flag
|
||||
\arg DMA_CHx(x=0..7)
|
||||
\param[in] flag: specify get which flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DMA_FLAG_FEE: FIFO error and exception flag
|
||||
\arg DMA_FLAG_SDE: single data mode exception flag
|
||||
\arg DMA_FLAG_TAE: transfer access error flag
|
||||
\arg DMA_FLAG_HTF: half transfer finish flag
|
||||
\arg DMA_FLAG_FTF: full transger finish flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_flag_clear(uint32_t dma_periph, dma_channel_enum channelx, uint32_t flag)
|
||||
{
|
||||
if(channelx < DMA_CH4) {
|
||||
DMA_INTC0(dma_periph) |= DMA_FLAG_ADD(flag, channelx);
|
||||
} else {
|
||||
channelx -= (dma_channel_enum)4;
|
||||
DMA_INTC1(dma_periph) |= DMA_FLAG_ADD(flag, channelx);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DMA interrupt
|
||||
\param[in] dma_periph: DMAx(x=0,1)
|
||||
\arg DMAx(x=0,1)
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..7)
|
||||
\param[in] source: specify which interrupt to enbale
|
||||
only one parameters can be selected which are shown as below:
|
||||
\arg DMA_INT_SDE: single data mode exception interrupt enable
|
||||
\arg DMA_INT_TAE: tranfer access error interrupt enable
|
||||
\arg DMA_INT_HTF: half transfer finish interrupt enable
|
||||
\arg DMA_INT_FTF: full transfer finish interrupt enable
|
||||
\arg DMA_INT_FEE: FIFO exception interrupt enable
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_interrupt_enable(uint32_t dma_periph, dma_channel_enum channelx, uint32_t source)
|
||||
{
|
||||
if(DMA_CHXFCTL_FEEIE != source) {
|
||||
DMA_CHCTL(dma_periph, channelx) |= source;
|
||||
} else {
|
||||
DMA_CHFCTL(dma_periph, channelx) |= source;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DMA interrupt
|
||||
\param[in] dma_periph: DMAx(x=0,1)
|
||||
\arg DMAx(x=0,1)
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..7)
|
||||
\param[in] source: specify which interrupt to disbale
|
||||
only one parameters can be selected which are shown as below:
|
||||
\arg DMA_INT_SDE: single data mode exception interrupt enable
|
||||
\arg DMA_INT_TAE: tranfer access error interrupt enable
|
||||
\arg DMA_INT_HTF: half transfer finish interrupt enable
|
||||
\arg DMA_INT_FTF: full transfer finish interrupt enable
|
||||
\arg DMA_INT_FEE: FIFO exception interrupt enable
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_interrupt_disable(uint32_t dma_periph, dma_channel_enum channelx, uint32_t source)
|
||||
{
|
||||
if(DMA_CHXFCTL_FEEIE != source) {
|
||||
DMA_CHCTL(dma_periph, channelx) &= ~source;
|
||||
} else {
|
||||
DMA_CHFCTL(dma_periph, channelx) &= ~source;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get DMA interrupt flag is set or not
|
||||
\param[in] dma_periph: DMAx(x=0,1)
|
||||
\arg DMAx(x=0,1)
|
||||
\param[in] channelx: specify which DMA channel to get interrupt flag
|
||||
\arg DMA_CHx(x=0..7)
|
||||
\param[in] interrupt: specify get which flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DMA_INT_FLAG_FEE: FIFO error and exception flag
|
||||
\arg DMA_INT_FLAG_SDE: single data mode exception flag
|
||||
\arg DMA_INT_FLAG_TAE: transfer access error flag
|
||||
\arg DMA_INT_FLAG_HTF: half transfer finish flag
|
||||
\arg DMA_INT_FLAG_FTF: full transger finish flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus dma_interrupt_flag_get(uint32_t dma_periph, dma_channel_enum channelx, uint32_t interrupt)
|
||||
{
|
||||
uint32_t interrupt_enable = 0U, interrupt_flag = 0U;
|
||||
dma_channel_enum channel_flag_offset = channelx;
|
||||
if(channelx < DMA_CH4) {
|
||||
switch(interrupt) {
|
||||
case DMA_INTF_FEEIF:
|
||||
interrupt_flag = DMA_INTF0(dma_periph) & DMA_FLAG_ADD(interrupt, channelx);
|
||||
interrupt_enable = DMA_CHFCTL(dma_periph, channelx) & DMA_CHXFCTL_FEEIE;
|
||||
break;
|
||||
case DMA_INTF_SDEIF:
|
||||
interrupt_flag = DMA_INTF0(dma_periph) & DMA_FLAG_ADD(interrupt, channelx);
|
||||
interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_SDEIE;
|
||||
break;
|
||||
case DMA_INTF_TAEIF:
|
||||
interrupt_flag = DMA_INTF0(dma_periph) & DMA_FLAG_ADD(interrupt, channelx);
|
||||
interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_TAEIE;
|
||||
break;
|
||||
case DMA_INTF_HTFIF:
|
||||
interrupt_flag = DMA_INTF0(dma_periph) & DMA_FLAG_ADD(interrupt, channelx);
|
||||
interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_HTFIE;
|
||||
break;
|
||||
case DMA_INTF_FTFIF:
|
||||
interrupt_flag = (DMA_INTF0(dma_periph) & DMA_FLAG_ADD(interrupt, channelx));
|
||||
interrupt_enable = (DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_FTFIE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
channel_flag_offset -= (dma_channel_enum)4;
|
||||
switch(interrupt) {
|
||||
case DMA_INTF_FEEIF:
|
||||
interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(interrupt, channel_flag_offset);
|
||||
interrupt_enable = DMA_CHFCTL(dma_periph, channelx) & DMA_CHXFCTL_FEEIE;
|
||||
break;
|
||||
case DMA_INTF_SDEIF:
|
||||
interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(interrupt, channel_flag_offset);
|
||||
interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_SDEIE;
|
||||
break;
|
||||
case DMA_INTF_TAEIF:
|
||||
interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(interrupt, channel_flag_offset);
|
||||
interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_TAEIE;
|
||||
break;
|
||||
case DMA_INTF_HTFIF:
|
||||
interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(interrupt, channel_flag_offset);
|
||||
interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_HTFIE;
|
||||
break;
|
||||
case DMA_INTF_FTFIF:
|
||||
interrupt_flag = DMA_INTF1(dma_periph) & DMA_FLAG_ADD(interrupt, channel_flag_offset);
|
||||
interrupt_enable = DMA_CHCTL(dma_periph, channelx) & DMA_CHXCTL_FTFIE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(interrupt_flag && interrupt_enable) {
|
||||
return SET;
|
||||
} else {
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear DMA a channel interrupt flag
|
||||
\param[in] dma_periph: DMAx(x=0,1)
|
||||
\arg DMAx(x=0,1)
|
||||
\param[in] channelx: specify which DMA channel to clear interrupt flag
|
||||
\arg DMA_CHx(x=0..7)
|
||||
\param[in] interrupt: specify get which flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DMA_INT_FLAG_FEE: FIFO error and exception flag
|
||||
\arg DMA_INT_FLAG_SDE: single data mode exception flag
|
||||
\arg DMA_INT_FLAG_TAE: transfer access error flag
|
||||
\arg DMA_INT_FLAG_HTF: half transfer finish flag
|
||||
\arg DMA_INT_FLAG_FTF: full transger finish flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_interrupt_flag_clear(uint32_t dma_periph, dma_channel_enum channelx, uint32_t interrupt)
|
||||
{
|
||||
if(channelx < DMA_CH4) {
|
||||
DMA_INTC0(dma_periph) |= DMA_FLAG_ADD(interrupt, channelx);
|
||||
} else {
|
||||
channelx -= (dma_channel_enum)4;
|
||||
DMA_INTC1(dma_periph) |= DMA_FLAG_ADD(interrupt, channelx);
|
||||
}
|
||||
}
|
||||
+3519
File diff suppressed because it is too large
Load Diff
+1248
File diff suppressed because it is too large
Load Diff
+250
@@ -0,0 +1,250 @@
|
||||
/*!
|
||||
\file gd32f4xx_exti.c
|
||||
\brief EXTI driver
|
||||
\version 2024-12-20, V3.3.1, firmware for GD32F4xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2024, 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 "gd32f4xx_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_INTEN = EXTI_REG_RESET_VALUE;
|
||||
EXTI_EVEN = EXTI_REG_RESET_VALUE;
|
||||
EXTI_RTEN = EXTI_REG_RESET_VALUE;
|
||||
EXTI_FTEN = EXTI_REG_RESET_VALUE;
|
||||
EXTI_SWIEV = 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..22): 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 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 &= ~(uint32_t)linex;
|
||||
EXTI_EVEN &= ~(uint32_t)linex;
|
||||
EXTI_RTEN &= ~(uint32_t)linex;
|
||||
EXTI_FTEN &= ~(uint32_t)linex;
|
||||
|
||||
/* set the EXTI mode and enable the interrupts or events from EXTI line x */
|
||||
switch(mode) {
|
||||
case EXTI_INTERRUPT:
|
||||
EXTI_INTEN |= (uint32_t)linex;
|
||||
break;
|
||||
case EXTI_EVENT:
|
||||
EXTI_EVEN |= (uint32_t)linex;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* set the EXTI trigger type */
|
||||
switch(trig_type) {
|
||||
case EXTI_TRIG_RISING:
|
||||
EXTI_RTEN |= (uint32_t)linex;
|
||||
EXTI_FTEN &= ~(uint32_t)linex;
|
||||
break;
|
||||
case EXTI_TRIG_FALLING:
|
||||
EXTI_RTEN &= ~(uint32_t)linex;
|
||||
EXTI_FTEN |= (uint32_t)linex;
|
||||
break;
|
||||
case EXTI_TRIG_BOTH:
|
||||
EXTI_RTEN |= (uint32_t)linex;
|
||||
EXTI_FTEN |= (uint32_t)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..22): EXTI line x
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exti_interrupt_enable(exti_line_enum linex)
|
||||
{
|
||||
EXTI_INTEN |= (uint32_t)linex;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the interrupt 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..22): EXTI line x
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exti_interrupt_disable(exti_line_enum linex)
|
||||
{
|
||||
EXTI_INTEN &= ~(uint32_t)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..22): EXTI line x
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exti_event_enable(exti_line_enum linex)
|
||||
{
|
||||
EXTI_EVEN |= (uint32_t)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..22): EXTI line x
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exti_event_disable(exti_line_enum linex)
|
||||
{
|
||||
EXTI_EVEN &= ~(uint32_t)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..22): EXTI line x
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exti_software_interrupt_enable(exti_line_enum linex)
|
||||
{
|
||||
EXTI_SWIEV |= (uint32_t)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..22): EXTI line x
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exti_software_interrupt_disable(exti_line_enum linex)
|
||||
{
|
||||
EXTI_SWIEV &= ~(uint32_t)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..22): 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 & (uint32_t)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..22): EXTI line x
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exti_flag_clear(exti_line_enum linex)
|
||||
{
|
||||
EXTI_PD = (uint32_t)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..22): 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 & (uint32_t)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..22): EXTI line x
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exti_interrupt_flag_clear(exti_line_enum linex)
|
||||
{
|
||||
EXTI_PD = (uint32_t)linex;
|
||||
}
|
||||
+1064
File diff suppressed because it is too large
Load Diff
+215
@@ -0,0 +1,215 @@
|
||||
/*!
|
||||
\file gd32f4xx_fwdgt.c
|
||||
\brief FWDGT driver
|
||||
|
||||
\version 2024-12-20, V3.3.1, firmware for GD32F4xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2024, 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 "gd32f4xx_fwdgt.h"
|
||||
|
||||
/*!
|
||||
\brief enable write access to FWDGT_PSC and FWDGT_RLD
|
||||
\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 and FWDGT_RLD
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fwdgt_write_disable(void)
|
||||
{
|
||||
FWDGT_CTL = FWDGT_WRITEACCESS_DISABLE;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief start the free watchdog timer counter
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fwdgt_enable(void)
|
||||
{
|
||||
FWDGT_CTL = FWDGT_KEY_ENABLE;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the free watchdog timer 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 > 0U) && ((uint32_t)RESET != flag_status));
|
||||
|
||||
if ((uint32_t)RESET != flag_status){
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* configure FWDGT */
|
||||
FWDGT_PSC = (uint32_t)prescaler_value;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the free watchdog timer 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 > 0U) && ((uint32_t)RESET != flag_status));
|
||||
|
||||
if ((uint32_t)RESET != flag_status){
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
FWDGT_RLD = RLD_RLD(reload_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 > 0U) && ((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 > 0U) && ((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_STAT_PUD: a write operation to FWDGT_PSC register is on going
|
||||
\arg FWDGT_STAT_RUD: a write operation to FWDGT_RLD 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;
|
||||
}
|
||||
+431
@@ -0,0 +1,431 @@
|
||||
/*!
|
||||
\file gd32f4xx_gpio.c
|
||||
\brief GPIO driver
|
||||
|
||||
\version 2024-12-20, V3.3.1, firmware for GD32F4xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2024, 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 "gd32f4xx_gpio.h"
|
||||
|
||||
/*!
|
||||
\brief reset GPIO port
|
||||
\param[in] gpio_periph: GPIO port
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIOx(x = A,B,C,D,E,F,G,H,I)
|
||||
\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 GPIOI:
|
||||
/* reset GPIOI */
|
||||
rcu_periph_reset_enable(RCU_GPIOIRST);
|
||||
rcu_periph_reset_disable(RCU_GPIOIRST);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set GPIO mode
|
||||
\param[in] gpio_periph: GPIO port
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIOx(x = A,B,C,D,E,F,G,H,I)
|
||||
\param[in] mode: GPIO pin mode
|
||||
\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
|
||||
\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: GPIO port
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIOx(x = A,B,C,D,E,F,G,H,I)
|
||||
\param[in] otype: GPIO pin output mode
|
||||
\arg GPIO_OTYPE_PP: push pull mode
|
||||
\arg GPIO_OTYPE_OD: open drain mode
|
||||
\param[in] speed: GPIO pin output max speed
|
||||
\arg GPIO_OSPEED_2MHZ: output max speed 2MHz
|
||||
\arg GPIO_OSPEED_25MHZ: output max speed 25MHz
|
||||
\arg GPIO_OSPEED_50MHZ: output max speed 50MHz
|
||||
\arg GPIO_OSPEED_MAX: output max speed more than 50MHz
|
||||
\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 ospeedr;
|
||||
|
||||
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 */
|
||||
ospeedr = GPIO_OSPD(gpio_periph);
|
||||
|
||||
for(i = 0U; i < 16U; i++) {
|
||||
if((1U << i) & pin) {
|
||||
/* clear the specified pin output speed bits */
|
||||
ospeedr &= ~GPIO_OSPEED_MASK(i);
|
||||
/* set the specified pin output speed bits */
|
||||
ospeedr |= GPIO_OSPEED_SET(i, speed);
|
||||
}
|
||||
}
|
||||
GPIO_OSPD(gpio_periph) = ospeedr;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set GPIO pin bit
|
||||
\param[in] gpio_periph: GPIO port
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIOx(x = A,B,C,D,E,F,G,H,I)
|
||||
\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: GPIO port
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIOx(x = A,B,C,D,E,F,G,H,I)
|
||||
\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: GPIO port
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIOx(x = A,B,C,D,E,F,G,H,I)
|
||||
\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
|
||||
\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: GPIO port
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIOx(x = A,B,C,D,E,F,G,H,I)
|
||||
\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 get GPIO pin input status
|
||||
\param[in] gpio_periph: GPIO port
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIOx(x = A,B,C,D,E,F,G,H,I)
|
||||
\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 input status of GPIO pin: 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 all pins input status
|
||||
\param[in] gpio_periph: GPIO port
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIOx(x = A,B,C,D,E,F,G,H,I)
|
||||
\param[out] none
|
||||
\retval input status 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: GPIO port
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIOx(x = A,B,C,D,E,F,G,H,I)
|
||||
\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 output status of GPIO pin: 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: GPIO port
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIOx(x = A,B,C,D,E,F,G,H,I)
|
||||
\param[out] none
|
||||
\retval output status 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: GPIO port
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIOx(x = A,B,C,D,E,F,G,H,I)
|
||||
\param[in] alt_func_num: GPIO pin af function
|
||||
\arg GPIO_AF_0: SYSTEM
|
||||
\arg GPIO_AF_1: TIMER0, TIMER1
|
||||
\arg GPIO_AF_2: TIMER2, TIMER3, TIMER4
|
||||
\arg GPIO_AF_3: TIMER7, TIMER8, TIMER9, TIMER10
|
||||
\arg GPIO_AF_4: I2C0, I2C1, I2C2
|
||||
\arg GPIO_AF_5: SPI0, SPI1, SPI2, SPI3, SPI4, SPI5
|
||||
\arg GPIO_AF_6: SPI2, SPI3, SPI4
|
||||
\arg GPIO_AF_7: USART0, USART1, USART2, SPI1, SPI2
|
||||
\arg GPIO_AF_8: UART3, UART4, USART5, UART6, UART7
|
||||
\arg GPIO_AF_9: CAN0, CAN1, TLI, TIMER11, TIMER12, TIMER13, I2C1, I2C2, CTC
|
||||
\arg GPIO_AF_10: USB_FS, USB_HS
|
||||
\arg GPIO_AF_11: ENET
|
||||
\arg GPIO_AF_12: EXMC, SDIO, USB_HS
|
||||
\arg GPIO_AF_13: DCI
|
||||
\arg GPIO_AF_14: TLI
|
||||
\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: GPIO port
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIOx(x = A,B,C,D,E,F,G,H,I)
|
||||
\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: GPIO port
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIOx(x = A,B,C,D,E,F,G,H,I)
|
||||
\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: GPIO port
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg GPIOx(x = A,B,C,D,E,F,G,H,I)
|
||||
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void gpio_port_toggle(uint32_t gpio_periph)
|
||||
{
|
||||
GPIO_TG(gpio_periph) = 0x0000FFFFU;
|
||||
}
|
||||
+836
@@ -0,0 +1,836 @@
|
||||
/*!
|
||||
\file gd32f4xx_i2c.c
|
||||
\brief I2C driver
|
||||
|
||||
\version 2024-12-20, V3.3.1, firmware for GD32F4xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2024, 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 "gd32f4xx_i2c.h"
|
||||
|
||||
/* I2C register bit mask */
|
||||
#define I2CCLK_MAX ((uint32_t)0x0000003CU) /*!< i2cclk maximum value */
|
||||
#define I2CCLK_MIN ((uint32_t)0x00000002U) /*!< i2cclk minimum value */
|
||||
#define I2C_FLAG_MASK ((uint32_t)0x0000FFFFU) /*!< i2c flag 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 STAT1_PECV_OFFSET ((uint32_t)0x00000008U) /* bit offset of PECV in I2C_STAT1 */
|
||||
|
||||
/*!
|
||||
\brief reset I2C
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_deinit(uint32_t i2c_periph)
|
||||
{
|
||||
switch(i2c_periph) {
|
||||
case I2C0:
|
||||
/* reset I2C0 */
|
||||
rcu_periph_reset_enable(RCU_I2C0RST);
|
||||
rcu_periph_reset_disable(RCU_I2C0RST);
|
||||
break;
|
||||
case I2C1:
|
||||
/* reset I2C1 */
|
||||
rcu_periph_reset_enable(RCU_I2C1RST);
|
||||
rcu_periph_reset_disable(RCU_I2C1RST);
|
||||
break;
|
||||
case I2C2:
|
||||
/* reset I2C2 */
|
||||
rcu_periph_reset_enable(RCU_I2C2RST);
|
||||
rcu_periph_reset_disable(RCU_I2C2RST);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure I2C clock
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] clkspeed: I2C clock speed, supports standard mode (up to 100 kHz), fast mode (up to 400 kHz)
|
||||
\param[in] dutycyc: duty cycle in fast mode
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2C_DTCY_2: T_low/T_high = 2 in fast mode
|
||||
\arg I2C_DTCY_16_9: T_low/T_high = 16/9 in fast mode
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_clock_config(uint32_t i2c_periph, uint32_t clkspeed, uint32_t dutycyc)
|
||||
{
|
||||
uint32_t pclk1, clkc, freq, risetime;
|
||||
uint32_t temp;
|
||||
|
||||
pclk1 = rcu_clock_freq_get(CK_APB1);
|
||||
/* I2C peripheral clock frequency */
|
||||
freq = (uint32_t)(pclk1 / 1000000U);
|
||||
if(freq >= I2CCLK_MAX) {
|
||||
freq = I2CCLK_MAX;
|
||||
}
|
||||
temp = I2C_CTL1(i2c_periph);
|
||||
temp &= ~I2C_CTL1_I2CCLK;
|
||||
temp |= freq;
|
||||
|
||||
I2C_CTL1(i2c_periph) = temp;
|
||||
|
||||
if(100000U >= clkspeed) {
|
||||
/* the maximum SCL rise time is 1000ns in standard mode */
|
||||
risetime = (uint32_t)((pclk1 / 1000000U) + 1U);
|
||||
if(risetime >= I2CCLK_MAX) {
|
||||
I2C_RT(i2c_periph) = I2CCLK_MAX;
|
||||
} else if(risetime <= I2CCLK_MIN) {
|
||||
I2C_RT(i2c_periph) = I2CCLK_MIN;
|
||||
} else {
|
||||
I2C_RT(i2c_periph) = risetime;
|
||||
}
|
||||
clkc = (uint32_t)(pclk1 / (clkspeed * 2U));
|
||||
if(clkc < 0x04U) {
|
||||
/* the CLKC in standard mode minmum value is 4 */
|
||||
clkc = 0x04U;
|
||||
}
|
||||
|
||||
I2C_CKCFG(i2c_periph) |= (I2C_CKCFG_CLKC & clkc);
|
||||
|
||||
} else if(400000U >= clkspeed) {
|
||||
/* the maximum SCL rise time is 300ns in fast mode */
|
||||
I2C_RT(i2c_periph) = (uint32_t)(((freq * (uint32_t)300U) / (uint32_t)1000U) + (uint32_t)1U);
|
||||
if(I2C_DTCY_2 == dutycyc) {
|
||||
/* I2C duty cycle is 2 */
|
||||
clkc = (uint32_t)(pclk1 / (clkspeed * 3U));
|
||||
I2C_CKCFG(i2c_periph) &= ~I2C_CKCFG_DTCY;
|
||||
} else {
|
||||
/* I2C duty cycle is 16/9 */
|
||||
clkc = (uint32_t)(pclk1 / (clkspeed * 25U));
|
||||
I2C_CKCFG(i2c_periph) |= I2C_CKCFG_DTCY;
|
||||
}
|
||||
if(0U == (clkc & I2C_CKCFG_CLKC)) {
|
||||
/* the CLKC in fast mode minmum value is 1 */
|
||||
clkc |= 0x0001U;
|
||||
}
|
||||
I2C_CKCFG(i2c_periph) |= I2C_CKCFG_FAST;
|
||||
I2C_CKCFG(i2c_periph) |= clkc;
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure I2C address
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] mode:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2C_I2CMODE_ENABLE: I2C mode
|
||||
\arg I2C_SMBUSMODE_ENABLE: SMBus mode
|
||||
\param[in] addformat: 7bits or 10bits
|
||||
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[in] addr: I2C address
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_mode_addr_config(uint32_t i2c_periph, uint32_t mode, uint32_t addformat, uint32_t addr)
|
||||
{
|
||||
/* SMBus/I2C mode selected */
|
||||
uint32_t ctl = 0U;
|
||||
|
||||
ctl = I2C_CTL0(i2c_periph);
|
||||
ctl &= ~(I2C_CTL0_SMBEN);
|
||||
ctl |= mode;
|
||||
I2C_CTL0(i2c_periph) = ctl;
|
||||
/* configure address */
|
||||
addr = addr & I2C_ADDRESS_MASK;
|
||||
I2C_SADDR0(i2c_periph) = (addformat | addr);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief select SMBus type
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] type:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2C_SMBUS_DEVICE: SMBus mode device type
|
||||
\arg I2C_SMBUS_HOST: SMBus mode host type
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_smbus_type_config(uint32_t i2c_periph, uint32_t type)
|
||||
{
|
||||
if(I2C_SMBUS_HOST == type) {
|
||||
I2C_CTL0(i2c_periph) |= I2C_CTL0_SMBSEL;
|
||||
} else {
|
||||
I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_SMBSEL);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief whether or not to send an ACK
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] ack:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2C_ACK_ENABLE: ACK will be sent
|
||||
\arg I2C_ACK_DISABLE: ACK will not be sent
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_ack_config(uint32_t i2c_periph, uint32_t ack)
|
||||
{
|
||||
uint32_t ctl = 0U;
|
||||
|
||||
ctl = I2C_CTL0(i2c_periph);
|
||||
ctl &= ~(I2C_CTL0_ACKEN);
|
||||
ctl |= ack;
|
||||
I2C_CTL0(i2c_periph) = ctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure I2C POAP position
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] pos:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2C_ACKPOS_CURRENT: ACKEN bit decides whether or not to send ACK or not for the current byte
|
||||
\arg I2C_ACKPOS_NEXT: ACKEN bit decides whether or not to send ACK for the next byte
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_ackpos_config(uint32_t i2c_periph, uint32_t pos)
|
||||
{
|
||||
uint32_t ctl = 0U;
|
||||
/* configure I2C POAP position */
|
||||
ctl = I2C_CTL0(i2c_periph);
|
||||
ctl &= ~(I2C_CTL0_POAP);
|
||||
ctl |= pos;
|
||||
I2C_CTL0(i2c_periph) = ctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief master sends slave address
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] addr: slave address
|
||||
\param[in] trandirection: transmitter or receiver
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2C_TRANSMITTER: transmitter
|
||||
\arg I2C_RECEIVER: receiver
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_master_addressing(uint32_t i2c_periph, uint32_t addr, uint32_t trandirection)
|
||||
{
|
||||
/* master is a transmitter or a receiver */
|
||||
if(I2C_TRANSMITTER == trandirection) {
|
||||
addr = addr & I2C_TRANSMITTER;
|
||||
} else {
|
||||
addr = addr | I2C_RECEIVER;
|
||||
}
|
||||
/* send slave address */
|
||||
I2C_DATA(i2c_periph) = addr;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable dual-address mode
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] addr: the second address in dual-address mode
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_dualaddr_enable(uint32_t i2c_periph, uint32_t addr)
|
||||
{
|
||||
/* configure address */
|
||||
addr = addr & I2C_ADDRESS2_MASK;
|
||||
I2C_SADDR1(i2c_periph) = (I2C_SADDR1_DUADEN | addr);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable dual-address mode
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_dualaddr_disable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_SADDR1(i2c_periph) &= ~(I2C_SADDR1_DUADEN);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable I2C
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\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)
|
||||
\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)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_start_on_bus(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL0(i2c_periph) |= I2C_CTL0_START;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief generate a STOP condition on I2C bus
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_stop_on_bus(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_CTL0(i2c_periph) |= I2C_CTL0_STOP;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief I2C transmit data function
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] data: data of transmission
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_data_transmit(uint32_t i2c_periph, uint8_t data)
|
||||
{
|
||||
I2C_DATA(i2c_periph) = DATA_TRANS(data);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief I2C receive data function
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[out] none
|
||||
\retval data of received
|
||||
*/
|
||||
uint8_t i2c_data_receive(uint32_t i2c_periph)
|
||||
{
|
||||
return (uint8_t)DATA_RECV(I2C_DATA(i2c_periph));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure I2C DMA mode
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] dmastate:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2C_DMA_ON: enable DMA mode
|
||||
\arg I2C_DMA_OFF: disable DMA mode
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_dma_config(uint32_t i2c_periph, uint32_t dmastate)
|
||||
{
|
||||
/* configure I2C DMA function */
|
||||
uint32_t ctl = 0U;
|
||||
|
||||
ctl = I2C_CTL1(i2c_periph);
|
||||
ctl &= ~(I2C_CTL1_DMAON);
|
||||
ctl |= dmastate;
|
||||
I2C_CTL1(i2c_periph) = ctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure whether next DMA EOT is DMA last transfer or not
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] dmalast:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2C_DMALST_ON: next DMA EOT is the last transfer
|
||||
\arg I2C_DMALST_OFF: next DMA EOT is not the last transfer
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_dma_last_transfer_config(uint32_t i2c_periph, uint32_t dmalast)
|
||||
{
|
||||
/* configure DMA last transfer */
|
||||
uint32_t ctl = 0U;
|
||||
|
||||
ctl = I2C_CTL1(i2c_periph);
|
||||
ctl &= ~(I2C_CTL1_DMALST);
|
||||
ctl |= dmalast;
|
||||
I2C_CTL1(i2c_periph) = ctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief whether to stretch SCL low when data is not ready in slave mode
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] stretchpara:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2C_SCLSTRETCH_ENABLE: enable SCL stretching
|
||||
\arg I2C_SCLSTRETCH_DISABLE: disable SCL stretching
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_stretch_scl_low_config(uint32_t i2c_periph, uint32_t stretchpara)
|
||||
{
|
||||
/* configure I2C SCL strerching */
|
||||
uint32_t ctl = 0U;
|
||||
|
||||
ctl = I2C_CTL0(i2c_periph);
|
||||
ctl &= ~(I2C_CTL0_SS);
|
||||
ctl |= stretchpara;
|
||||
I2C_CTL0(i2c_periph) = ctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief whether or not to response to a general call
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] gcallpara:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2C_GCEN_ENABLE: slave will response to a general call
|
||||
\arg I2C_GCEN_DISABLE: slave will not response to a general call
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_slave_response_to_gcall_config(uint32_t i2c_periph, uint32_t gcallpara)
|
||||
{
|
||||
/* configure slave response to a general call enable or disable */
|
||||
uint32_t ctl = 0U;
|
||||
|
||||
ctl = I2C_CTL0(i2c_periph);
|
||||
ctl &= ~(I2C_CTL0_GCEN);
|
||||
ctl |= gcallpara;
|
||||
I2C_CTL0(i2c_periph) = ctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure software reset of I2C
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] sreset:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2C_SRESET_SET: I2C is under reset
|
||||
\arg I2C_SRESET_RESET: I2C is not under reset
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_software_reset_config(uint32_t i2c_periph, uint32_t sreset)
|
||||
{
|
||||
/* modify CTL0 and configure software reset I2C state */
|
||||
uint32_t ctl = 0U;
|
||||
|
||||
ctl = I2C_CTL0(i2c_periph);
|
||||
ctl &= ~(I2C_CTL0_SRESET);
|
||||
ctl |= sreset;
|
||||
I2C_CTL0(i2c_periph) = ctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure I2C PEC calculation
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] pecstate:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2C_PEC_ENABLE: PEC calculation on
|
||||
\arg I2C_PEC_DISABLE: PEC calculation off
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_pec_config(uint32_t i2c_periph, uint32_t pecstate)
|
||||
{
|
||||
/* on/off PEC calculation */
|
||||
uint32_t ctl = 0U;
|
||||
|
||||
ctl = I2C_CTL0(i2c_periph);
|
||||
ctl &= ~(I2C_CTL0_PECEN);
|
||||
ctl |= pecstate;
|
||||
I2C_CTL0(i2c_periph) = ctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure whether to transfer PEC value
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] pecpara:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2C_PECTRANS_ENABLE: transfer PEC value
|
||||
\arg I2C_PECTRANS_DISABLE: not transfer PEC value
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_pec_transfer_config(uint32_t i2c_periph, uint32_t pecpara)
|
||||
{
|
||||
/* whether to transfer PEC */
|
||||
uint32_t ctl = 0U;
|
||||
|
||||
ctl = I2C_CTL0(i2c_periph);
|
||||
ctl &= ~(I2C_CTL0_PECTRANS);
|
||||
ctl |= pecpara;
|
||||
I2C_CTL0(i2c_periph) = ctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get packet error checking value
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[out] none
|
||||
\retval PEC value
|
||||
*/
|
||||
uint8_t i2c_pec_value_get(uint32_t i2c_periph)
|
||||
{
|
||||
return (uint8_t)((I2C_STAT1(i2c_periph) & I2C_STAT1_PECV) >> STAT1_PECV_OFFSET);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure I2C alert through SMBA pin
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] smbuspara:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2C_SALTSEND_ENABLE: issue alert through SMBA pin
|
||||
\arg I2C_SALTSEND_DISABLE: not issue alert through SMBA pin
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_smbus_alert_config(uint32_t i2c_periph, uint32_t smbuspara)
|
||||
{
|
||||
/* configure smubus alert through SMBA pin */
|
||||
uint32_t ctl = 0U;
|
||||
|
||||
ctl = I2C_CTL0(i2c_periph);
|
||||
ctl &= ~(I2C_CTL0_SALT);
|
||||
ctl |= smbuspara;
|
||||
I2C_CTL0(i2c_periph) = ctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure I2C ARP protocol in SMBus
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] arpstate:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2C_ARP_ENABLE: enable ARP
|
||||
\arg I2C_ARP_DISABLE: disable ARP
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_smbus_arp_config(uint32_t i2c_periph, uint32_t arpstate)
|
||||
{
|
||||
/* enable or disable I2C ARP protocol*/
|
||||
uint32_t ctl = 0U;
|
||||
|
||||
ctl = I2C_CTL0(i2c_periph);
|
||||
ctl &= ~(I2C_CTL0_ARPEN);
|
||||
ctl |= arpstate;
|
||||
I2C_CTL0(i2c_periph) = ctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable analog noise filter
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_analog_noise_filter_disable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_FCTL(i2c_periph) |= I2C_FCTL_AFD;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable analog noise filter
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_analog_noise_filter_enable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_FCTL(i2c_periph) &= ~(I2C_FCTL_AFD);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure digital noise filter
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] dfilterpara: refer to i2c_digital_filter_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2C_DF_DISABLE: disable digital noise filter
|
||||
\arg I2C_DF_1PCLK: enable digital noise filter and the maximum filtered spiker's length 1 PCLK1
|
||||
\arg I2C_DF_2PCLK: enable digital noise filter and the maximum filtered spiker's length 2 PCLK1
|
||||
\arg I2C_DF_3PCLK: enable digital noise filter and the maximum filtered spiker's length 3 PCLK1
|
||||
\arg I2C_DF_4PCLK: enable digital noise filter and the maximum filtered spiker's length 4 PCLK1
|
||||
\arg I2C_DF_5PCLK: enable digital noise filter and the maximum filtered spiker's length 5 PCLK1
|
||||
\arg I2C_DF_6PCLK: enable digital noise filter and the maximum filtered spiker's length 6 PCLK1
|
||||
\arg I2C_DF_7PCLK: enable digital noise filter and the maximum filtered spiker's length 7 PCLK1
|
||||
\arg I2C_DF_8PCLK: enable digital noise filter and the maximum filtered spiker's length 8 PCLK1
|
||||
\arg I2C_DF_9PCLK: enable digital noise filter and the maximum filtered spiker's length 9 PCLK1
|
||||
\arg I2C_DF_10PCLK: enable digital noise filter and the maximum filtered spiker's length 10 PCLK1
|
||||
\arg I2C_DF_11CLK: enable digital noise filter and the maximum filtered spiker's length 11 PCLK1
|
||||
\arg I2C_DF_12CLK: enable digital noise filter and the maximum filtered spiker's length 12 PCLK1
|
||||
\arg I2C_DF_13PCLK: enable digital noise filter and the maximum filtered spiker's length 13 PCLK1
|
||||
\arg I2C_DF_14PCLK: enable digital noise filter and the maximum filtered spiker's length 14 PCLK1
|
||||
\arg I2C_DF_15PCLK: enable digital noise filter and the maximum filtered spiker's length 15 PCLK1
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_digital_noise_filter_config(uint32_t i2c_periph, i2c_digital_filter_enum dfilterpara)
|
||||
{
|
||||
I2C_FCTL(i2c_periph) |= dfilterpara;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable SAM_V interface
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_sam_enable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_SAMCS(i2c_periph) |= I2C_SAMCS_SAMEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable SAM_V interface
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_sam_disable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_SAMCS(i2c_periph) &= ~(I2C_SAMCS_SAMEN);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable SAM_V interface timeout detect
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_sam_timeout_enable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_SAMCS(i2c_periph) |= I2C_SAMCS_STOEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable SAM_V interface timeout detect
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_sam_timeout_disable(uint32_t i2c_periph)
|
||||
{
|
||||
I2C_SAMCS(i2c_periph) &= ~(I2C_SAMCS_STOEN);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get I2C flag status
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] flag: I2C flags, refer to i2c_flag_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2C_FLAG_SBSEND: start condition sent out in master mode
|
||||
\arg I2C_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode
|
||||
\arg I2C_FLAG_BTC: byte transmission finishes
|
||||
\arg I2C_FLAG_ADD10SEND: header of 10-bit address is sent in master mode
|
||||
\arg I2C_FLAG_STPDET: stop condition detected in slave mode
|
||||
\arg I2C_FLAG_RBNE: I2C_DATA is not empty during receiving
|
||||
\arg I2C_FLAG_TBE: I2C_DATA is empty during transmitting
|
||||
\arg I2C_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus
|
||||
\arg I2C_FLAG_LOSTARB: arbitration lost in master mode
|
||||
\arg I2C_FLAG_AERR: acknowledge error
|
||||
\arg I2C_FLAG_OUERR: over-run or under-run situation occurs in slave mode
|
||||
\arg I2C_FLAG_PECERR: PEC error when receiving data
|
||||
\arg I2C_FLAG_SMBTO: timeout signal in SMBus mode
|
||||
\arg I2C_FLAG_SMBALT: SMBus alert status
|
||||
\arg I2C_FLAG_MASTER: a flag indicating whether I2C block is in master or slave mode
|
||||
\arg I2C_FLAG_I2CBSY: busy flag
|
||||
\arg I2C_FLAG_TR: whether the I2C is a transmitter or a receiver
|
||||
\arg I2C_FLAG_RXGC: general call address (00h) received
|
||||
\arg I2C_FLAG_DEFSMB: default address of SMBus device
|
||||
\arg I2C_FLAG_HSTSMB: SMBus host header detected in slave mode
|
||||
\arg I2C_FLAG_DUMOD: dual flag in slave mode indicating which address is matched in dual-address mode
|
||||
\arg I2C_FLAG_TFF: txframe fall flag
|
||||
\arg I2C_FLAG_TFR: txframe rise flag
|
||||
\arg I2C_FLAG_RFF: rxframe fall flag
|
||||
\arg I2C_FLAG_RFR: rxframe rise flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus i2c_flag_get(uint32_t i2c_periph, i2c_flag_enum flag)
|
||||
{
|
||||
if(RESET != (I2C_REG_VAL(i2c_periph, flag) & BIT(I2C_BIT_POS(flag)))) {
|
||||
return SET;
|
||||
} else {
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear I2C flag status
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] flag: I2C flags, refer to i2c_flag_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2C_FLAG_SMBALT: SMBus alert status
|
||||
\arg I2C_FLAG_SMBTO: timeout signal in SMBus mode
|
||||
\arg I2C_FLAG_PECERR: PEC error when receiving data
|
||||
\arg I2C_FLAG_OUERR: over-run or under-run situation occurs in slave mode
|
||||
\arg I2C_FLAG_AERR: acknowledge error
|
||||
\arg I2C_FLAG_LOSTARB: arbitration lost in master mode
|
||||
\arg I2C_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus
|
||||
\arg I2C_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode
|
||||
\arg I2C_FLAG_TFF: txframe fall flag
|
||||
\arg I2C_FLAG_TFR: txframe rise flag
|
||||
\arg I2C_FLAG_RFF: rxframe fall flag
|
||||
\arg I2C_FLAG_RFR: rxframe rise flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_flag_clear(uint32_t i2c_periph, i2c_flag_enum flag)
|
||||
{
|
||||
if(I2C_FLAG_ADDSEND == flag) {
|
||||
/* read I2C_STAT0 and then read I2C_STAT1 to clear ADDSEND */
|
||||
I2C_STAT0(i2c_periph);
|
||||
I2C_STAT1(i2c_periph);
|
||||
} else {
|
||||
I2C_REG_VAL(i2c_periph, flag) &= ~BIT(I2C_BIT_POS(flag));
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable I2C interrupt
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] interrupt: I2C interrupts, refer to i2c_interrupt_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2C_INT_ERR: error interrupt
|
||||
\arg I2C_INT_EV: event interrupt
|
||||
\arg I2C_INT_BUF: buffer interrupt
|
||||
\arg I2C_INT_TFF: txframe fall interrupt
|
||||
\arg I2C_INT_TFR: txframe rise interrupt
|
||||
\arg I2C_INT_RFF: rxframe fall interrupt
|
||||
\arg I2C_INT_RFR: rxframe rise interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_interrupt_enable(uint32_t i2c_periph, i2c_interrupt_enum interrupt)
|
||||
{
|
||||
I2C_REG_VAL(i2c_periph, interrupt) |= BIT(I2C_BIT_POS(interrupt));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable I2C interrupt
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] interrupt: I2C interrupts, refer to i2c_interrupt_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2C_INT_ERR: error interrupt
|
||||
\arg I2C_INT_EV: event interrupt
|
||||
\arg I2C_INT_BUF: buffer interrupt
|
||||
\arg I2C_INT_TFF: txframe fall interrupt
|
||||
\arg I2C_INT_TFR: txframe rise interrupt
|
||||
\arg I2C_INT_RFF: rxframe fall interrupt
|
||||
\arg I2C_INT_RFR: rxframe rise interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_interrupt_disable(uint32_t i2c_periph, i2c_interrupt_enum interrupt)
|
||||
{
|
||||
I2C_REG_VAL(i2c_periph, interrupt) &= ~BIT(I2C_BIT_POS(interrupt));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get I2C interrupt flag status
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] int_flag: I2C interrupt flags, refer to i2c_interrupt_flag_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2C_INT_FLAG_SBSEND: start condition sent out in master mode interrupt flag
|
||||
\arg I2C_INT_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode interrupt flag
|
||||
\arg I2C_INT_FLAG_BTC: byte transmission finishes interrupt flag
|
||||
\arg I2C_INT_FLAG_ADD10SEND: header of 10-bit address is sent in master mode interrupt flag
|
||||
\arg I2C_INT_FLAG_STPDET: stop condition detected in slave mode interrupt flag
|
||||
\arg I2C_INT_FLAG_RBNE: I2C_DATA is not Empty during receiving interrupt flag
|
||||
\arg I2C_INT_FLAG_TBE: I2C_DATA is empty during transmitting interrupt flag
|
||||
\arg I2C_INT_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus interrupt flag
|
||||
\arg I2C_INT_FLAG_LOSTARB: arbitration lost in master mode interrupt flag
|
||||
\arg I2C_INT_FLAG_AERR: acknowledge error interrupt flag
|
||||
\arg I2C_INT_FLAG_OUERR: over-run or under-run situation occurs in slave mode interrupt flag
|
||||
\arg I2C_INT_FLAG_PECERR: PEC error when receiving data interrupt flag
|
||||
\arg I2C_INT_FLAG_SMBTO: timeout signal in SMBus mode interrupt flag
|
||||
\arg I2C_INT_FLAG_SMBALT: SMBus alert status interrupt flag
|
||||
\arg I2C_INT_FLAG_TFF: txframe fall interrupt flag
|
||||
\arg I2C_INT_FLAG_TFR: txframe rise interrupt flag
|
||||
\arg I2C_INT_FLAG_RFF: rxframe fall interrupt flag
|
||||
\arg I2C_INT_FLAG_RFR: rxframe rise 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 intenable = 0U, flagstatus = 0U, bufie;
|
||||
|
||||
/* check BUFIE */
|
||||
bufie = I2C_CTL1(i2c_periph)&I2C_CTL1_BUFIE;
|
||||
|
||||
/* get the interrupt enable bit status */
|
||||
intenable = (I2C_REG_VAL(i2c_periph, int_flag) & BIT(I2C_BIT_POS(int_flag)));
|
||||
/* get the corresponding flag bit status */
|
||||
flagstatus = (I2C_REG_VAL2(i2c_periph, int_flag) & BIT(I2C_BIT_POS2(int_flag)));
|
||||
|
||||
if((I2C_INT_FLAG_RBNE == int_flag) || (I2C_INT_FLAG_TBE == int_flag)) {
|
||||
if(intenable && bufie) {
|
||||
intenable = 1U;
|
||||
} else {
|
||||
intenable = 0U;
|
||||
}
|
||||
}
|
||||
if((0U != flagstatus) && (0U != intenable)) {
|
||||
return SET;
|
||||
} else {
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear I2C interrupt flag status
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] int_flag: I2C interrupt flags, refer to i2c_interrupt_flag_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2C_INT_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode interrupt flag
|
||||
\arg I2C_INT_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus interrupt flag
|
||||
\arg I2C_INT_FLAG_LOSTARB: arbitration lost in master mode interrupt flag
|
||||
\arg I2C_INT_FLAG_AERR: acknowledge error interrupt flag
|
||||
\arg I2C_INT_FLAG_OUERR: over-run or under-run situation occurs in slave mode interrupt flag
|
||||
\arg I2C_INT_FLAG_PECERR: PEC error when receiving data interrupt flag
|
||||
\arg I2C_INT_FLAG_SMBTO: timeout signal in SMBus mode interrupt flag
|
||||
\arg I2C_INT_FLAG_SMBALT: SMBus alert status interrupt flag
|
||||
\arg I2C_INT_FLAG_TFF: txframe fall interrupt flag
|
||||
\arg I2C_INT_FLAG_TFR: txframe rise interrupt flag
|
||||
\arg I2C_INT_FLAG_RFF: rxframe fall interrupt flag
|
||||
\arg I2C_INT_FLAG_RFR: rxframe rise interrupt flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_interrupt_flag_clear(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag)
|
||||
{
|
||||
if(I2C_INT_FLAG_ADDSEND == int_flag) {
|
||||
/* read I2C_STAT0 and then read I2C_STAT1 to clear ADDSEND */
|
||||
I2C_STAT0(i2c_periph);
|
||||
I2C_STAT1(i2c_periph);
|
||||
} else {
|
||||
I2C_REG_VAL2(i2c_periph, int_flag) &= ~BIT(I2C_BIT_POS2(int_flag));
|
||||
}
|
||||
}
|
||||
+636
@@ -0,0 +1,636 @@
|
||||
/*!
|
||||
\file gd32f4xx_ipa.c
|
||||
\brief IPA driver
|
||||
|
||||
\version 2024-12-20, V3.3.1, firmware for GD32F4xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2024, 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 "gd32f4xx_ipa.h"
|
||||
|
||||
#define IPA_DEFAULT_VALUE 0x00000000U
|
||||
|
||||
/*!
|
||||
\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 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
|
||||
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_ARG1555,FOREGROUND_PPF_ARGB4444,FOREGROUND_PPF_L8,FOREGROUND_PPF_AL44,
|
||||
FOREGROUND_PPF_AL88,FOREGROUND_PPF_L4,FOREGROUND_PPF_A8,FOREGROUND_PPF_A4)
|
||||
foreground_prered: foreground pre-defined red value
|
||||
foreground_pregreen: foreground pre-defined green value
|
||||
foreground_preblue: foreground pre-defined blue value
|
||||
\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;
|
||||
}
|
||||
|
||||
/*!
|
||||
\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_ARG1555,FOREGROUND_PPF_ARGB4444,FOREGROUND_PPF_L8,FOREGROUND_PPF_AL44,
|
||||
FOREGROUND_PPF_AL88,FOREGROUND_PPF_L4,FOREGROUND_PPF_A8,FOREGROUND_PPF_A4)
|
||||
foreground_prered: foreground pre-defined red value
|
||||
foreground_pregreen: foreground pre-defined green value
|
||||
foreground_preblue: foreground pre-defined blue value
|
||||
\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 |= (foreground_struct->foreground_prealpha << 24U);
|
||||
IPA_FPCTL |= foreground_struct->foreground_alpha_algorithm;
|
||||
IPA_FPCTL |= foreground_struct->foreground_pf;
|
||||
/* 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));
|
||||
|
||||
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
|
||||
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_BG_ALPHA_MODE_1,IPA_BG_ALPHA_MODE_2
|
||||
background_pf: background pixel format(BACKGROUND_PPF_ARGB8888,BACKGROUND_PPF_RGB888,BACKGROUND_PPF_RGB565,
|
||||
BACKGROUND_PPF_ARG1555,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
|
||||
\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_ARG1555,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
|
||||
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
|
||||
\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;
|
||||
}
|
||||
|
||||
/*!
|
||||
\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
|
||||
\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 configuration */
|
||||
IPA_DPCTL &= ~(IPA_DPCTL_DPF);
|
||||
IPA_DPCTL = destination_struct->destination_pf;
|
||||
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));
|
||||
|
||||
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 {
|
||||
IPA_FPCTL &= ~(IPA_FPCTL_FLPF);
|
||||
}
|
||||
/* 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 {
|
||||
IPA_BPCTL &= ~(IPA_BPCTL_BLPF);
|
||||
}
|
||||
/* 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) {
|
||||
IPA_ITCTL |= IPA_ITCTL_ITEN;
|
||||
} else {
|
||||
IPA_ITCTL &= ~(IPA_ITCTL_ITEN);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\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 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(0U != (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);
|
||||
}
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
/*!
|
||||
\file gd32f4xx_iref.c
|
||||
\brief IREF driver
|
||||
|
||||
\version 2024-12-20, V3.3.1, firmware for GD32F4xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2024, 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 "gd32f4xx_iref.h"
|
||||
|
||||
/*!
|
||||
\brief deinitialize IREF
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void iref_deinit(void)
|
||||
{
|
||||
rcu_periph_reset_enable(RCU_IREFRST);
|
||||
rcu_periph_reset_disable(RCU_IREFRST);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable IREF
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void iref_enable(void)
|
||||
{
|
||||
IREF_CTL |= IREF_CTL_CREN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable IREF
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void iref_disable(void)
|
||||
{
|
||||
IREF_CTL &= ~IREF_CTL_CREN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set IREF mode
|
||||
\param[in] step
|
||||
\arg IREF_MODE_LOW_POWER: 1uA step
|
||||
\arg IREF_MODE_HIGH_CURRENT: 8uA step
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void iref_mode_set(uint32_t step)
|
||||
{
|
||||
IREF_CTL &= ~IREF_CTL_SSEL;
|
||||
IREF_CTL |= step;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set IREF precision_trim_value
|
||||
\param[in] precisiontrim
|
||||
\arg IREF_CUR_PRECISION_TRIM_X(x=0..31): (-15+ x)%
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void iref_precision_trim_value_set(uint32_t precisiontrim)
|
||||
{
|
||||
IREF_CTL &= ~IREF_CTL_CPT;
|
||||
IREF_CTL |= precisiontrim;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set IREF sink mode
|
||||
\param[in] sinkmode
|
||||
\arg IREF_SOURCE_CURRENT : source current.
|
||||
\arg IREF_SINK_CURRENT: sink current
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void iref_sink_set(uint32_t sinkmode)
|
||||
{
|
||||
IREF_CTL &= ~IREF_CTL_SCMOD;
|
||||
IREF_CTL |= sinkmode;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set IREF step data
|
||||
\param[in] stepdata
|
||||
\arg IREF_CUR_STEP_DATA_X:(x=0..63): step*x
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
|
||||
void iref_step_data_config(uint32_t stepdata)
|
||||
{
|
||||
IREF_CTL &= ~IREF_CTL_CSDT;
|
||||
IREF_CTL |= stepdata;
|
||||
}
|
||||
+172
@@ -0,0 +1,172 @@
|
||||
/*!
|
||||
\file gd32f4xx_misc.c
|
||||
\brief MISC driver
|
||||
\version 2024-12-20, V3.3.1, firmware for GD32F4xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2024, 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 "gd32f4xx_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 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 */
|
||||
if(((SCB->AIRCR) & (uint32_t)0x700U) == NVIC_PRIGROUP_PRE0_SUB4) {
|
||||
temp_pre = 0U;
|
||||
temp_sub = 0x4U;
|
||||
} else if(((SCB->AIRCR) & (uint32_t)0x700U) == NVIC_PRIGROUP_PRE1_SUB3) {
|
||||
temp_pre = 1U;
|
||||
temp_sub = 0x3U;
|
||||
} else if(((SCB->AIRCR) & (uint32_t)0x700U) == NVIC_PRIGROUP_PRE2_SUB2) {
|
||||
temp_pre = 2U;
|
||||
temp_sub = 0x2U;
|
||||
} else if(((SCB->AIRCR) & (uint32_t)0x700U) == NVIC_PRIGROUP_PRE3_SUB1) {
|
||||
temp_pre = 3U;
|
||||
temp_sub = 0x1U;
|
||||
} else if(((SCB->AIRCR) & (uint32_t)0x700U) == NVIC_PRIGROUP_PRE4_SUB0) {
|
||||
temp_pre = 4U;
|
||||
temp_sub = 0x0U;
|
||||
} else {
|
||||
nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
|
||||
temp_pre = 2U;
|
||||
temp_sub = 0x2U;
|
||||
}
|
||||
/* 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[nvic_irq] = (uint8_t)temp_priority;
|
||||
/* enable the selected IRQ */
|
||||
NVIC->ISER[nvic_irq >> 0x05U] = (uint32_t)0x01U << (nvic_irq & (uint8_t)0x1FU);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable NVIC 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[nvic_irq >> 0x05] = (uint32_t)0x01 << (nvic_irq & (uint8_t)0x1F);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set the NVIC vector table base address
|
||||
\param[in] nvic_vict_tab: the RAM or FLASH base address
|
||||
\arg NVIC_VECTTAB_RAM: RAM base address
|
||||
\are 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_vict_tab, uint32_t offset)
|
||||
{
|
||||
SCB->VTOR = nvic_vict_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 lowpower 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 lowpower 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_HCLK: systick clock source is from HCLK
|
||||
\arg SYSTICK_CLKSOURCE_HCLK_DIV8: systick clock source is from HCLK/8
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
|
||||
void systick_clksource_set(uint32_t systick_clksource)
|
||||
{
|
||||
if(SYSTICK_CLKSOURCE_HCLK == systick_clksource) {
|
||||
/* set the systick clock source from HCLK */
|
||||
SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK;
|
||||
} else {
|
||||
/* set the systick clock source from HCLK/8 */
|
||||
SysTick->CTRL &= SYSTICK_CLKSOURCE_HCLK_DIV8;
|
||||
}
|
||||
}
|
||||
+410
@@ -0,0 +1,410 @@
|
||||
/*!
|
||||
\file gd32f4xx_pmu.c
|
||||
\brief PMU driver
|
||||
|
||||
\version 2024-12-20, V3.3.1, firmware for GD32F4xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2024, 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 "gd32f4xx_pmu.h"
|
||||
#include "core_cm4.h"
|
||||
|
||||
/*!
|
||||
\brief reset PMU registers
|
||||
\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:
|
||||
\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: voltage threshold is 3.1V
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_lvd_select(uint32_t lvdt_n)
|
||||
{
|
||||
/* disable LVD */
|
||||
PMU_CTL &= ~PMU_CTL_LVDEN;
|
||||
/* clear LVDT bits */
|
||||
PMU_CTL &= ~PMU_CTL_LVDT;
|
||||
/* set LVDT bits according to pmu_lvdt_n */
|
||||
PMU_CTL |= lvdt_n;
|
||||
/* enable LVD */
|
||||
PMU_CTL |= PMU_CTL_LVDEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable PMU lvd
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_lvd_disable(void)
|
||||
{
|
||||
/* disable LVD */
|
||||
PMU_CTL &= ~PMU_CTL_LVDEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief select LDO output voltage
|
||||
this bit set by software when the main PLL closed, before closing PLL, change the system clock to IRC16M or HXTAL
|
||||
\param[in] ldo_output:
|
||||
\arg PMU_LDOVS_LOW: low-driver mode enable in deep-sleep mode
|
||||
\arg PMU_LDOVS_MID: mid-driver mode disable in deep-sleep mode
|
||||
\arg PMU_LDOVS_HIGH: high-driver mode disable in deep-sleep mode
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_ldo_output_select(uint32_t ldo_output)
|
||||
{
|
||||
PMU_CTL &= ~PMU_CTL_LDOVS;
|
||||
PMU_CTL |= ldo_output;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable high-driver mode
|
||||
this bit set by software only when IRC16M or HXTAL used as system clock
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_highdriver_mode_enable(void)
|
||||
{
|
||||
PMU_CTL |= PMU_CTL_HDEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable high-driver mode
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_highdriver_mode_disable(void)
|
||||
{
|
||||
PMU_CTL &= ~PMU_CTL_HDEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief switch high-driver mode
|
||||
this bit set by software only when IRC16M or HXTAL used as system clock
|
||||
\param[in] highdr_switch:
|
||||
\arg PMU_HIGHDR_SWITCH_NONE: disable high-driver mode switch
|
||||
\arg PMU_HIGHDR_SWITCH_EN: enable high-driver mode switch
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_highdriver_switch_select(uint32_t highdr_switch)
|
||||
{
|
||||
/* wait for HDRF flag set */
|
||||
while(SET != pmu_flag_get(PMU_FLAG_HDRF)) {
|
||||
}
|
||||
PMU_CTL &= ~PMU_CTL_HDS;
|
||||
PMU_CTL |= highdr_switch;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable low-driver mode in deep-sleep
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_lowdriver_mode_enable(void)
|
||||
{
|
||||
PMU_CTL |= PMU_CTL_LDEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable low-driver mode in deep-sleep
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_lowdriver_mode_disable(void)
|
||||
{
|
||||
PMU_CTL &= ~PMU_CTL_LDEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief in deep-sleep mode, driver mode when use low power LDO
|
||||
\param[in] mode:
|
||||
\arg PMU_NORMALDR_LOWPWR: normal driver when use low power LDO
|
||||
\arg PMU_LOWDR_LOWPWR: low-driver mode enabled when LDEN is 11 and use low power LDO
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_lowpower_driver_config(uint32_t mode)
|
||||
{
|
||||
PMU_CTL &= ~PMU_CTL_LDLP;
|
||||
PMU_CTL |= mode;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief in deep-sleep mode, driver mode when use normal power LDO
|
||||
\param[in] mode:
|
||||
\arg PMU_NORMALDR_NORMALPWR: normal driver when use normal power LDO
|
||||
\arg PMU_LOWDR_NORMALPWR: low-driver mode enabled when LDEN is 11 and use normal power LDO
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_normalpower_driver_config(uint32_t mode)
|
||||
{
|
||||
PMU_CTL &= ~PMU_CTL_LDNP;
|
||||
PMU_CTL |= mode;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief PMU work in sleep mode
|
||||
\param[in] sleepmodecmd:
|
||||
\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-M4 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();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief PMU work in deep-sleep mode
|
||||
\param[in] ldo
|
||||
\arg PMU_LDO_NORMAL: LDO normal work when pmu enter deep-sleep mode
|
||||
\arg PMU_LDO_LOWPOWER: LDO work at low power mode when pmu enter deep-sleep mode
|
||||
\param[in] lowdrive:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg PMU_LOWDRIVER_DISABLE: Low-driver mode disable in deep-sleep mode
|
||||
\arg PMU_LOWDRIVER_ENABLE: Low-driver mode enable in deep-sleep mode
|
||||
\param[in] deepsleepmodecmd:
|
||||
\arg WFI_CMD: use WFI command
|
||||
\arg WFE_CMD: use WFE command
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_to_deepsleepmode(uint32_t ldo, uint32_t lowdrive, uint8_t deepsleepmodecmd)
|
||||
{
|
||||
static uint32_t reg_snap[4];
|
||||
/* clear stbmod and ldolp bits */
|
||||
PMU_CTL &= ~((uint32_t)(PMU_CTL_STBMOD | PMU_CTL_LDOLP | PMU_CTL_LDEN | PMU_CTL_LDNP | PMU_CTL_LDLP));
|
||||
|
||||
/* set ldolp bit according to pmu_ldo */
|
||||
PMU_CTL |= ldo;
|
||||
|
||||
/* configure low drive mode in deep-sleep mode */
|
||||
if(PMU_LOWDRIVER_ENABLE == lowdrive) {
|
||||
if(PMU_LDO_NORMAL == ldo) {
|
||||
PMU_CTL |= (uint32_t)(PMU_CTL_LDEN | PMU_CTL_LDNP);
|
||||
} else {
|
||||
PMU_CTL |= (uint32_t)(PMU_CTL_LDEN | PMU_CTL_LDLP);
|
||||
}
|
||||
}
|
||||
/* set sleepdeep bit of Cortex-M4 system control register */
|
||||
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
|
||||
|
||||
reg_snap[0] = REG32(0xE000E010U);
|
||||
reg_snap[1] = REG32(0xE000E100U);
|
||||
reg_snap[2] = REG32(0xE000E104U);
|
||||
reg_snap[3] = REG32(0xE000E108U);
|
||||
|
||||
REG32(0xE000E010U) &= 0x00010004U;
|
||||
REG32(0xE000E180U) = 0XFF7FF831U;
|
||||
REG32(0xE000E184U) = 0XBFFFF8FFU;
|
||||
REG32(0xE000E188U) = 0xFFFFEFFFU;
|
||||
|
||||
/* select WFI or WFE command to enter deep-sleep mode */
|
||||
if(WFI_CMD == deepsleepmodecmd) {
|
||||
__WFI();
|
||||
} else {
|
||||
__SEV();
|
||||
__WFE();
|
||||
__WFE();
|
||||
}
|
||||
|
||||
REG32(0xE000E010U) = reg_snap[0];
|
||||
REG32(0xE000E100U) = reg_snap[1];
|
||||
REG32(0xE000E104U) = reg_snap[2];
|
||||
REG32(0xE000E108U) = reg_snap[3];
|
||||
|
||||
/* reset sleepdeep bit of Cortex-M4 system control register */
|
||||
SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief pmu work in standby mode
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_to_standbymode(void)
|
||||
{
|
||||
/* set stbmod bit */
|
||||
PMU_CTL |= PMU_CTL_STBMOD;
|
||||
|
||||
/* reset wakeup flag */
|
||||
PMU_CTL |= PMU_CTL_WURST;
|
||||
|
||||
/* set sleepdeep bit of Cortex-M4 system control register */
|
||||
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
|
||||
|
||||
REG32(0xE000E010U) &= 0x00010004U;
|
||||
REG32(0xE000E180U) = 0XFFFFFFF3U;
|
||||
REG32(0xE000E184U) = 0XFFFFFDFFU;
|
||||
REG32(0xE000E188U) = 0xFFFFFFFFU;
|
||||
REG32(0xE000E18CU) = 0xFFFFFFFFU;
|
||||
|
||||
/* select WFI command to enter standby mode */
|
||||
__WFI();
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable PMU wakeup pin
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_wakeup_pin_enable(void)
|
||||
{
|
||||
PMU_CS |= PMU_CS_WUPEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable PMU wakeup pin
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_wakeup_pin_disable(void)
|
||||
{
|
||||
PMU_CS &= ~PMU_CS_WUPEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief backup SRAM LDO on
|
||||
\param[in] bkp_ldo:
|
||||
\arg PMU_BLDOON_OFF: backup SRAM LDO closed
|
||||
\arg PMU_BLDOON_ON: open the backup SRAM LDO
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_backup_ldo_config(uint32_t bkp_ldo)
|
||||
{
|
||||
PMU_CS &= ~PMU_CS_BLDOON;
|
||||
PMU_CS |= bkp_ldo;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable write access to the registers in backup domain
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_backup_write_enable(void)
|
||||
{
|
||||
PMU_CTL |= PMU_CTL_BKPWEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable write access to the registers in backup domain
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_backup_write_disable(void)
|
||||
{
|
||||
PMU_CTL &= ~PMU_CTL_BKPWEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get flag state
|
||||
\param[in] flag:
|
||||
\arg PMU_FLAG_WAKEUP: wakeup flag
|
||||
\arg PMU_FLAG_STANDBY: standby flag
|
||||
\arg PMU_FLAG_LVD: lvd flag
|
||||
\arg PMU_FLAG_BLDORF: backup SRAM LDO ready flag
|
||||
\arg PMU_FLAG_LDOVSRF: LDO voltage select ready flag
|
||||
\arg PMU_FLAG_HDRF: high-driver ready flag
|
||||
\arg PMU_FLAG_HDSRF: high-driver switch ready flag
|
||||
\arg PMU_FLAG_LDRF: low-driver mode ready flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus pmu_flag_get(uint32_t flag)
|
||||
{
|
||||
if(PMU_CS & flag) {
|
||||
return SET;
|
||||
} else {
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear flag bit
|
||||
\param[in] flag:
|
||||
\arg PMU_FLAG_RESET_WAKEUP: reset wakeup flag
|
||||
\arg PMU_FLAG_RESET_STANDBY: reset standby flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_flag_clear(uint32_t flag)
|
||||
{
|
||||
switch(flag) {
|
||||
case PMU_FLAG_RESET_WAKEUP:
|
||||
/* reset wakeup flag */
|
||||
PMU_CTL |= PMU_CTL_WURST;
|
||||
break;
|
||||
case PMU_FLAG_RESET_STANDBY:
|
||||
/* reset standby flag */
|
||||
PMU_CTL |= PMU_CTL_STBRST;
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
}
|
||||
+1329
File diff suppressed because it is too large
Load Diff
+1291
File diff suppressed because it is too large
Load Diff
+801
@@ -0,0 +1,801 @@
|
||||
/*!
|
||||
\file gd32f4xx_sdio.c
|
||||
\brief SDIO driver
|
||||
|
||||
\version 2024-12-20, V3.3.1, firmware for GD32F4xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2024, 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 "gd32f4xx_sdio.h"
|
||||
|
||||
/*!
|
||||
\brief deinitialize the SDIO
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_deinit(void)
|
||||
{
|
||||
rcu_periph_reset_enable(RCU_SDIORST);
|
||||
rcu_periph_reset_disable(RCU_SDIORST);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the SDIO clock
|
||||
\param[in] clock_edge: SDIO_CLK clock edge
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SDIO_SDIOCLKEDGE_RISING: select the rising edge of the SDIOCLK to generate SDIO_CLK
|
||||
\arg SDIO_SDIOCLKEDGE_FALLING: select the falling edge of the SDIOCLK to generate SDIO_CLK
|
||||
\param[in] clock_bypass: clock bypass
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SDIO_CLOCKBYPASS_ENABLE: clock bypass
|
||||
\arg SDIO_CLOCKBYPASS_DISABLE: no bypass
|
||||
\param[in] clock_powersave: SDIO_CLK clock dynamic switch on/off for power saving
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SDIO_CLOCKPWRSAVE_ENABLE: SDIO_CLK closed when bus is idle
|
||||
\arg SDIO_CLOCKPWRSAVE_DISABLE: SDIO_CLK clock is always on
|
||||
\param[in] clock_division: clock division, less than 512
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_clock_config(uint32_t clock_edge, uint32_t clock_bypass, uint32_t clock_powersave, uint16_t clock_division)
|
||||
{
|
||||
uint32_t clock_config = 0U;
|
||||
clock_config = SDIO_CLKCTL;
|
||||
/* reset the CLKEDGE, CLKBYP, CLKPWRSAV, DIV */
|
||||
clock_config &= ~(SDIO_CLKCTL_CLKEDGE | SDIO_CLKCTL_CLKBYP | SDIO_CLKCTL_CLKPWRSAV | SDIO_CLKCTL_DIV8 | SDIO_CLKCTL_DIV);
|
||||
/* if the clock division is greater or equal to 256, set the DIV[8] */
|
||||
if(clock_division >= 256U) {
|
||||
clock_config |= SDIO_CLKCTL_DIV8;
|
||||
clock_division -= 256U;
|
||||
}
|
||||
/* configure the SDIO_CLKCTL according to the parameters */
|
||||
clock_config |= (clock_edge | clock_bypass | clock_powersave | clock_division);
|
||||
SDIO_CLKCTL = clock_config;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable hardware clock control
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_hardware_clock_enable(void)
|
||||
{
|
||||
SDIO_CLKCTL |= SDIO_CLKCTL_HWCLKEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable hardware clock control
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_hardware_clock_disable(void)
|
||||
{
|
||||
SDIO_CLKCTL &= ~SDIO_CLKCTL_HWCLKEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set different SDIO card bus mode
|
||||
\param[in] bus_mode: SDIO card bus mode
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SDIO_BUSMODE_1BIT: 1-bit SDIO card bus mode
|
||||
\arg SDIO_BUSMODE_4BIT: 4-bit SDIO card bus mode
|
||||
\arg SDIO_BUSMODE_8BIT: 8-bit SDIO card bus mode
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_bus_mode_set(uint32_t bus_mode)
|
||||
{
|
||||
/* reset the SDIO card bus mode bits and set according to bus_mode */
|
||||
SDIO_CLKCTL &= ~SDIO_CLKCTL_BUSMODE;
|
||||
SDIO_CLKCTL |= bus_mode;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set the SDIO power state
|
||||
\param[in] power_state: SDIO power state
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SDIO_POWER_ON: SDIO power on
|
||||
\arg SDIO_POWER_OFF: SDIO power off
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_power_state_set(uint32_t power_state)
|
||||
{
|
||||
SDIO_PWRCTL = power_state;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the SDIO power state
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval SDIO power state
|
||||
\arg SDIO_POWER_ON: SDIO power on
|
||||
\arg SDIO_POWER_OFF: SDIO power off
|
||||
*/
|
||||
uint32_t sdio_power_state_get(void)
|
||||
{
|
||||
return SDIO_PWRCTL;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable SDIO_CLK clock output
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_clock_enable(void)
|
||||
{
|
||||
SDIO_CLKCTL |= SDIO_CLKCTL_CLKEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable SDIO_CLK clock output
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_clock_disable(void)
|
||||
{
|
||||
SDIO_CLKCTL &= ~SDIO_CLKCTL_CLKEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the command and response
|
||||
\param[in] cmd_index: command index, refer to the related specifications
|
||||
\param[in] cmd_argument: command argument, refer to the related specifications
|
||||
\param[in] response_type: response type
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SDIO_RESPONSETYPE_NO: no response
|
||||
\arg SDIO_RESPONSETYPE_SHORT: short response
|
||||
\arg SDIO_RESPONSETYPE_LONG: long response
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_command_response_config(uint32_t cmd_index, uint32_t cmd_argument, uint32_t response_type)
|
||||
{
|
||||
uint32_t cmd_config = 0U;
|
||||
/* disable the CSM */
|
||||
SDIO_CMDCTL &= ~SDIO_CMDCTL_CSMEN;
|
||||
/* reset the command index, command argument and response type */
|
||||
SDIO_CMDAGMT &= ~SDIO_CMDAGMT_CMDAGMT;
|
||||
SDIO_CMDAGMT = cmd_argument;
|
||||
cmd_config = SDIO_CMDCTL;
|
||||
cmd_config &= ~(SDIO_CMDCTL_CMDIDX | SDIO_CMDCTL_CMDRESP);
|
||||
/* configure SDIO_CMDCTL and SDIO_CMDAGMT according to the parameters */
|
||||
cmd_config |= (cmd_index | response_type);
|
||||
SDIO_CMDCTL = cmd_config;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set the command state machine wait type
|
||||
\param[in] wait_type: wait type
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SDIO_WAITTYPE_NO: not wait interrupt
|
||||
\arg SDIO_WAITTYPE_INTERRUPT: wait interrupt
|
||||
\arg SDIO_WAITTYPE_DATAEND: wait the end of data transfer
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_wait_type_set(uint32_t wait_type)
|
||||
{
|
||||
/* reset INTWAIT and WAITDEND */
|
||||
SDIO_CMDCTL &= ~(SDIO_CMDCTL_INTWAIT | SDIO_CMDCTL_WAITDEND);
|
||||
/* set the wait type according to wait_type */
|
||||
SDIO_CMDCTL |= wait_type;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the CSM(command state machine)
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_csm_enable(void)
|
||||
{
|
||||
SDIO_CMDCTL |= SDIO_CMDCTL_CSMEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the CSM(command state machine)
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_csm_disable(void)
|
||||
{
|
||||
SDIO_CMDCTL &= ~SDIO_CMDCTL_CSMEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the last response command index
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval last response command index
|
||||
*/
|
||||
uint8_t sdio_command_index_get(void)
|
||||
{
|
||||
return (uint8_t)SDIO_RSPCMDIDX;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the response for the last received command
|
||||
\param[in] sdio_responsex: SDIO response
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SDIO_RESPONSE0: card response[31:0]/card response[127:96]
|
||||
\arg SDIO_RESPONSE1: card response[95:64]
|
||||
\arg SDIO_RESPONSE2: card response[63:32]
|
||||
\arg SDIO_RESPONSE3: card response[31:1], plus bit 0
|
||||
\param[out] none
|
||||
\retval response for the last received command
|
||||
*/
|
||||
uint32_t sdio_response_get(uint32_t sdio_responsex)
|
||||
{
|
||||
uint32_t resp_content = 0U;
|
||||
switch(sdio_responsex) {
|
||||
case SDIO_RESPONSE0:
|
||||
resp_content = SDIO_RESP0;
|
||||
break;
|
||||
case SDIO_RESPONSE1:
|
||||
resp_content = SDIO_RESP1;
|
||||
break;
|
||||
case SDIO_RESPONSE2:
|
||||
resp_content = SDIO_RESP2;
|
||||
break;
|
||||
case SDIO_RESPONSE3:
|
||||
resp_content = SDIO_RESP3;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return resp_content;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the data timeout, data length and data block size
|
||||
\param[in] data_timeout: data timeout period in card bus clock periods
|
||||
\param[in] data_length: number of data bytes to be transferred
|
||||
\param[in] data_blocksize: size of data block for block transfer
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SDIO_DATABLOCKSIZE_1BYTE: block size = 1 byte
|
||||
\arg SDIO_DATABLOCKSIZE_2BYTES: block size = 2 bytes
|
||||
\arg SDIO_DATABLOCKSIZE_4BYTES: block size = 4 bytes
|
||||
\arg SDIO_DATABLOCKSIZE_8BYTES: block size = 8 bytes
|
||||
\arg SDIO_DATABLOCKSIZE_16BYTES: block size = 16 bytes
|
||||
\arg SDIO_DATABLOCKSIZE_32BYTES: block size = 32 bytes
|
||||
\arg SDIO_DATABLOCKSIZE_64BYTES: block size = 64 bytes
|
||||
\arg SDIO_DATABLOCKSIZE_128BYTES: block size = 128 bytes
|
||||
\arg SDIO_DATABLOCKSIZE_256BYTES: block size = 256 bytes
|
||||
\arg SDIO_DATABLOCKSIZE_512BYTES: block size = 512 bytes
|
||||
\arg SDIO_DATABLOCKSIZE_1024BYTES: block size = 1024 bytes
|
||||
\arg SDIO_DATABLOCKSIZE_2048BYTES: block size = 2048 bytes
|
||||
\arg SDIO_DATABLOCKSIZE_4096BYTES: block size = 4096 bytes
|
||||
\arg SDIO_DATABLOCKSIZE_8192BYTES: block size = 8192 bytes
|
||||
\arg SDIO_DATABLOCKSIZE_16384BYTES: block size = 16384 bytes
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_data_config(uint32_t data_timeout, uint32_t data_length, uint32_t data_blocksize)
|
||||
{
|
||||
/* reset data timeout, data length and data block size */
|
||||
SDIO_DATATO &= ~SDIO_DATATO_DATATO;
|
||||
SDIO_DATALEN &= ~SDIO_DATALEN_DATALEN;
|
||||
SDIO_DATACTL &= ~SDIO_DATACTL_BLKSZ;
|
||||
/* configure the related parameters of data */
|
||||
SDIO_DATATO = data_timeout;
|
||||
SDIO_DATALEN = data_length;
|
||||
SDIO_DATACTL |= data_blocksize;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the data transfer mode and direction
|
||||
\param[in] transfer_mode: mode of data transfer
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SDIO_TRANSMODE_BLOCK: block transfer
|
||||
\arg SDIO_TRANSMODE_STREAM: stream transfer or SDIO multibyte transfer
|
||||
\param[in] transfer_direction: data transfer direction, read or write
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SDIO_TRANSDIRECTION_TOCARD: write data to card
|
||||
\arg SDIO_TRANSDIRECTION_TOSDIO: read data from card
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_data_transfer_config(uint32_t transfer_mode, uint32_t transfer_direction)
|
||||
{
|
||||
uint32_t data_trans = 0U;
|
||||
/* reset the data transfer mode, transfer direction and set according to the parameters */
|
||||
data_trans = SDIO_DATACTL;
|
||||
data_trans &= ~(SDIO_DATACTL_TRANSMOD | SDIO_DATACTL_DATADIR);
|
||||
data_trans |= (transfer_mode | transfer_direction);
|
||||
SDIO_DATACTL = data_trans;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the DSM(data state machine) for data transfer
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_dsm_enable(void)
|
||||
{
|
||||
SDIO_DATACTL |= SDIO_DATACTL_DATAEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the DSM(data state machine)
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_dsm_disable(void)
|
||||
{
|
||||
SDIO_DATACTL &= ~SDIO_DATACTL_DATAEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief write data(one word) to the transmit FIFO
|
||||
\param[in] data: 32-bit data write to card
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_data_write(uint32_t data)
|
||||
{
|
||||
SDIO_FIFO = data;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief read data(one word) from the receive FIFO
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval received data
|
||||
*/
|
||||
uint32_t sdio_data_read(void)
|
||||
{
|
||||
return SDIO_FIFO;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the number of remaining data bytes to be transferred to card
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval number of remaining data bytes to be transferred
|
||||
*/
|
||||
uint32_t sdio_data_counter_get(void)
|
||||
{
|
||||
return SDIO_DATACNT;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the number of words remaining to be written or read from FIFO
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval remaining number of words
|
||||
*/
|
||||
uint32_t sdio_fifo_counter_get(void)
|
||||
{
|
||||
return SDIO_FIFOCNT;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the DMA request for SDIO
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_dma_enable(void)
|
||||
{
|
||||
SDIO_DATACTL |= SDIO_DATACTL_DMAEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the DMA request for SDIO
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_dma_disable(void)
|
||||
{
|
||||
SDIO_DATACTL &= ~SDIO_DATACTL_DMAEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the flags state of SDIO
|
||||
\param[in] flag: flags state of SDIO
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg SDIO_FLAG_CCRCERR: command response received (CRC check failed) flag
|
||||
\arg SDIO_FLAG_DTCRCERR: data block sent/received (CRC check failed) flag
|
||||
\arg SDIO_FLAG_CMDTMOUT: command response timeout flag
|
||||
\arg SDIO_FLAG_DTTMOUT: data timeout flag
|
||||
\arg SDIO_FLAG_TXURE: transmit FIFO underrun error occurs flag
|
||||
\arg SDIO_FLAG_RXORE: received FIFO overrun error occurs flag
|
||||
\arg SDIO_FLAG_CMDRECV: command response received (CRC check passed) flag
|
||||
\arg SDIO_FLAG_CMDSEND: command sent (no response required) flag
|
||||
\arg SDIO_FLAG_DTEND: data end (data counter, SDIO_DATACNT, is zero) flag
|
||||
\arg SDIO_FLAG_STBITE: start bit error in the bus flag
|
||||
\arg SDIO_FLAG_DTBLKEND: data block sent/received (CRC check passed) flag
|
||||
\arg SDIO_FLAG_CMDRUN: command transmission in progress flag
|
||||
\arg SDIO_FLAG_TXRUN: data transmission in progress flag
|
||||
\arg SDIO_FLAG_RXRUN: data reception in progress flag
|
||||
\arg SDIO_FLAG_TFH: transmit FIFO is half empty flag: at least 8 words can be written into the FIFO
|
||||
\arg SDIO_FLAG_RFH: receive FIFO is half full flag: at least 8 words can be read in the FIFO
|
||||
\arg SDIO_FLAG_TFF: transmit FIFO is full flag
|
||||
\arg SDIO_FLAG_RFF: receive FIFO is full flag
|
||||
\arg SDIO_FLAG_TFE: transmit FIFO is empty flag
|
||||
\arg SDIO_FLAG_RFE: receive FIFO is empty flag
|
||||
\arg SDIO_FLAG_TXDTVAL: data is valid in transmit FIFO flag
|
||||
\arg SDIO_FLAG_RXDTVAL: data is valid in receive FIFO flag
|
||||
\arg SDIO_FLAG_SDIOINT: SD I/O interrupt received flag
|
||||
\arg SDIO_FLAG_ATAEND: CE-ATA command completion signal received (only for CMD61) flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus sdio_flag_get(uint32_t flag)
|
||||
{
|
||||
FlagStatus temp_flag = RESET;
|
||||
if(RESET != (SDIO_STAT & flag)) {
|
||||
temp_flag = SET;
|
||||
}
|
||||
return temp_flag;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear the pending flags of SDIO
|
||||
\param[in] flag: flags state of SDIO
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg SDIO_FLAG_CCRCERR: command response received (CRC check failed) flag
|
||||
\arg SDIO_FLAG_DTCRCERR: data block sent/received (CRC check failed) flag
|
||||
\arg SDIO_FLAG_CMDTMOUT: command response timeout flag
|
||||
\arg SDIO_FLAG_DTTMOUT: data timeout flag
|
||||
\arg SDIO_FLAG_TXURE: transmit FIFO underrun error occurs flag
|
||||
\arg SDIO_FLAG_RXORE: received FIFO overrun error occurs flag
|
||||
\arg SDIO_FLAG_CMDRECV: command response received (CRC check passed) flag
|
||||
\arg SDIO_FLAG_CMDSEND: command sent (no response required) flag
|
||||
\arg SDIO_FLAG_DTEND: data end (data counter, SDIO_DATACNT, is zero) flag
|
||||
\arg SDIO_FLAG_STBITE: start bit error in the bus flag
|
||||
\arg SDIO_FLAG_DTBLKEND: data block sent/received (CRC check passed) flag
|
||||
\arg SDIO_FLAG_SDIOINT: SD I/O interrupt received flag
|
||||
\arg SDIO_FLAG_ATAEND: CE-ATA command completion signal received (only for CMD61) flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_flag_clear(uint32_t flag)
|
||||
{
|
||||
SDIO_INTC = flag;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the SDIO interrupt
|
||||
\param[in] int_flag: interrupt flags state of SDIO
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg SDIO_INT_CCRCERR: SDIO CCRCERR interrupt
|
||||
\arg SDIO_INT_DTCRCERR: SDIO DTCRCERR interrupt
|
||||
\arg SDIO_INT_CMDTMOUT: SDIO CMDTMOUT interrupt
|
||||
\arg SDIO_INT_DTTMOUT: SDIO DTTMOUT interrupt
|
||||
\arg SDIO_INT_TXURE: SDIO TXURE interrupt
|
||||
\arg SDIO_INT_RXORE: SDIO RXORE interrupt
|
||||
\arg SDIO_INT_CMDRECV: SDIO CMDRECV interrupt
|
||||
\arg SDIO_INT_CMDSEND: SDIO CMDSEND interrupt
|
||||
\arg SDIO_INT_DTEND: SDIO DTEND interrupt
|
||||
\arg SDIO_INT_STBITE: SDIO STBITE interrupt
|
||||
\arg SDIO_INT_DTBLKEND: SDIO DTBLKEND interrupt
|
||||
\arg SDIO_INT_CMDRUN: SDIO CMDRUN interrupt
|
||||
\arg SDIO_INT_TXRUN: SDIO TXRUN interrupt
|
||||
\arg SDIO_INT_RXRUN: SDIO RXRUN interrupt
|
||||
\arg SDIO_INT_TFH: SDIO TFH interrupt
|
||||
\arg SDIO_INT_RFH: SDIO RFH interrupt
|
||||
\arg SDIO_INT_TFF: SDIO TFF interrupt
|
||||
\arg SDIO_INT_RFF: SDIO RFF interrupt
|
||||
\arg SDIO_INT_TFE: SDIO TFE interrupt
|
||||
\arg SDIO_INT_RFE: SDIO RFE interrupt
|
||||
\arg SDIO_INT_TXDTVAL: SDIO TXDTVAL interrupt
|
||||
\arg SDIO_INT_RXDTVAL: SDIO RXDTVAL interrupt
|
||||
\arg SDIO_INT_SDIOINT: SDIO SDIOINT interrupt
|
||||
\arg SDIO_INT_ATAEND: SDIO ATAEND interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_interrupt_enable(uint32_t int_flag)
|
||||
{
|
||||
SDIO_INTEN |= int_flag;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the SDIO interrupt
|
||||
\param[in] int_flag: interrupt flags state of SDIO
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg SDIO_INT_CCRCERR: SDIO CCRCERR interrupt
|
||||
\arg SDIO_INT_DTCRCERR: SDIO DTCRCERR interrupt
|
||||
\arg SDIO_INT_CMDTMOUT: SDIO CMDTMOUT interrupt
|
||||
\arg SDIO_INT_DTTMOUT: SDIO DTTMOUT interrupt
|
||||
\arg SDIO_INT_TXURE: SDIO TXURE interrupt
|
||||
\arg SDIO_INT_RXORE: SDIO RXORE interrupt
|
||||
\arg SDIO_INT_CMDRECV: SDIO CMDRECV interrupt
|
||||
\arg SDIO_INT_CMDSEND: SDIO CMDSEND interrupt
|
||||
\arg SDIO_INT_DTEND: SDIO DTEND interrupt
|
||||
\arg SDIO_INT_STBITE: SDIO STBITE interrupt
|
||||
\arg SDIO_INT_DTBLKEND: SDIO DTBLKEND interrupt
|
||||
\arg SDIO_INT_CMDRUN: SDIO CMDRUN interrupt
|
||||
\arg SDIO_INT_TXRUN: SDIO TXRUN interrupt
|
||||
\arg SDIO_INT_RXRUN: SDIO RXRUN interrupt
|
||||
\arg SDIO_INT_TFH: SDIO TFH interrupt
|
||||
\arg SDIO_INT_RFH: SDIO RFH interrupt
|
||||
\arg SDIO_INT_TFF: SDIO TFF interrupt
|
||||
\arg SDIO_INT_RFF: SDIO RFF interrupt
|
||||
\arg SDIO_INT_TFE: SDIO TFE interrupt
|
||||
\arg SDIO_INT_RFE: SDIO RFE interrupt
|
||||
\arg SDIO_INT_TXDTVAL: SDIO TXDTVAL interrupt
|
||||
\arg SDIO_INT_RXDTVAL: SDIO RXDTVAL interrupt
|
||||
\arg SDIO_INT_SDIOINT: SDIO SDIOINT interrupt
|
||||
\arg SDIO_INT_ATAEND: SDIO ATAEND interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_interrupt_disable(uint32_t int_flag)
|
||||
{
|
||||
SDIO_INTEN &= ~int_flag;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the interrupt flags state of SDIO
|
||||
\param[in] int_flag: interrupt flags state of SDIO
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg SDIO_INT_FLAG_CCRCERR: SDIO CCRCERR interrupt flag
|
||||
\arg SDIO_INT_FLAG_DTCRCERR: SDIO DTCRCERR interrupt flag
|
||||
\arg SDIO_INT_FLAG_CMDTMOUT: SDIO CMDTMOUT interrupt flag
|
||||
\arg SDIO_INT_FLAG_DTTMOUT: SDIO DTTMOUT interrupt flag
|
||||
\arg SDIO_INT_FLAG_TXURE: SDIO TXURE interrupt flag
|
||||
\arg SDIO_INT_FLAG_RXORE: SDIO RXORE interrupt flag
|
||||
\arg SDIO_INT_FLAG_CMDRECV: SDIO CMDRECV interrupt flag
|
||||
\arg SDIO_INT_FLAG_CMDSEND: SDIO CMDSEND interrupt flag
|
||||
\arg SDIO_INT_FLAG_DTEND: SDIO DTEND interrupt flag
|
||||
\arg SDIO_INT_FLAG_STBITE: SDIO STBITE interrupt flag
|
||||
\arg SDIO_INT_FLAG_DTBLKEND: SDIO DTBLKEND interrupt flag
|
||||
\arg SDIO_INT_FLAG_CMDRUN: SDIO CMDRUN interrupt flag
|
||||
\arg SDIO_INT_FLAG_TXRUN: SDIO TXRUN interrupt flag
|
||||
\arg SDIO_INT_FLAG_RXRUN: SDIO RXRUN interrupt flag
|
||||
\arg SDIO_INT_FLAG_TFH: SDIO TFH interrupt flag
|
||||
\arg SDIO_INT_FLAG_RFH: SDIO RFH interrupt flag
|
||||
\arg SDIO_INT_FLAG_TFF: SDIO TFF interrupt flag
|
||||
\arg SDIO_INT_FLAG_RFF: SDIO RFF interrupt flag
|
||||
\arg SDIO_INT_FLAG_TFE: SDIO TFE interrupt flag
|
||||
\arg SDIO_INT_FLAG_RFE: SDIO RFE interrupt flag
|
||||
\arg SDIO_INT_FLAG_TXDTVAL: SDIO TXDTVAL interrupt flag
|
||||
\arg SDIO_INT_FLAG_RXDTVAL: SDIO RXDTVAL interrupt flag
|
||||
\arg SDIO_INT_FLAG_SDIOINT: SDIO SDIOINT interrupt flag
|
||||
\arg SDIO_INT_FLAG_ATAEND: SDIO ATAEND interrupt flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus sdio_interrupt_flag_get(uint32_t int_flag)
|
||||
{
|
||||
FlagStatus temp_flag = RESET;
|
||||
if(RESET != (SDIO_STAT & int_flag)) {
|
||||
temp_flag = SET;
|
||||
}
|
||||
return temp_flag;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear the interrupt pending flags of SDIO
|
||||
\param[in] int_flag: interrupt flags state of SDIO
|
||||
one or more parameters can be selected which are shown as below:
|
||||
\arg SDIO_INT_FLAG_CCRCERR: command response received (CRC check failed) flag
|
||||
\arg SDIO_INT_FLAG_DTCRCERR: data block sent/received (CRC check failed) flag
|
||||
\arg SDIO_INT_FLAG_CMDTMOUT: command response timeout flag
|
||||
\arg SDIO_INT_FLAG_DTTMOUT: data timeout flag
|
||||
\arg SDIO_INT_FLAG_TXURE: transmit FIFO underrun error occurs flag
|
||||
\arg SDIO_INT_FLAG_RXORE: received FIFO overrun error occurs flag
|
||||
\arg SDIO_INT_FLAG_CMDRECV: command response received (CRC check passed) flag
|
||||
\arg SDIO_INT_FLAG_CMDSEND: command sent (no response required) flag
|
||||
\arg SDIO_INT_FLAG_DTEND: data end (data counter, SDIO_DATACNT, is zero) flag
|
||||
\arg SDIO_INT_FLAG_STBITE: start bit error in the bus flag
|
||||
\arg SDIO_INT_FLAG_DTBLKEND: data block sent/received (CRC check passed) flag
|
||||
\arg SDIO_INT_FLAG_SDIOINT: SD I/O interrupt received flag
|
||||
\arg SDIO_INT_FLAG_ATAEND: CE-ATA command completion signal received (only for CMD61) flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_interrupt_flag_clear(uint32_t int_flag)
|
||||
{
|
||||
SDIO_INTC = int_flag;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the read wait mode(SD I/O only)
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_readwait_enable(void)
|
||||
{
|
||||
SDIO_DATACTL |= SDIO_DATACTL_RWEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the read wait mode(SD I/O only)
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_readwait_disable(void)
|
||||
{
|
||||
SDIO_DATACTL &= ~SDIO_DATACTL_RWEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the function that stop the read wait process(SD I/O only)
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_stop_readwait_enable(void)
|
||||
{
|
||||
SDIO_DATACTL |= SDIO_DATACTL_RWSTOP;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the function that stop the read wait process(SD I/O only)
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_stop_readwait_disable(void)
|
||||
{
|
||||
SDIO_DATACTL &= ~SDIO_DATACTL_RWSTOP;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set the read wait type(SD I/O only)
|
||||
\param[in] readwait_type: SD I/O read wait type
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SDIO_READWAITTYPE_CLK: read wait control by stopping SDIO_CLK
|
||||
\arg SDIO_READWAITTYPE_DAT2: read wait control using SDIO_DAT[2]
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_readwait_type_set(uint32_t readwait_type)
|
||||
{
|
||||
if(SDIO_READWAITTYPE_CLK == readwait_type) {
|
||||
SDIO_DATACTL |= SDIO_DATACTL_RWTYPE;
|
||||
} else {
|
||||
SDIO_DATACTL &= ~SDIO_DATACTL_RWTYPE;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the SD I/O mode specific operation(SD I/O only)
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_operation_enable(void)
|
||||
{
|
||||
SDIO_DATACTL |= SDIO_DATACTL_IOEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the SD I/O mode specific operation(SD I/O only)
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_operation_disable(void)
|
||||
{
|
||||
SDIO_DATACTL &= ~SDIO_DATACTL_IOEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the SD I/O suspend operation(SD I/O only)
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_suspend_enable(void)
|
||||
{
|
||||
SDIO_CMDCTL |= SDIO_CMDCTL_SUSPEND;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the SD I/O suspend operation(SD I/O only)
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_suspend_disable(void)
|
||||
{
|
||||
SDIO_CMDCTL &= ~SDIO_CMDCTL_SUSPEND;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the CE-ATA command(CE-ATA only)
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_ceata_command_enable(void)
|
||||
{
|
||||
SDIO_CMDCTL |= SDIO_CMDCTL_ATAEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the CE-ATA command(CE-ATA only)
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_ceata_command_disable(void)
|
||||
{
|
||||
SDIO_CMDCTL &= ~SDIO_CMDCTL_ATAEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the CE-ATA interrupt(CE-ATA only)
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_ceata_interrupt_enable(void)
|
||||
{
|
||||
SDIO_CMDCTL &= ~SDIO_CMDCTL_NINTEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the CE-ATA interrupt(CE-ATA only)
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_ceata_interrupt_disable(void)
|
||||
{
|
||||
SDIO_CMDCTL |= SDIO_CMDCTL_NINTEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the CE-ATA command completion signal(CE-ATA only)
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_ceata_command_completion_enable(void)
|
||||
{
|
||||
SDIO_CMDCTL |= SDIO_CMDCTL_ENCMDC;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the CE-ATA command completion signal(CE-ATA only)
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void sdio_ceata_command_completion_disable(void)
|
||||
{
|
||||
SDIO_CMDCTL &= ~SDIO_CMDCTL_ENCMDC;
|
||||
}
|
||||
+890
@@ -0,0 +1,890 @@
|
||||
/*!
|
||||
\file gd32f4xx_spi.c
|
||||
\brief SPI driver
|
||||
|
||||
\version 2024-12-20, V3.3.1, firmware for GD32F4xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2024, 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 "gd32f4xx_spi.h"
|
||||
#include "gd32f4xx_rcu.h"
|
||||
|
||||
/* SPI/I2S parameter initialization mask */
|
||||
#define SPI_INIT_MASK ((uint32_t)0x00003040U) /*!< SPI parameter initialization mask */
|
||||
#define I2S_INIT_MASK ((uint32_t)0x0000F047U) /*!< I2S parameter initialization mask */
|
||||
#define I2S_FULL_DUPLEX_MASK ((uint32_t)0x00000480U) /*!< I2S full duples mode configure parameter initialization mask */
|
||||
|
||||
/* default value */
|
||||
#define SPI_I2SPSC_DEFAULT_VALUE ((uint32_t)0x00000002U) /*!< default value of SPI_I2SPSC register */
|
||||
|
||||
/*!
|
||||
\brief deinitialize SPI and I2S
|
||||
\param[in] spi_periph: SPIx(x=0,1,2,3,4,5),include I2S1_ADD and I2S2_ADD
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void spi_i2s_deinit(uint32_t spi_periph)
|
||||
{
|
||||
switch(spi_periph) {
|
||||
case SPI0:
|
||||
/* reset SPI0 */
|
||||
rcu_periph_reset_enable(RCU_SPI0RST);
|
||||
rcu_periph_reset_disable(RCU_SPI0RST);
|
||||
break;
|
||||
case SPI1:
|
||||
/* reset SPI1,I2S1 and I2S1_ADD */
|
||||
rcu_periph_reset_enable(RCU_SPI1RST);
|
||||
rcu_periph_reset_disable(RCU_SPI1RST);
|
||||
break;
|
||||
case SPI2:
|
||||
/* reset SPI2,I2S2 and I2S2_ADD */
|
||||
rcu_periph_reset_enable(RCU_SPI2RST);
|
||||
rcu_periph_reset_disable(RCU_SPI2RST);
|
||||
break;
|
||||
case SPI3:
|
||||
/* reset SPI3 */
|
||||
rcu_periph_reset_enable(RCU_SPI3RST);
|
||||
rcu_periph_reset_disable(RCU_SPI3RST);
|
||||
break;
|
||||
case SPI4:
|
||||
/* reset SPI4 */
|
||||
rcu_periph_reset_enable(RCU_SPI4RST);
|
||||
rcu_periph_reset_disable(RCU_SPI4RST);
|
||||
break;
|
||||
case SPI5:
|
||||
/* reset SPI5 */
|
||||
rcu_periph_reset_enable(RCU_SPI5RST);
|
||||
rcu_periph_reset_disable(RCU_SPI5RST);
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the parameters of SPI struct with default values
|
||||
\param[in] none
|
||||
\param[out] spi_parameter_struct: the initialized struct spi_parameter_struct pointer
|
||||
\retval none
|
||||
*/
|
||||
void spi_struct_para_init(spi_parameter_struct *spi_struct)
|
||||
{
|
||||
/* configure the structure with default value */
|
||||
spi_struct->device_mode = SPI_SLAVE;
|
||||
spi_struct->trans_mode = SPI_TRANSMODE_FULLDUPLEX;
|
||||
spi_struct->frame_size = SPI_FRAMESIZE_8BIT;
|
||||
spi_struct->nss = SPI_NSS_HARD;
|
||||
spi_struct->clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
|
||||
spi_struct->prescale = SPI_PSC_2;
|
||||
spi_struct->endian = SPI_ENDIAN_MSB;
|
||||
}
|
||||
/*!
|
||||
\brief initialize SPI parameter
|
||||
\param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
|
||||
\param[in] spi_struct: SPI parameter initialization stuct members of the structure
|
||||
and the member values are shown as below:
|
||||
device_mode: SPI_MASTER, SPI_SLAVE.
|
||||
trans_mode: SPI_TRANSMODE_FULLDUPLEX, SPI_TRANSMODE_RECEIVEONLY,
|
||||
SPI_TRANSMODE_BDRECEIVE, SPI_TRANSMODE_BDTRANSMIT
|
||||
frame_size: SPI_FRAMESIZE_16BIT, SPI_FRAMESIZE_8BIT
|
||||
nss: SPI_NSS_SOFT, SPI_NSS_HARD
|
||||
endian: SPI_ENDIAN_MSB, SPI_ENDIAN_LSB
|
||||
clock_polarity_phase: SPI_CK_PL_LOW_PH_1EDGE, SPI_CK_PL_HIGH_PH_1EDGE
|
||||
SPI_CK_PL_LOW_PH_2EDGE, SPI_CK_PL_HIGH_PH_2EDGE
|
||||
prescale: SPI_PSC_n (n=2,4,8,16,32,64,128,256)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void spi_init(uint32_t spi_periph, spi_parameter_struct *spi_struct)
|
||||
{
|
||||
uint32_t reg = 0U;
|
||||
reg = SPI_CTL0(spi_periph);
|
||||
reg &= SPI_INIT_MASK;
|
||||
|
||||
/* select SPI as master or slave */
|
||||
reg |= spi_struct->device_mode;
|
||||
/* select SPI transfer mode */
|
||||
reg |= spi_struct->trans_mode;
|
||||
/* select SPI frame size */
|
||||
reg |= spi_struct->frame_size;
|
||||
/* select SPI nss use hardware or software */
|
||||
reg |= spi_struct->nss;
|
||||
/* select SPI LSB or MSB */
|
||||
reg |= spi_struct->endian;
|
||||
/* select SPI polarity and phase */
|
||||
reg |= spi_struct->clock_polarity_phase;
|
||||
/* select SPI prescale to adjust transmit speed */
|
||||
reg |= spi_struct->prescale;
|
||||
|
||||
/* write to SPI_CTL0 register */
|
||||
SPI_CTL0(spi_periph) = (uint32_t)reg;
|
||||
|
||||
SPI_I2SCTL(spi_periph) &= (uint32_t)(~SPI_I2SCTL_I2SSEL);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable SPI
|
||||
\param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void spi_enable(uint32_t spi_periph)
|
||||
{
|
||||
SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_SPIEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable SPI
|
||||
\param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void spi_disable(uint32_t spi_periph)
|
||||
{
|
||||
SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_SPIEN);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize I2S parameter
|
||||
\param[in] spi_periph: SPIx(x=1,2)
|
||||
\param[in] i2s_mode: I2S operation mode
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2S_MODE_SLAVETX : I2S slave transmit mode
|
||||
\arg I2S_MODE_SLAVERX : I2S slave receive mode
|
||||
\arg I2S_MODE_MASTERTX : I2S master transmit mode
|
||||
\arg I2S_MODE_MASTERRX : I2S master receive mode
|
||||
\param[in] i2s_standard: I2S standard
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2S_STD_PHILLIPS : I2S phillips standard
|
||||
\arg I2S_STD_MSB : I2S MSB standard
|
||||
\arg I2S_STD_LSB : I2S LSB standard
|
||||
\arg I2S_STD_PCMSHORT : I2S PCM short standard
|
||||
\arg I2S_STD_PCMLONG : I2S PCM long standard
|
||||
\param[in] i2s_ckpl: I2S idle state clock polarity
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2S_CKPL_LOW : I2S clock polarity low level
|
||||
\arg I2S_CKPL_HIGH : I2S clock polarity high level
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2s_init(uint32_t spi_periph, uint32_t i2s_mode, uint32_t i2s_standard, uint32_t i2s_ckpl)
|
||||
{
|
||||
uint32_t reg = 0U;
|
||||
reg = SPI_I2SCTL(spi_periph);
|
||||
reg &= I2S_INIT_MASK;
|
||||
|
||||
/* enable I2S mode */
|
||||
reg |= (uint32_t)SPI_I2SCTL_I2SSEL;
|
||||
/* select I2S mode */
|
||||
reg |= (uint32_t)i2s_mode;
|
||||
/* select I2S standard */
|
||||
reg |= (uint32_t)i2s_standard;
|
||||
/* select I2S polarity */
|
||||
reg |= (uint32_t)i2s_ckpl;
|
||||
|
||||
/* write to SPI_I2SCTL register */
|
||||
SPI_I2SCTL(spi_periph) = (uint32_t)reg;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure I2S prescale
|
||||
\param[in] spi_periph: SPIx(x=1,2)
|
||||
\param[in] i2s_audiosample: I2S audio sample rate
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2S_AUDIOSAMPLE_8K: audio sample rate is 8KHz
|
||||
\arg I2S_AUDIOSAMPLE_11K: audio sample rate is 11KHz
|
||||
\arg I2S_AUDIOSAMPLE_16K: audio sample rate is 16KHz
|
||||
\arg I2S_AUDIOSAMPLE_22K: audio sample rate is 22KHz
|
||||
\arg I2S_AUDIOSAMPLE_32K: audio sample rate is 32KHz
|
||||
\arg I2S_AUDIOSAMPLE_44K: audio sample rate is 44KHz
|
||||
\arg I2S_AUDIOSAMPLE_48K: audio sample rate is 48KHz
|
||||
\arg I2S_AUDIOSAMPLE_96K: audio sample rate is 96KHz
|
||||
\arg I2S_AUDIOSAMPLE_192K: audio sample rate is 192KHz
|
||||
\param[in] i2s_frameformat: I2S data length and channel length
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2S_FRAMEFORMAT_DT16B_CH16B: I2S data length is 16 bit and channel length is 16 bit
|
||||
\arg I2S_FRAMEFORMAT_DT16B_CH32B: I2S data length is 16 bit and channel length is 32 bit
|
||||
\arg I2S_FRAMEFORMAT_DT24B_CH32B: I2S data length is 24 bit and channel length is 32 bit
|
||||
\arg I2S_FRAMEFORMAT_DT32B_CH32B: I2S data length is 32 bit and channel length is 32 bit
|
||||
\param[in] i2s_mckout: I2S master clock output
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg I2S_MCKOUT_ENABLE: I2S master clock output enable
|
||||
\arg I2S_MCKOUT_DISABLE: I2S master clock output disable
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2s_psc_config(uint32_t spi_periph, uint32_t i2s_audiosample, uint32_t i2s_frameformat, uint32_t i2s_mckout)
|
||||
{
|
||||
uint32_t i2sdiv = 2U, i2sof = 0U;
|
||||
uint32_t clks = 0U;
|
||||
uint32_t i2sclock = 0U;
|
||||
|
||||
#ifndef I2S_EXTERNAL_CLOCK_IN
|
||||
uint32_t plli2sm = 0U, plli2sn = 0U, plli2sr = 0U;
|
||||
#endif /* I2S_EXTERNAL_CLOCK_IN */
|
||||
|
||||
/* deinit SPI_I2SPSC register */
|
||||
SPI_I2SPSC(spi_periph) = SPI_I2SPSC_DEFAULT_VALUE;
|
||||
|
||||
#ifdef I2S_EXTERNAL_CLOCK_IN
|
||||
rcu_i2s_clock_config(RCU_I2SSRC_I2S_CKIN);
|
||||
|
||||
/* set the I2S clock to the external clock input value */
|
||||
i2sclock = I2S_EXTERNAL_CLOCK_IN;
|
||||
#else
|
||||
|
||||
/* turn on the oscillator HXTAL */
|
||||
rcu_osci_on(RCU_HXTAL);
|
||||
/* wait for oscillator stabilization flags is SET */
|
||||
rcu_osci_stab_wait(RCU_HXTAL);
|
||||
/* turn on the PLLI2S */
|
||||
rcu_osci_on(RCU_PLLI2S_CK);
|
||||
/* wait for PLLI2S flags is SET */
|
||||
rcu_osci_stab_wait(RCU_PLLI2S_CK);
|
||||
/* configure the I2S clock source selection */
|
||||
rcu_i2s_clock_config(RCU_I2SSRC_PLLI2S);
|
||||
|
||||
/* get the RCU_PLL_PLLPSC value */
|
||||
plli2sm = (uint32_t)(RCU_PLL & RCU_PLL_PLLPSC);
|
||||
/* get the RCU_PLLI2S_PLLI2SN value */
|
||||
plli2sn = (uint32_t)((RCU_PLLI2S & RCU_PLLI2S_PLLI2SN) >> 6);
|
||||
/* get the RCU_PLLI2S_PLLI2SR value */
|
||||
plli2sr = (uint32_t)((RCU_PLLI2S & RCU_PLLI2S_PLLI2SR) >> 28);
|
||||
|
||||
if((RCU_PLL & RCU_PLL_PLLSEL) == RCU_PLLSRC_HXTAL) {
|
||||
/* get the I2S source clock value */
|
||||
i2sclock = (uint32_t)(((HXTAL_VALUE / plli2sm) * plli2sn) / plli2sr);
|
||||
} else {
|
||||
/* get the I2S source clock value */
|
||||
i2sclock = (uint32_t)(((IRC16M_VALUE / plli2sm) * plli2sn) / plli2sr);
|
||||
}
|
||||
#endif /* I2S_EXTERNAL_CLOCK_IN */
|
||||
|
||||
/* config the prescaler depending on the mclk output state, the frame format and audio sample rate */
|
||||
if(I2S_MCKOUT_ENABLE == i2s_mckout) {
|
||||
clks = (uint32_t)(((i2sclock / 256U) * 10U) / i2s_audiosample);
|
||||
} else {
|
||||
if(I2S_FRAMEFORMAT_DT16B_CH16B == i2s_frameformat) {
|
||||
clks = (uint32_t)(((i2sclock / 32U) * 10U) / i2s_audiosample);
|
||||
} else {
|
||||
clks = (uint32_t)(((i2sclock / 64U) * 10U) / i2s_audiosample);
|
||||
}
|
||||
}
|
||||
/* remove the floating point */
|
||||
clks = (clks + 5U) / 10U;
|
||||
i2sof = (clks & 0x00000001U);
|
||||
i2sdiv = ((clks - i2sof) / 2U);
|
||||
i2sof = (i2sof << 8U);
|
||||
|
||||
/* set the default values */
|
||||
if((i2sdiv < 2U) || (i2sdiv > 255U)) {
|
||||
i2sdiv = 2U;
|
||||
i2sof = 0U;
|
||||
}
|
||||
|
||||
/* configure SPI_I2SPSC */
|
||||
SPI_I2SPSC(spi_periph) = (uint32_t)(i2sdiv | i2sof | i2s_mckout);
|
||||
|
||||
/* clear SPI_I2SCTL_DTLEN and SPI_I2SCTL_CHLEN bits */
|
||||
SPI_I2SCTL(spi_periph) &= (uint32_t)(~(SPI_I2SCTL_DTLEN | SPI_I2SCTL_CHLEN));
|
||||
/* configure data frame format */
|
||||
SPI_I2SCTL(spi_periph) |= (uint32_t)i2s_frameformat;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable I2S
|
||||
\param[in] spi_periph: SPIx(x=1,2)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2s_enable(uint32_t spi_periph)
|
||||
{
|
||||
SPI_I2SCTL(spi_periph) |= (uint32_t)SPI_I2SCTL_I2SEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable I2S
|
||||
\param[in] spi_periph: SPIx(x=1,2)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2s_disable(uint32_t spi_periph)
|
||||
{
|
||||
SPI_I2SCTL(spi_periph) &= (uint32_t)(~SPI_I2SCTL_I2SEN);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable SPI nss output
|
||||
\param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void spi_nss_output_enable(uint32_t spi_periph)
|
||||
{
|
||||
SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_NSSDRV;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable SPI nss output
|
||||
\param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void spi_nss_output_disable(uint32_t spi_periph)
|
||||
{
|
||||
SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_NSSDRV);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief SPI nss pin high level in software mode
|
||||
\param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void spi_nss_internal_high(uint32_t spi_periph)
|
||||
{
|
||||
SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_SWNSS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief SPI nss pin low level in software mode
|
||||
\param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void spi_nss_internal_low(uint32_t spi_periph)
|
||||
{
|
||||
SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_SWNSS);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable SPI DMA send or receive
|
||||
\param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
|
||||
\param[in] spi_dma: SPI DMA mode
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SPI_DMA_TRANSMIT: SPI transmit data use DMA
|
||||
\arg SPI_DMA_RECEIVE: SPI receive data use DMA
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void spi_dma_enable(uint32_t spi_periph, uint8_t spi_dma)
|
||||
{
|
||||
if(SPI_DMA_TRANSMIT == spi_dma) {
|
||||
SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_DMATEN;
|
||||
} else {
|
||||
SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_DMAREN;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief diable SPI DMA send or receive
|
||||
\param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
|
||||
\param[in] spi_dma: SPI DMA mode
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SPI_DMA_TRANSMIT: SPI transmit data use DMA
|
||||
\arg SPI_DMA_RECEIVE: SPI receive data use DMA
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void spi_dma_disable(uint32_t spi_periph, uint8_t spi_dma)
|
||||
{
|
||||
if(SPI_DMA_TRANSMIT == spi_dma) {
|
||||
SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_DMATEN);
|
||||
} else {
|
||||
SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_DMAREN);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure SPI/I2S data frame format
|
||||
\param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
|
||||
\param[in] frame_format: SPI frame size
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SPI_FRAMESIZE_16BIT: SPI frame size is 16 bits
|
||||
\arg SPI_FRAMESIZE_8BIT: SPI frame size is 8 bits
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void spi_i2s_data_frame_format_config(uint32_t spi_periph, uint16_t frame_format)
|
||||
{
|
||||
/* clear SPI_CTL0_FF16 bit */
|
||||
SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_FF16);
|
||||
/* configure SPI_CTL0_FF16 bit */
|
||||
SPI_CTL0(spi_periph) |= (uint32_t)frame_format;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief SPI transmit data
|
||||
\param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
|
||||
\param[in] data: 16-bit data
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void spi_i2s_data_transmit(uint32_t spi_periph, uint16_t data)
|
||||
{
|
||||
SPI_DATA(spi_periph) = (uint32_t)data;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief SPI receive data
|
||||
\param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
|
||||
\param[out] none
|
||||
\retval 16-bit data
|
||||
*/
|
||||
uint16_t spi_i2s_data_receive(uint32_t spi_periph)
|
||||
{
|
||||
return ((uint16_t)SPI_DATA(spi_periph));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure SPI bidirectional transfer direction
|
||||
\param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
|
||||
\param[in] transfer_direction: SPI transfer direction
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SPI_BIDIRECTIONAL_TRANSMIT: SPI work in transmit-only mode
|
||||
\arg SPI_BIDIRECTIONAL_RECEIVE: SPI work in receive-only mode
|
||||
\retval none
|
||||
*/
|
||||
void spi_bidirectional_transfer_config(uint32_t spi_periph, uint32_t transfer_direction)
|
||||
{
|
||||
if(SPI_BIDIRECTIONAL_TRANSMIT == transfer_direction) {
|
||||
/* set the transmit only mode */
|
||||
SPI_CTL0(spi_periph) |= (uint32_t)SPI_BIDIRECTIONAL_TRANSMIT;
|
||||
} else {
|
||||
/* set the receive only mode */
|
||||
SPI_CTL0(spi_periph) &= SPI_BIDIRECTIONAL_RECEIVE;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure i2s full duplex mode
|
||||
\param[in] i2s_add_periph: I2Sx_ADD(x=1,2)
|
||||
\param[in] i2s_mode:
|
||||
\arg I2S_MODE_SLAVETX : I2S slave transmit mode
|
||||
\arg I2S_MODE_SLAVERX : I2S slave receive mode
|
||||
\arg I2S_MODE_MASTERTX : I2S master transmit mode
|
||||
\arg I2S_MODE_MASTERRX : I2S master receive mode
|
||||
\param[in] i2s_standard:
|
||||
\arg I2S_STD_PHILLIPS : I2S phillips standard
|
||||
\arg I2S_STD_MSB : I2S MSB standard
|
||||
\arg I2S_STD_LSB : I2S LSB standard
|
||||
\arg I2S_STD_PCMSHORT : I2S PCM short standard
|
||||
\arg I2S_STD_PCMLONG : I2S PCM long standard
|
||||
\param[in] i2s_ckpl:
|
||||
\arg I2S_CKPL_LOW : I2S clock polarity low level
|
||||
\arg I2S_CKPL_HIGH : I2S clock polarity high level
|
||||
\param[in] i2s_frameformat:
|
||||
\arg I2S_FRAMEFORMAT_DT16B_CH16B: I2S data length is 16 bit and channel length is 16 bit
|
||||
\arg I2S_FRAMEFORMAT_DT16B_CH32B: I2S data length is 16 bit and channel length is 32 bit
|
||||
\arg I2S_FRAMEFORMAT_DT24B_CH32B: I2S data length is 24 bit and channel length is 32 bit
|
||||
\arg I2S_FRAMEFORMAT_DT32B_CH32B: I2S data length is 32 bit and channel length is 32 bit
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2s_full_duplex_mode_config(uint32_t i2s_add_periph, uint32_t i2s_mode, uint32_t i2s_standard,
|
||||
uint32_t i2s_ckpl, uint32_t i2s_frameformat)
|
||||
{
|
||||
uint32_t reg = 0U, tmp = 0U;
|
||||
|
||||
reg = I2S_ADD_I2SCTL(i2s_add_periph);
|
||||
reg &= I2S_FULL_DUPLEX_MASK;
|
||||
|
||||
/* get the mode of the extra I2S module I2Sx_ADD */
|
||||
if((I2S_MODE_MASTERTX == i2s_mode) || (I2S_MODE_SLAVETX == i2s_mode)) {
|
||||
tmp = I2S_MODE_SLAVERX;
|
||||
} else {
|
||||
tmp = I2S_MODE_SLAVETX;
|
||||
}
|
||||
|
||||
/* enable I2S mode */
|
||||
reg |= (uint32_t)SPI_I2SCTL_I2SSEL;
|
||||
/* select I2S mode */
|
||||
reg |= (uint32_t)tmp;
|
||||
/* select I2S standard */
|
||||
reg |= (uint32_t)i2s_standard;
|
||||
/* select I2S polarity */
|
||||
reg |= (uint32_t)i2s_ckpl;
|
||||
/* configure data frame format */
|
||||
reg |= (uint32_t)i2s_frameformat;
|
||||
|
||||
/* write to SPI_I2SCTL register */
|
||||
I2S_ADD_I2SCTL(i2s_add_periph) = (uint32_t)reg;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear SPI/I2S format error flag status
|
||||
\param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
|
||||
\param[in] flag: SPI/I2S frame format error flag
|
||||
\arg SPI_FLAG_FERR: only for SPI work in TI mode
|
||||
\arg I2S_FLAG_FERR: for I2S
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void spi_i2s_format_error_clear(uint32_t spi_periph, uint32_t flag)
|
||||
{
|
||||
SPI_STAT(spi_periph) = (uint32_t)(~flag);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set SPI CRC polynomial
|
||||
\param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
|
||||
\param[in] crc_poly: CRC polynomial value
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void spi_crc_polynomial_set(uint32_t spi_periph, uint16_t crc_poly)
|
||||
{
|
||||
/* set SPI CRC polynomial */
|
||||
SPI_CRCPOLY(spi_periph) = (uint32_t)crc_poly;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get SPI CRC polynomial
|
||||
\param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
|
||||
\param[out] none
|
||||
\retval 16-bit CRC polynomial
|
||||
*/
|
||||
uint16_t spi_crc_polynomial_get(uint32_t spi_periph)
|
||||
{
|
||||
return ((uint16_t)SPI_CRCPOLY(spi_periph));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief turn on SPI CRC function
|
||||
\param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void spi_crc_on(uint32_t spi_periph)
|
||||
{
|
||||
SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief turn off SPI CRC function
|
||||
\param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void spi_crc_off(uint32_t spi_periph)
|
||||
{
|
||||
SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_CRCEN);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief SPI next data is CRC value
|
||||
\param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void spi_crc_next(uint32_t spi_periph)
|
||||
{
|
||||
SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCNT;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get SPI CRC send value or receive value
|
||||
\param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
|
||||
\param[in] spi_crc: SPI crc value
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SPI_CRC_TX: get transmit crc value
|
||||
\arg SPI_CRC_RX: get receive crc value
|
||||
\param[out] none
|
||||
\retval 16-bit CRC value
|
||||
*/
|
||||
uint16_t spi_crc_get(uint32_t spi_periph, uint8_t spi_crc)
|
||||
{
|
||||
if(SPI_CRC_TX == spi_crc) {
|
||||
return ((uint16_t)(SPI_TCRC(spi_periph)));
|
||||
} else {
|
||||
return ((uint16_t)(SPI_RCRC(spi_periph)));
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear SPI CRC error flag status
|
||||
\param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void spi_crc_error_clear(uint32_t spi_periph)
|
||||
{
|
||||
SPI_STAT(spi_periph) = (uint32_t)(~SPI_FLAG_CRCERR);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable SPI TI mode
|
||||
\param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void spi_ti_mode_enable(uint32_t spi_periph)
|
||||
{
|
||||
SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_TMOD;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable SPI TI mode
|
||||
\param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void spi_ti_mode_disable(uint32_t spi_periph)
|
||||
{
|
||||
SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_TMOD);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable quad wire SPI
|
||||
\param[in] spi_periph: SPIx(only x=5)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void spi_quad_enable(uint32_t spi_periph)
|
||||
{
|
||||
SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_QMOD;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable quad wire SPI
|
||||
\param[in] spi_periph: SPIx(only x=5)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void spi_quad_disable(uint32_t spi_periph)
|
||||
{
|
||||
SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_QMOD);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable quad wire SPI write
|
||||
\param[in] spi_periph: SPIx(only x=5)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void spi_quad_write_enable(uint32_t spi_periph)
|
||||
{
|
||||
SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_QRD);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable quad wire SPI read
|
||||
\param[in] spi_periph: SPIx(only x=5)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void spi_quad_read_enable(uint32_t spi_periph)
|
||||
{
|
||||
SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_QRD;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable SPI_IO2 and SPI_IO3 pin output
|
||||
\param[in] spi_periph: SPIx(only x=5)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void spi_quad_io23_output_enable(uint32_t spi_periph)
|
||||
{
|
||||
SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_IO23_DRV;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable SPI_IO2 and SPI_IO3 pin output
|
||||
\param[in] spi_periph: SPIx(only x=5)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void spi_quad_io23_output_disable(uint32_t spi_periph)
|
||||
{
|
||||
SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_IO23_DRV);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get SPI and I2S flag status
|
||||
\param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
|
||||
\param[in] spi_i2s_flag: SPI/I2S flag status
|
||||
only one parameter can be selected which are shown as below:
|
||||
\arg SPI_FLAG_TBE: transmit buffer empty flag
|
||||
\arg SPI_FLAG_RBNE: receive buffer not empty flag
|
||||
\arg SPI_FLAG_TRANS: transmit on-going flag
|
||||
\arg SPI_FLAG_RXORERR: receive overrun error flag
|
||||
\arg SPI_FLAG_CONFERR: mode config error flag
|
||||
\arg SPI_FLAG_CRCERR: CRC error flag
|
||||
\arg SPI_FLAG_FERR: format error flag
|
||||
\arg I2S_FLAG_TBE: transmit buffer empty flag
|
||||
\arg I2S_FLAG_RBNE: receive buffer not empty flag
|
||||
\arg I2S_FLAG_TRANS: transmit on-going flag
|
||||
\arg I2S_FLAG_RXORERR: overrun error flag
|
||||
\arg I2S_FLAG_TXURERR: underrun error flag
|
||||
\arg I2S_FLAG_CH: channel side flag
|
||||
\arg I2S_FLAG_FERR: format error flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus spi_i2s_flag_get(uint32_t spi_periph, uint32_t flag)
|
||||
{
|
||||
if(SPI_STAT(spi_periph) & flag) {
|
||||
return SET;
|
||||
} else {
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable SPI and I2S interrupt
|
||||
\param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
|
||||
\param[in] spi_i2s_int: SPI/I2S interrupt
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SPI_I2S_INT_TBE: transmit buffer empty interrupt
|
||||
\arg SPI_I2S_INT_RBNE: receive buffer not empty interrupt
|
||||
\arg SPI_I2S_INT_ERR: CRC error,configuration error,reception overrun error,
|
||||
transmission underrun error and format error interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void spi_i2s_interrupt_enable(uint32_t spi_periph, uint8_t interrupt)
|
||||
{
|
||||
switch(interrupt) {
|
||||
/* SPI/I2S transmit buffer empty interrupt */
|
||||
case SPI_I2S_INT_TBE:
|
||||
SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_TBEIE;
|
||||
break;
|
||||
/* SPI/I2S receive buffer not empty interrupt */
|
||||
case SPI_I2S_INT_RBNE:
|
||||
SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_RBNEIE;
|
||||
break;
|
||||
/* SPI/I2S error */
|
||||
case SPI_I2S_INT_ERR:
|
||||
SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_ERRIE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable SPI and I2S interrupt
|
||||
\param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
|
||||
\param[in] spi_i2s_int: SPI/I2S interrupt
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SPI_I2S_INT_TBE: transmit buffer empty interrupt
|
||||
\arg SPI_I2S_INT_RBNE: receive buffer not empty interrupt
|
||||
\arg SPI_I2S_INT_ERR: CRC error,configuration error,reception overrun error,
|
||||
transmission underrun error and format error interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void spi_i2s_interrupt_disable(uint32_t spi_periph, uint8_t interrupt)
|
||||
{
|
||||
switch(interrupt) {
|
||||
/* SPI/I2S transmit buffer empty interrupt */
|
||||
case SPI_I2S_INT_TBE :
|
||||
SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_TBEIE);
|
||||
break;
|
||||
/* SPI/I2S receive buffer not empty interrupt */
|
||||
case SPI_I2S_INT_RBNE :
|
||||
SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_RBNEIE);
|
||||
break;
|
||||
/* SPI/I2S error */
|
||||
case SPI_I2S_INT_ERR :
|
||||
SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_ERRIE);
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get SPI and I2S interrupt flag status
|
||||
\param[in] spi_periph: SPIx(x=0,1,2,3,4,5)
|
||||
\param[in] spi_i2s_int: SPI/I2S interrupt flag status
|
||||
only one parameter can be selected which are shown as below:
|
||||
\arg SPI_I2S_INT_FLAG_TBE: transmit buffer empty interrupt flag
|
||||
\arg SPI_I2S_INT_FLAG_RBNE: receive buffer not empty interrupt flag
|
||||
\arg SPI_I2S_INT_FLAG_RXORERR: overrun interrupt flag
|
||||
\arg SPI_INT_FLAG_CONFERR: config error interrupt flag
|
||||
\arg SPI_INT_FLAG_CRCERR: CRC error interrupt flag
|
||||
\arg I2S_INT_FLAG_TXURERR: underrun error interrupt flag
|
||||
\arg SPI_I2S_INT_FLAG_FERR: format error interrupt flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus spi_i2s_interrupt_flag_get(uint32_t spi_periph, uint8_t interrupt)
|
||||
{
|
||||
uint32_t reg1 = SPI_STAT(spi_periph);
|
||||
uint32_t reg2 = SPI_CTL1(spi_periph);
|
||||
|
||||
switch(interrupt) {
|
||||
/* SPI/I2S transmit buffer empty interrupt */
|
||||
case SPI_I2S_INT_FLAG_TBE :
|
||||
reg1 = reg1 & SPI_STAT_TBE;
|
||||
reg2 = reg2 & SPI_CTL1_TBEIE;
|
||||
break;
|
||||
/* SPI/I2S receive buffer not empty interrupt */
|
||||
case SPI_I2S_INT_FLAG_RBNE :
|
||||
reg1 = reg1 & SPI_STAT_RBNE;
|
||||
reg2 = reg2 & SPI_CTL1_RBNEIE;
|
||||
break;
|
||||
/* SPI/I2S overrun interrupt */
|
||||
case SPI_I2S_INT_FLAG_RXORERR :
|
||||
reg1 = reg1 & SPI_STAT_RXORERR;
|
||||
reg2 = reg2 & SPI_CTL1_ERRIE;
|
||||
break;
|
||||
/* SPI config error interrupt */
|
||||
case SPI_INT_FLAG_CONFERR :
|
||||
reg1 = reg1 & SPI_STAT_CONFERR;
|
||||
reg2 = reg2 & SPI_CTL1_ERRIE;
|
||||
break;
|
||||
/* SPI CRC error interrupt */
|
||||
case SPI_INT_FLAG_CRCERR :
|
||||
reg1 = reg1 & SPI_STAT_CRCERR;
|
||||
reg2 = reg2 & SPI_CTL1_ERRIE;
|
||||
break;
|
||||
/* I2S underrun error interrupt */
|
||||
case I2S_INT_FLAG_TXURERR :
|
||||
reg1 = reg1 & SPI_STAT_TXURERR;
|
||||
reg2 = reg2 & SPI_CTL1_ERRIE;
|
||||
break;
|
||||
/* SPI/I2S format error interrupt */
|
||||
case SPI_I2S_INT_FLAG_FERR :
|
||||
reg1 = reg1 & SPI_STAT_FERR;
|
||||
reg2 = reg2 & SPI_CTL1_ERRIE;
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
/*get SPI/I2S interrupt flag status */
|
||||
if(reg1 && reg2) {
|
||||
return SET;
|
||||
} else {
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
+202
@@ -0,0 +1,202 @@
|
||||
/*!
|
||||
\file gd32f4xx_syscfg.c
|
||||
\brief SYSCFG driver
|
||||
|
||||
\version 2024-12-20, V3.3.1, firmware for GD32F4xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2024, 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 "gd32f4xx_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 configure the boot mode
|
||||
\param[in] syscfg_bootmode: selects the memory remapping
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SYSCFG_BOOTMODE_FLASH: main flash memory (0x08000000~0x083BFFFF) is mapped at address 0x00000000
|
||||
\arg SYSCFG_BOOTMODE_BOOTLOADER: boot loader (0x1FFF0000 - 0x1FFF77FF) is mapped at address 0x00000000
|
||||
\arg SYSCFG_BOOTMODE_EXMC_SRAM: SRAM/NOR 0 and 1 of EXMC (0x60000000~0x67FFFFFF) is mapped at address 0x00000000
|
||||
\arg SYSCFG_BOOTMODE_SRAM: SRAM0 of on-chip SRAM (0x20000000~0x2001BFFF) is mapped at address 0x00000000
|
||||
\arg SYSCFG_BOOTMODE_EXMC_SDRAM: SDRAM bank0 of EXMC (0xC0000000~0xC7FFFFFF) is mapped at address 0x00000000
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void syscfg_bootmode_config(uint8_t syscfg_bootmode)
|
||||
{
|
||||
/* reset the SYSCFG_CFG0_BOOT_MODE bit and set according to syscfg_bootmode */
|
||||
SYSCFG_CFG0 &= ~SYSCFG_CFG0_BOOT_MODE;
|
||||
SYSCFG_CFG0 |= (uint32_t)syscfg_bootmode;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief FMC memory mapping swap
|
||||
\param[in] syscfg_fmc_swap: selects the interal flash bank swapping
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SYSCFG_FMC_SWP_BANK0: bank 0 is mapped at address 0x08000000 and bank 1 is mapped at address 0x08100000
|
||||
\arg SYSCFG_FMC_SWP_BANK1: bank 1 is mapped at address 0x08000000 and bank 0 is mapped at address 0x08100000
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void syscfg_fmc_swap_config(uint32_t syscfg_fmc_swap)
|
||||
{
|
||||
uint32_t reg;
|
||||
reg = SYSCFG_CFG0;
|
||||
/* reset the FMC_SWP bit and set according to syscfg_fmc_swap */
|
||||
reg &= ~SYSCFG_CFG0_FMC_SWP;
|
||||
SYSCFG_CFG0 = (reg | syscfg_fmc_swap);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief EXMC memory mapping swap
|
||||
\param[in] syscfg_exmc_swap: selects the memories in EXMC swapping
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SYSCFG_EXMC_SWP_ENABLE: SDRAM bank 0 and bank 1 are swapped with NAND bank 1 and PC card
|
||||
\arg SYSCFG_EXMC_SWP_DISABLE: no memory mapping swap
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void syscfg_exmc_swap_config(uint32_t syscfg_exmc_swap)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
reg = SYSCFG_CFG0;
|
||||
/* reset the SYSCFG_CFG0_EXMC_SWP bits and set according to syscfg_exmc_swap */
|
||||
reg &= ~SYSCFG_CFG0_EXMC_SWP;
|
||||
SYSCFG_CFG0 = (reg | syscfg_exmc_swap);
|
||||
}
|
||||
|
||||
/*!
|
||||
\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,I): 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(x = 0..15): 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 configure the PHY interface for the ethernet MAC
|
||||
\param[in] syscfg_enet_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 syscfg_enet_phy_interface)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
reg = SYSCFG_CFG1;
|
||||
/* reset the ENET_PHY_SEL bit and set according to syscfg_enet_phy_interface */
|
||||
reg &= ~SYSCFG_CFG1_ENET_PHY_SEL;
|
||||
SYSCFG_CFG1 = (reg | syscfg_enet_phy_interface);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the I/O compensation cell
|
||||
\param[in] syscfg_compensation: specifies the I/O compensation cell mode
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg SYSCFG_COMPENSATION_ENABLE: I/O compensation cell is enabled
|
||||
\arg SYSCFG_COMPENSATION_DISABLE: I/O compensation cell is disabled
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void syscfg_compensation_config(uint32_t syscfg_compensation)
|
||||
{
|
||||
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_compensation);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief checks whether the I/O compensation cell ready flag is set or not
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus syscfg_flag_get(void)
|
||||
{
|
||||
if(((uint32_t)RESET) != (SYSCFG_CPSCTL & SYSCFG_CPSCTL_CPS_RDY)) {
|
||||
return SET;
|
||||
} else {
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
+2176
File diff suppressed because it is too large
Load Diff
+596
@@ -0,0 +1,596 @@
|
||||
/*!
|
||||
\file gd32f4xx_tli.c
|
||||
\brief TLI driver
|
||||
|
||||
\version 2024-12-20, V3.3.1, firmware for GD32F4xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2024, 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 "gd32f4xx_tli.h"
|
||||
|
||||
#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_HIGH
|
||||
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;
|
||||
/* check whether the corresponding bit in TLI_INTEN is set or not */
|
||||
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;
|
||||
}
|
||||
}
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
/*!
|
||||
\file gd32f4xx_trng.c
|
||||
\brief TRNG driver
|
||||
|
||||
\version 2024-12-20, V3.3.1, firmware for GD32F4xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2024, 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 "gd32f4xx_trng.h"
|
||||
|
||||
/*!
|
||||
\brief reset 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 TRNG
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void trng_enable(void)
|
||||
{
|
||||
TRNG_CTL |= TRNG_CTL_TRNGEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable TRNG
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void trng_disable(void)
|
||||
{
|
||||
TRNG_CTL &= ~TRNG_CTL_TRNGEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the true random data
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval uint32_t: 0x0-0xFFFFFFFF
|
||||
*/
|
||||
uint32_t trng_get_true_random_data(void)
|
||||
{
|
||||
return (TRNG_DATA);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable TRNG interrupt
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void trng_interrupt_enable(void)
|
||||
{
|
||||
TRNG_CTL |= TRNG_CTL_TRNGIE;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable TRNG interrupt
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void trng_interrupt_disable(void)
|
||||
{
|
||||
TRNG_CTL &= ~TRNG_CTL_TRNGIE;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get TRNG flag status
|
||||
\param[in] flag: TRNG flag
|
||||
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 get TRNG interrupt flag status
|
||||
\param[in] int_flag: TRNG interrupt flag
|
||||
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 TRNG interrupt flag status
|
||||
\param[in] int_flag: TRNG interrupt flag
|
||||
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;
|
||||
}
|
||||
+982
@@ -0,0 +1,982 @@
|
||||
/*!
|
||||
\file gd32f4xx_usart.c
|
||||
\brief USART driver
|
||||
|
||||
\version 2024-12-20, V3.3.1, firmware for GD32F4xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2024, 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 "gd32f4xx_usart.h"
|
||||
|
||||
/* USART register bit offset */
|
||||
#define GP_GUAT_OFFSET ((uint32_t)8U) /* bit offset of GUAT in USART_GP */
|
||||
#define CTL3_SCRTNUM_OFFSET ((uint32_t)1U) /* bit offset of SCRTNUM in USART_CTL3 */
|
||||
#define RT_BL_OFFSET ((uint32_t)24U) /* bit offset of BL in USART_RT */
|
||||
|
||||
/*!
|
||||
\brief reset USART/UART
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_deinit(uint32_t usart_periph)
|
||||
{
|
||||
switch(usart_periph) {
|
||||
case USART0:
|
||||
rcu_periph_reset_enable(RCU_USART0RST);
|
||||
rcu_periph_reset_disable(RCU_USART0RST);
|
||||
break;
|
||||
case USART1:
|
||||
rcu_periph_reset_enable(RCU_USART1RST);
|
||||
rcu_periph_reset_disable(RCU_USART1RST);
|
||||
break;
|
||||
case USART2:
|
||||
rcu_periph_reset_enable(RCU_USART2RST);
|
||||
rcu_periph_reset_disable(RCU_USART2RST);
|
||||
break;
|
||||
case USART5:
|
||||
rcu_periph_reset_enable(RCU_USART5RST);
|
||||
rcu_periph_reset_disable(RCU_USART5RST);
|
||||
break;
|
||||
case UART3:
|
||||
rcu_periph_reset_enable(RCU_UART3RST);
|
||||
rcu_periph_reset_disable(RCU_UART3RST);
|
||||
break;
|
||||
case UART4:
|
||||
rcu_periph_reset_enable(RCU_UART4RST);
|
||||
rcu_periph_reset_disable(RCU_UART4RST);
|
||||
break;
|
||||
case UART6:
|
||||
rcu_periph_reset_enable(RCU_UART6RST);
|
||||
rcu_periph_reset_disable(RCU_UART6RST);
|
||||
break;
|
||||
case UART7:
|
||||
rcu_periph_reset_enable(RCU_UART7RST);
|
||||
rcu_periph_reset_disable(RCU_UART7RST);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure USART baud rate value
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[in] baudval: baud rate value
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_baudrate_set(uint32_t usart_periph, uint32_t baudval)
|
||||
{
|
||||
uint32_t uclk = 0U, intdiv = 0U, fradiv = 0U, udiv = 0U;
|
||||
switch(usart_periph) {
|
||||
/* get clock frequency */
|
||||
case USART0:
|
||||
uclk = rcu_clock_freq_get(CK_APB2);
|
||||
break;
|
||||
case USART5:
|
||||
uclk = rcu_clock_freq_get(CK_APB2);
|
||||
break;
|
||||
case USART1:
|
||||
uclk = rcu_clock_freq_get(CK_APB1);
|
||||
break;
|
||||
case USART2:
|
||||
uclk = rcu_clock_freq_get(CK_APB1);
|
||||
break;
|
||||
case UART3:
|
||||
uclk = rcu_clock_freq_get(CK_APB1);
|
||||
break;
|
||||
case UART4:
|
||||
uclk = rcu_clock_freq_get(CK_APB1);
|
||||
break;
|
||||
case UART6:
|
||||
uclk = rcu_clock_freq_get(CK_APB1);
|
||||
break;
|
||||
case UART7:
|
||||
uclk = rcu_clock_freq_get(CK_APB1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(USART_CTL0(usart_periph) & USART_CTL0_OVSMOD) {
|
||||
/* when oversampling by 8, configure the value of USART_BAUD */
|
||||
udiv = ((2U * uclk) + baudval / 2U) / baudval;
|
||||
intdiv = udiv & 0xfff0U;
|
||||
fradiv = (udiv >> 1U) & 0x7U;
|
||||
USART_BAUD(usart_periph) = ((USART_BAUD_FRADIV | USART_BAUD_INTDIV) & (intdiv | fradiv));
|
||||
} else {
|
||||
/* when oversampling by 16, configure the value of USART_BAUD */
|
||||
udiv = (uclk + baudval / 2U) / baudval;
|
||||
intdiv = udiv & 0xfff0U;
|
||||
fradiv = udiv & 0xfU;
|
||||
USART_BAUD(usart_periph) = ((USART_BAUD_FRADIV | USART_BAUD_INTDIV) & (intdiv | fradiv));
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure USART parity function
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[in] paritycfg: configure USART parity
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg USART_PM_NONE: no parity
|
||||
\arg USART_PM_EVEN: even parity
|
||||
\arg USART_PM_ODD: odd parity
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_parity_config(uint32_t usart_periph, uint32_t paritycfg)
|
||||
{
|
||||
/* clear USART_CTL0 PM,PCEN Bits */
|
||||
USART_CTL0(usart_periph) &= ~(USART_CTL0_PM | USART_CTL0_PCEN);
|
||||
/* configure USART parity mode */
|
||||
USART_CTL0(usart_periph) |= paritycfg ;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure USART word length
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[in] wlen: USART word length configure
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg USART_WL_8BIT: 8 bits
|
||||
\arg USART_WL_9BIT: 9 bits
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_word_length_set(uint32_t usart_periph, uint32_t wlen)
|
||||
{
|
||||
/* clear USART_CTL0 WL bit */
|
||||
USART_CTL0(usart_periph) &= ~USART_CTL0_WL;
|
||||
/* configure USART word length */
|
||||
USART_CTL0(usart_periph) |= wlen;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure USART stop bit length
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[in] stblen: USART stop bit configure
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg USART_STB_1BIT: 1 bit
|
||||
\arg USART_STB_0_5BIT: 0.5 bit(not available for UARTx(x=3,4,6,7))
|
||||
\arg USART_STB_2BIT: 2 bits
|
||||
\arg USART_STB_1_5BIT: 1.5 bits(not available for UARTx(x=3,4,6,7))
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_stop_bit_set(uint32_t usart_periph, uint32_t stblen)
|
||||
{
|
||||
/* clear USART_CTL1 STB bits */
|
||||
USART_CTL1(usart_periph) &= ~USART_CTL1_STB;
|
||||
/* configure USART stop bits */
|
||||
USART_CTL1(usart_periph) |= stblen;
|
||||
}
|
||||
/*!
|
||||
\brief enable USART
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_enable(uint32_t usart_periph)
|
||||
{
|
||||
USART_CTL0(usart_periph) |= USART_CTL0_UEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable USART
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_disable(uint32_t usart_periph)
|
||||
{
|
||||
USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure USART transmitter
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[in] txconfig: enable or disable USART transmitter
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg USART_TRANSMIT_ENABLE: enable USART transmission
|
||||
\arg USART_TRANSMIT_DISABLE: enable USART transmission
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_transmit_config(uint32_t usart_periph, uint32_t txconfig)
|
||||
{
|
||||
uint32_t ctl = 0U;
|
||||
|
||||
ctl = USART_CTL0(usart_periph);
|
||||
ctl &= ~USART_CTL0_TEN;
|
||||
ctl |= txconfig;
|
||||
/* configure transfer mode */
|
||||
USART_CTL0(usart_periph) = ctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure USART receiver
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[in] rxconfig: enable or disable USART receiver
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg USART_RECEIVE_ENABLE: enable USART reception
|
||||
\arg USART_RECEIVE_DISABLE: disable USART reception
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_receive_config(uint32_t usart_periph, uint32_t rxconfig)
|
||||
{
|
||||
uint32_t ctl = 0U;
|
||||
|
||||
ctl = USART_CTL0(usart_periph);
|
||||
ctl &= ~USART_CTL0_REN;
|
||||
ctl |= rxconfig;
|
||||
/* configure transfer mode */
|
||||
USART_CTL0(usart_periph) = ctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief data is transmitted/received with the LSB/MSB first
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)
|
||||
\param[in] msbf: LSB/MSB
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg USART_MSBF_LSB: LSB first
|
||||
\arg USART_MSBF_MSB: MSB first
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_data_first_config(uint32_t usart_periph, uint32_t msbf)
|
||||
{
|
||||
uint32_t ctl = 0U;
|
||||
|
||||
ctl = USART_CTL3(usart_periph);
|
||||
ctl &= ~(USART_CTL3_MSBF);
|
||||
ctl |= msbf;
|
||||
/* configure data transmitted/received mode */
|
||||
USART_CTL3(usart_periph) = ctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure USART inversion
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)
|
||||
\param[in] invertpara: refer to enum USART_INVERT_CONFIG
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg USART_DINV_ENABLE: data bit level inversion
|
||||
\arg USART_DINV_DISABLE: data bit level not inversion
|
||||
\arg USART_TXPIN_ENABLE: TX pin level inversion
|
||||
\arg USART_TXPIN_DISABLE: TX pin level not inversion
|
||||
\arg USART_RXPIN_ENABLE: RX pin level inversion
|
||||
\arg USART_RXPIN_DISABLE: RX pin level not inversion
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_invert_config(uint32_t usart_periph, usart_invert_enum invertpara)
|
||||
{
|
||||
/* inverted or not the specified siginal */
|
||||
switch(invertpara) {
|
||||
case USART_DINV_ENABLE:
|
||||
USART_CTL3(usart_periph) |= USART_CTL3_DINV;
|
||||
break;
|
||||
case USART_TXPIN_ENABLE:
|
||||
USART_CTL3(usart_periph) |= USART_CTL3_TINV;
|
||||
break;
|
||||
case USART_RXPIN_ENABLE:
|
||||
USART_CTL3(usart_periph) |= USART_CTL3_RINV;
|
||||
break;
|
||||
case USART_DINV_DISABLE:
|
||||
USART_CTL3(usart_periph) &= ~(USART_CTL3_DINV);
|
||||
break;
|
||||
case USART_TXPIN_DISABLE:
|
||||
USART_CTL3(usart_periph) &= ~(USART_CTL3_TINV);
|
||||
break;
|
||||
case USART_RXPIN_DISABLE:
|
||||
USART_CTL3(usart_periph) &= ~(USART_CTL3_RINV);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the USART oversample mode
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[in] oversamp: oversample value
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg USART_OVSMOD_8: 8 bits
|
||||
\arg USART_OVSMOD_16: 16 bits
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_oversample_config(uint32_t usart_periph, uint32_t oversamp)
|
||||
{
|
||||
/* clear OVSMOD bit */
|
||||
USART_CTL0(usart_periph) &= ~(USART_CTL0_OVSMOD);
|
||||
USART_CTL0(usart_periph) |= oversamp;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure sample bit method
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[in] obsm: sample bit
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg USART_OSB_1bit: 1 bit
|
||||
\arg USART_OSB_3bit: 3 bits
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_sample_bit_config(uint32_t usart_periph, uint32_t obsm)
|
||||
{
|
||||
USART_CTL2(usart_periph) &= ~(USART_CTL2_OSB);
|
||||
USART_CTL2(usart_periph) |= obsm;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable receiver timeout of USART
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_receiver_timeout_enable(uint32_t usart_periph)
|
||||
{
|
||||
USART_CTL3(usart_periph) |= USART_CTL3_RTEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable receiver timeout of USART
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_receiver_timeout_disable(uint32_t usart_periph)
|
||||
{
|
||||
USART_CTL3(usart_periph) &= ~(USART_CTL3_RTEN);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set the receiver timeout threshold of USART
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)
|
||||
\param[in] rtimeout: 0-0x00FFFFFF
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_receiver_timeout_threshold_config(uint32_t usart_periph, uint32_t rtimeout)
|
||||
{
|
||||
USART_RT(usart_periph) &= ~(USART_RT_RT);
|
||||
USART_RT(usart_periph) |= rtimeout;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief USART transmit data function
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[in] data: data of transmission
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_data_transmit(uint32_t usart_periph, uint16_t data)
|
||||
{
|
||||
USART_DATA(usart_periph) = USART_DATA_DATA & (uint32_t)data;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief USART receive data function
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[out] none
|
||||
\retval data of received
|
||||
*/
|
||||
uint16_t usart_data_receive(uint32_t usart_periph)
|
||||
{
|
||||
return (uint16_t)(GET_BITS(USART_DATA(usart_periph), 0U, 8U));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the address of the USART in wake up by address match mode
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[in] addr: address of USART/UART
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_address_config(uint32_t usart_periph, uint8_t addr)
|
||||
{
|
||||
USART_CTL1(usart_periph) &= ~(USART_CTL1_ADDR);
|
||||
USART_CTL1(usart_periph) |= (USART_CTL1_ADDR & (uint32_t)addr);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable mute mode
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_mute_mode_enable(uint32_t usart_periph)
|
||||
{
|
||||
USART_CTL0(usart_periph) |= USART_CTL0_RWU;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable mute mode
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_mute_mode_disable(uint32_t usart_periph)
|
||||
{
|
||||
USART_CTL0(usart_periph) &= ~(USART_CTL0_RWU);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure wakeup method in mute mode
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[in] wmehtod: two method be used to enter or exit the mute mode
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg USART_WM_IDLE: idle line
|
||||
\arg USART_WM_ADDR: address mask
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_mute_mode_wakeup_config(uint32_t usart_periph, uint32_t wmehtod)
|
||||
{
|
||||
USART_CTL0(usart_periph) &= ~(USART_CTL0_WM);
|
||||
USART_CTL0(usart_periph) |= wmehtod;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable LIN mode
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_lin_mode_enable(uint32_t usart_periph)
|
||||
{
|
||||
USART_CTL1(usart_periph) |= USART_CTL1_LMEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable LIN mode
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_lin_mode_disable(uint32_t usart_periph)
|
||||
{
|
||||
USART_CTL1(usart_periph) &= ~(USART_CTL1_LMEN);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure lin break frame length
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[in] lblen: lin break frame length
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg USART_LBLEN_10B: 10 bits
|
||||
\arg USART_LBLEN_11B: 11 bits
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_lin_break_detection_length_config(uint32_t usart_periph, uint32_t lblen)
|
||||
{
|
||||
USART_CTL1(usart_periph) &= ~(USART_CTL1_LBLEN);
|
||||
USART_CTL1(usart_periph) |= (USART_CTL1_LBLEN & lblen);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief send break frame
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_send_break(uint32_t usart_periph)
|
||||
{
|
||||
USART_CTL0(usart_periph) |= USART_CTL0_SBKCMD;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable half duplex mode
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_halfduplex_enable(uint32_t usart_periph)
|
||||
{
|
||||
USART_CTL2(usart_periph) |= USART_CTL2_HDEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable half duplex mode
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_halfduplex_disable(uint32_t usart_periph)
|
||||
{
|
||||
USART_CTL2(usart_periph) &= ~(USART_CTL2_HDEN);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable CK pin in synchronous mode
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_synchronous_clock_enable(uint32_t usart_periph)
|
||||
{
|
||||
USART_CTL1(usart_periph) |= USART_CTL1_CKEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable CK pin in synchronous mode
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_synchronous_clock_disable(uint32_t usart_periph)
|
||||
{
|
||||
USART_CTL1(usart_periph) &= ~(USART_CTL1_CKEN);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure USART synchronous mode parameters
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)
|
||||
\param[in] clen: CK length
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg USART_CLEN_NONE: there are 7 CK pulses for an 8 bit frame and 8 CK pulses for a 9 bit frame
|
||||
\arg USART_CLEN_EN: there are 8 CK pulses for an 8 bit frame and 9 CK pulses for a 9 bit frame
|
||||
\param[in] cph: clock phase
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg USART_CPH_1CK: first clock transition is the first data capture edge
|
||||
\arg USART_CPH_2CK: second clock transition is the first data capture edge
|
||||
\param[in] cpl: clock polarity
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg USART_CPL_LOW: steady low value on CK pin
|
||||
\arg USART_CPL_HIGH: steady high value on CK pin
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_synchronous_clock_config(uint32_t usart_periph, uint32_t clen, uint32_t cph, uint32_t cpl)
|
||||
{
|
||||
USART_CTL1(usart_periph) &= ~(USART_CTL1_CLEN | USART_CTL1_CPH | USART_CTL1_CPL);
|
||||
USART_CTL1(usart_periph) |= (USART_CTL1_CLEN & clen) | (USART_CTL1_CPH & cph) | (USART_CTL1_CPL & cpl);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure guard time value in smartcard mode
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)
|
||||
\param[in] guat: guard time value, 0-0xFF
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_guard_time_config(uint32_t usart_periph, uint8_t guat)
|
||||
{
|
||||
USART_GP(usart_periph) &= ~(USART_GP_GUAT);
|
||||
USART_GP(usart_periph) |= (USART_GP_GUAT & ((uint32_t)guat << GP_GUAT_OFFSET));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable smartcard mode
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_smartcard_mode_enable(uint32_t usart_periph)
|
||||
{
|
||||
USART_CTL2(usart_periph) |= USART_CTL2_SCEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable smartcard mode
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_smartcard_mode_disable(uint32_t usart_periph)
|
||||
{
|
||||
USART_CTL2(usart_periph) &= ~(USART_CTL2_SCEN);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable NACK in smartcard mode
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_smartcard_mode_nack_enable(uint32_t usart_periph)
|
||||
{
|
||||
USART_CTL2(usart_periph) |= USART_CTL2_NKEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable NACK in smartcard mode
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_smartcard_mode_nack_disable(uint32_t usart_periph)
|
||||
{
|
||||
USART_CTL2(usart_periph) &= ~(USART_CTL2_NKEN);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure smartcard auto-retry number
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)
|
||||
\param[in] scrtnum: smartcard auto-retry number
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_smartcard_autoretry_config(uint32_t usart_periph, uint8_t scrtnum)
|
||||
{
|
||||
USART_CTL3(usart_periph) &= ~(USART_CTL3_SCRTNUM);
|
||||
USART_CTL3(usart_periph) |= (USART_CTL3_SCRTNUM & ((uint32_t)scrtnum << CTL3_SCRTNUM_OFFSET));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure block length in Smartcard T=1 reception
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)
|
||||
\param[in] bl: block length
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_block_length_config(uint32_t usart_periph, uint8_t bl)
|
||||
{
|
||||
USART_RT(usart_periph) &= ~(USART_RT_BL);
|
||||
USART_RT(usart_periph) |= (USART_RT_BL & ((uint32_t)bl << RT_BL_OFFSET));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable IrDA mode
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_irda_mode_enable(uint32_t usart_periph)
|
||||
{
|
||||
USART_CTL2(usart_periph) |= USART_CTL2_IREN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable IrDA mode
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_irda_mode_disable(uint32_t usart_periph)
|
||||
{
|
||||
USART_CTL2(usart_periph) &= ~(USART_CTL2_IREN);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the peripheral clock prescaler in USART IrDA low-power mode
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[in] psc: 0-0xFF
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_prescaler_config(uint32_t usart_periph, uint8_t psc)
|
||||
{
|
||||
USART_GP(usart_periph) &= ~(USART_GP_PSC);
|
||||
USART_GP(usart_periph) |= (uint32_t)psc;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure IrDA low-power
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[in] irlp: IrDA low-power or normal
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg USART_IRLP_LOW: low-power
|
||||
\arg USART_IRLP_NORMAL: normal
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_irda_lowpower_config(uint32_t usart_periph, uint32_t irlp)
|
||||
{
|
||||
USART_CTL2(usart_periph) &= ~(USART_CTL2_IRLP);
|
||||
USART_CTL2(usart_periph) |= (USART_CTL2_IRLP & irlp);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure hardware flow control RTS
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)
|
||||
\param[in] rtsconfig: enable or disable RTS
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg USART_RTS_ENABLE: enable RTS
|
||||
\arg USART_RTS_DISABLE: disable RTS
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_hardware_flow_rts_config(uint32_t usart_periph, uint32_t rtsconfig)
|
||||
{
|
||||
USART_CTL2(usart_periph) &= ~(USART_CTL2_RTSEN);
|
||||
USART_CTL2(usart_periph) |= (USART_CTL2_RTSEN & rtsconfig);
|
||||
}
|
||||
/*!
|
||||
\brief configure hardware flow control CTS
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)
|
||||
\param[in] ctsconfig: enable or disable CTS
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg USART_CTS_ENABLE: enable CTS
|
||||
\arg USART_CTS_DISABLE: disable CTS
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_hardware_flow_cts_config(uint32_t usart_periph, uint32_t ctsconfig)
|
||||
{
|
||||
USART_CTL2(usart_periph) &= ~(USART_CTL2_CTSEN);
|
||||
USART_CTL2(usart_periph) |= (USART_CTL2_CTSEN & ctsconfig);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure break frame coherence mode
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)
|
||||
\param[in] bcm:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg USART_BCM_NONE: no parity error is detected
|
||||
\arg USART_BCM_EN: parity error is detected
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_break_frame_coherence_config(uint32_t usart_periph, uint32_t bcm)
|
||||
{
|
||||
USART_CHC(usart_periph) &= ~(USART_CHC_BCM);
|
||||
USART_CHC(usart_periph) |= (USART_CHC_BCM & bcm);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure parity check coherence mode
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[in] pcm:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg USART_PCM_NONE: not check parity
|
||||
\arg USART_PCM_EN: check the parity
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_parity_check_coherence_config(uint32_t usart_periph, uint32_t pcm)
|
||||
{
|
||||
USART_CHC(usart_periph) &= ~(USART_CHC_PCM);
|
||||
USART_CHC(usart_periph) |= (USART_CHC_PCM & pcm);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure hardware flow control coherence mode
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)
|
||||
\param[in] hcm:
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg USART_HCM_NONE: nRTS signal equals to the rxne status register
|
||||
\arg USART_HCM_EN: nRTS signal is set when the last data bit has been sampled
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_hardware_flow_coherence_config(uint32_t usart_periph, uint32_t hcm)
|
||||
{
|
||||
USART_CHC(usart_periph) &= ~(USART_CHC_HCM);
|
||||
USART_CHC(usart_periph) |= (USART_CHC_HCM & hcm);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure USART DMA reception
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[in] dmacmd: enable or disable DMA for reception
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg USART_RECEIVE_DMA_ENABLE: DMA enable for reception
|
||||
\arg USART_RECEIVE_DMA_DISABLE: DMA disable for reception
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_dma_receive_config(uint32_t usart_periph, uint32_t dmacmd)
|
||||
{
|
||||
USART_CTL2(usart_periph) &= ~(USART_CTL2_DENR);
|
||||
USART_CTL2(usart_periph) |= (USART_CTL2_DENR & dmacmd);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure USART DMA transmission
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[in] dmacmd: enable or disable DMA for transmission
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg USART_TRANSMIT_DMA_ENABLE: DMA enable for transmission
|
||||
\arg USART_TRANSMIT_DMA_DISABLE: DMA disable for transmission
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_dma_transmit_config(uint32_t usart_periph, uint32_t dmacmd)
|
||||
{
|
||||
USART_CTL2(usart_periph) &= ~(USART_CTL2_DENT);
|
||||
USART_CTL2(usart_periph) |= (USART_CTL2_DENT & dmacmd);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get flag in STAT0/STAT1/CHC register
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[in] flag: USART flags, refer to usart_flag_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg USART_FLAG_CTS: CTS change flag
|
||||
\arg USART_FLAG_LBD: LIN break detected flag
|
||||
\arg USART_FLAG_TBE: transmit data buffer empty
|
||||
\arg USART_FLAG_TC: transmission complete
|
||||
\arg USART_FLAG_RBNE: read data buffer not empty
|
||||
\arg USART_FLAG_IDLE: IDLE frame detected flag
|
||||
\arg USART_FLAG_ORERR: overrun error
|
||||
\arg USART_FLAG_NERR: noise error flag
|
||||
\arg USART_FLAG_FERR: frame error flag
|
||||
\arg USART_FLAG_PERR: parity error flag
|
||||
\arg USART_FLAG_BSY: busy flag
|
||||
\arg USART_FLAG_EB: end of block flag
|
||||
\arg USART_FLAG_RT: receiver timeout flag
|
||||
\arg USART_FLAG_EPERR: early parity error flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus usart_flag_get(uint32_t usart_periph, usart_flag_enum flag)
|
||||
{
|
||||
if(RESET != (USART_REG_VAL(usart_periph, flag) & BIT(USART_BIT_POS(flag)))) {
|
||||
return SET;
|
||||
} else {
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear flag in STAT0/STAT1/CHC register
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[in] flag: USART flags, refer to usart_flag_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg USART_FLAG_CTS: CTS change flag
|
||||
\arg USART_FLAG_LBD: LIN break detected flag
|
||||
\arg USART_FLAG_TC: transmission complete
|
||||
\arg USART_FLAG_RBNE: read data buffer not empty
|
||||
\arg USART_FLAG_EB: end of block flag
|
||||
\arg USART_FLAG_RT: receiver timeout flag
|
||||
\arg USART_FLAG_EPERR: early parity error flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_flag_clear(uint32_t usart_periph, usart_flag_enum flag)
|
||||
{
|
||||
if (USART_FLAG_EPERR == flag) {
|
||||
USART_REG_VAL(usart_periph, flag) &= ~BIT(USART_BIT_POS(flag));
|
||||
} else {
|
||||
USART_REG_VAL(usart_periph, flag) = ~BIT(USART_BIT_POS(flag));
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable USART interrupt
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[in] interrupt: USART interrupts, refer to usart_interrupt_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg USART_INT_PERR: parity error interrupt
|
||||
\arg USART_INT_TBE: transmitter buffer empty interrupt
|
||||
\arg USART_INT_TC: transmission complete interrupt
|
||||
\arg USART_INT_RBNE: read data buffer not empty interrupt and overrun error interrupt
|
||||
\arg USART_INT_IDLE: IDLE line detected interrupt
|
||||
\arg USART_INT_LBD: LIN break detected interrupt
|
||||
\arg USART_INT_ERR: error interrupt
|
||||
\arg USART_INT_CTS: CTS interrupt
|
||||
\arg USART_INT_RT: interrupt enable bit of receive timeout event
|
||||
\arg USART_INT_EB: interrupt enable bit of end of block event
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_interrupt_enable(uint32_t usart_periph, usart_interrupt_enum interrupt)
|
||||
{
|
||||
USART_REG_VAL(usart_periph, interrupt) |= BIT(USART_BIT_POS(interrupt));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable USART interrupt
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[in] interrupt: USART interrupts, refer to usart_interrupt_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg USART_INT_PERR: parity error interrupt
|
||||
\arg USART_INT_TBE: transmitter buffer empty interrupt
|
||||
\arg USART_INT_TC: transmission complete interrupt
|
||||
\arg USART_INT_RBNE: read data buffer not empty interrupt and overrun error interrupt
|
||||
\arg USART_INT_IDLE: IDLE line detected interrupt
|
||||
\arg USART_INT_LBD: LIN break detected interrupt
|
||||
\arg USART_INT_ERR: error interrupt
|
||||
\arg USART_INT_CTS: CTS interrupt
|
||||
\arg USART_INT_RT: interrupt enable bit of receive timeout event
|
||||
\arg USART_INT_EB: interrupt enable bit of end of block event
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_interrupt_disable(uint32_t usart_periph, usart_interrupt_enum interrupt)
|
||||
{
|
||||
USART_REG_VAL(usart_periph, interrupt) &= ~BIT(USART_BIT_POS(interrupt));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get USART interrupt and flag status
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[in] int_flag: USART interrupt flags, refer to usart_interrupt_flag_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg USART_INT_FLAG_PERR: parity error interrupt and flag
|
||||
\arg USART_INT_FLAG_TBE: transmitter buffer empty interrupt and flag
|
||||
\arg USART_INT_FLAG_TC: transmission complete interrupt and flag
|
||||
\arg USART_INT_FLAG_RBNE: read data buffer not empty interrupt and flag
|
||||
\arg USART_INT_FLAG_RBNE_ORERR: read data buffer not empty interrupt and overrun error flag
|
||||
\arg USART_INT_FLAG_IDLE: IDLE line detected interrupt and flag
|
||||
\arg USART_INT_FLAG_LBD: LIN break detected interrupt and flag
|
||||
\arg USART_INT_FLAG_CTS: CTS interrupt and flag
|
||||
\arg USART_INT_FLAG_ERR_ORERR: error interrupt and overrun error
|
||||
\arg USART_INT_FLAG_ERR_NERR: error interrupt and noise error flag
|
||||
\arg USART_INT_FLAG_ERR_FERR: error interrupt and frame error flag
|
||||
\arg USART_INT_FLAG_EB: interrupt enable bit of end of block event and flag
|
||||
\arg USART_INT_FLAG_RT: interrupt enable bit of receive timeout event and flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus usart_interrupt_flag_get(uint32_t usart_periph, usart_interrupt_flag_enum int_flag)
|
||||
{
|
||||
uint32_t intenable = 0U, flagstatus = 0U;
|
||||
/* get the interrupt enable bit status */
|
||||
intenable = (USART_REG_VAL(usart_periph, int_flag) & BIT(USART_BIT_POS(int_flag)));
|
||||
/* get the corresponding flag bit status */
|
||||
flagstatus = (USART_REG_VAL2(usart_periph, int_flag) & BIT(USART_BIT_POS2(int_flag)));
|
||||
|
||||
if((0U != flagstatus) && (0U != intenable)) {
|
||||
return SET;
|
||||
} else {
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear USART interrupt flag in STAT0/STAT1 register
|
||||
\param[in] usart_periph: USARTx(x=0,1,2,5)/UARTx(x=3,4,6,7)
|
||||
\param[in] int_flag: USART interrupt flags, refer to usart_interrupt_flag_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg USART_INT_FLAG_CTS: CTS change flag
|
||||
\arg USART_INT_FLAG_LBD: LIN break detected flag
|
||||
\arg USART_INT_FLAG_TC: transmission complete
|
||||
\arg USART_INT_FLAG_RBNE: read data buffer not empty
|
||||
\arg USART_INT_FLAG_EB: end of block flag
|
||||
\arg USART_INT_FLAG_RT: receiver timeout flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void usart_interrupt_flag_clear(uint32_t usart_periph, usart_interrupt_flag_enum int_flag)
|
||||
{
|
||||
USART_REG_VAL2(usart_periph, int_flag) &= ~BIT(USART_BIT_POS2(int_flag));
|
||||
}
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
/*!
|
||||
\file gd32f4xx_wwdgt.c
|
||||
\brief WWDGT driver
|
||||
|
||||
\version 2024-12-20, V3.3.1, firmware for GD32F4xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2024, 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 "gd32f4xx_wwdgt.h"
|
||||
|
||||
/*!
|
||||
\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 window watchdog timer counter
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void wwdgt_enable(void)
|
||||
{
|
||||
WWDGT_CTL |= WWDGT_CTL_WDGTEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the window watchdog timer 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: 0x00 - 0x7F
|
||||
\param[in] window: 0x00 - 0x7F
|
||||
\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 = (PCLK1/4096)/1
|
||||
\arg WWDGT_CFG_PSC_DIV2: the time base of window watchdog counter = (PCLK1/4096)/2
|
||||
\arg WWDGT_CFG_PSC_DIV4: the time base of window watchdog counter = (PCLK1/4096)/4
|
||||
\arg WWDGT_CFG_PSC_DIV8: the time base of window watchdog counter = (PCLK1/4096)/8
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void wwdgt_config(uint16_t counter, uint16_t window, uint32_t prescaler)
|
||||
{
|
||||
/* configure WIN and PSC bits, configure CNT bit */
|
||||
WWDGT_CTL = (uint32_t)(CTL_CNT(counter));
|
||||
WWDGT_CFG = (uint32_t)(CFG_WIN(window) | prescaler);
|
||||
}
|
||||
|
||||
/*!
|
||||
\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);
|
||||
}
|
||||
|
||||
/*!
|
||||
\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;
|
||||
}
|
||||
Reference in New Issue
Block a user