mirror of
https://github.com/EFeru/hoverboard-sideboard-hack-GD.git
synced 2025-08-17 09:06:11 +00:00
Initial commit
This commit is contained in:
817
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_adc.c
Normal file
817
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_adc.c
Normal file
@@ -0,0 +1,817 @@
|
||||
/*!
|
||||
\file gd32f1x0_adc.c
|
||||
\brief ADC driver
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2017 GigaDevice
|
||||
|
||||
2014-12-26, V1.0.0, platform GD32F1x0(x=3,5)
|
||||
2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9)
|
||||
2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
*/
|
||||
|
||||
#include "gd32f1x0_adc.h"
|
||||
|
||||
/*!
|
||||
\brief ADC reset
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void adc_deinit(void)
|
||||
{
|
||||
rcu_periph_reset_enable(RCU_ADCRST);
|
||||
rcu_periph_reset_disable(RCU_ADCRST);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable ADC interface
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void adc_enable(void)
|
||||
{
|
||||
if(RESET == (ADC_CTL1 & ADC_CTL1_ADCON)){
|
||||
ADC_CTL1 |= (uint32_t)ADC_CTL1_ADCON;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable ADC interface
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void adc_disable(void)
|
||||
{
|
||||
ADC_CTL1 &= (uint32_t)~(ADC_CTL1_ADCON);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief ADC calibration and reset calibration
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void adc_calibration_enable(void)
|
||||
{
|
||||
/* reset the selected ADC1 calibration registers */
|
||||
ADC_CTL1 |= (uint32_t) ADC_CTL1_RSTCLB;
|
||||
/* check the RSTCLB bit state */
|
||||
while((ADC_CTL1 & ADC_CTL1_RSTCLB)){
|
||||
}
|
||||
/* enable ADC calibration process */
|
||||
ADC_CTL1 |= ADC_CTL1_CLB;
|
||||
/* check the CLB bit state */
|
||||
while((ADC_CTL1 & ADC_CTL1_CLB)){
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DMA request
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void adc_dma_mode_enable(void)
|
||||
{
|
||||
ADC_CTL1 |= (uint32_t)(ADC_CTL1_DMA);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DMA request
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void adc_dma_mode_disable(void)
|
||||
{
|
||||
ADC_CTL1 &= ~((uint32_t)ADC_CTL1_DMA);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable ADC0 temperature sensor and Vrefint channel
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void adc_tempsensor_vrefint_enable(void)
|
||||
{
|
||||
/* enable the temperature sensor and Vrefint channel */
|
||||
ADC_CTL1 |= ADC_CTL1_TSVREN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable ADC0 temperature sensor and Vrefint channel
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void adc_tempsensor_vrefint_disable(void)
|
||||
{
|
||||
/* disable the temperature sensor and Vrefint channel */
|
||||
ADC_CTL1 &= ~ADC_CTL1_TSVREN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the vbat channel
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void adc_vbat_enable(void)
|
||||
{
|
||||
/* enable the vbat channel */
|
||||
ADC_CTL1 |= ADC_CTL1_VBETEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the vbat channel
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void adc_vbat_disable(void)
|
||||
{
|
||||
/* disable the vbat channel */
|
||||
ADC_CTL1 &= ~ADC_CTL1_VBETEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief adc discontinuous mode config
|
||||
\param[in] channel_group: select the channel group
|
||||
\arg ADC_REGULAR_CHANNEL: regular channel group
|
||||
\arg ADC_INSERTED_CHANNEL: inserted channel group
|
||||
\param[in] length: number of conversions in discontinuous mode,the number can be 1..8
|
||||
for regular channel ,the number is insignificant for inserted channel
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void adc_discontinuous_mode_config(uint8_t channel_group,uint8_t length)
|
||||
{
|
||||
ADC_CTL0 &= ~((uint32_t)(ADC_CTL0_DISRC | ADC_CTL0_DISIC));
|
||||
switch(channel_group){
|
||||
case ADC_REGULAR_CHANNEL:
|
||||
/* config the number of conversions in discontinuous mode */
|
||||
ADC_CTL0 &= ~((uint32_t)ADC_CTL0_DISNUM);
|
||||
ADC_CTL0 |= (uint32_t)(((uint32_t)length - 1U) << 13U);
|
||||
|
||||
ADC_CTL0 |= (uint32_t)ADC_CTL0_DISRC;
|
||||
break;
|
||||
case ADC_INSERTED_CHANNEL:
|
||||
ADC_CTL0 |= (uint32_t)ADC_CTL0_DISIC;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable or disable ADC special function
|
||||
\param[in] function: the function to config
|
||||
one or more parameters can be selected below
|
||||
\arg ADC_SCAN_MODE: scan mode select
|
||||
\arg ADC_INSERTED_CHANNEL_AUTO: inserted channel group convert automatically
|
||||
\arg ADC_CONTINUOUS_MODE: continuous mode select
|
||||
\param[in] newvalue: ENABLE or DISABLE
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void adc_special_function_config(uint32_t function, ControlStatus newvalue)
|
||||
{
|
||||
if(newvalue){
|
||||
if(RESET != (function & ADC_SCAN_MODE)){
|
||||
ADC_CTL0 |= ADC_SCAN_MODE;
|
||||
}
|
||||
if(RESET != (function & ADC_INSERTED_CHANNEL_AUTO)){
|
||||
ADC_CTL0 |= ADC_INSERTED_CHANNEL_AUTO;
|
||||
}
|
||||
if(RESET != (function & ADC_CONTINUOUS_MODE)){
|
||||
ADC_CTL1 |= ADC_CONTINUOUS_MODE;
|
||||
}
|
||||
}else{
|
||||
if(RESET != (function & ADC_SCAN_MODE)){
|
||||
ADC_CTL0 &= ~ADC_SCAN_MODE;
|
||||
}
|
||||
if(RESET != (function & ADC_INSERTED_CHANNEL_AUTO)){
|
||||
ADC_CTL0 &= ~ADC_INSERTED_CHANNEL_AUTO;
|
||||
}
|
||||
if(RESET != (function & ADC_CONTINUOUS_MODE)){
|
||||
ADC_CTL1 &= ~ADC_CONTINUOUS_MODE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief adc data alignment config
|
||||
\param[in] data_alignment: data alignment select
|
||||
only one parameter can be selected
|
||||
\arg ADC_DATAALIGN_RIGHT: LSB alignment
|
||||
\arg ADC_DATAALIGN_LEFT: MSB alignment
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void adc_data_alignment_config(uint32_t data_alignment)
|
||||
{
|
||||
if(data_alignment){
|
||||
ADC_CTL1 |= ADC_CTL1_DAL;
|
||||
}else{
|
||||
ADC_CTL1 &= ~((uint32_t)ADC_CTL1_DAL);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief config the length of regular channel group or inserted channel group
|
||||
\param[in] channel_group: select the channel group
|
||||
only one parameter can be selected
|
||||
\arg ADC_REGULAR_CHANNEL: regular channel group
|
||||
\arg ADC_INSERTED_CHANNEL: inserted channel group
|
||||
\param[in] length: the length of the channel
|
||||
regular channel 1-17
|
||||
inserted channel 1-4
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void adc_channel_length_config(uint8_t channel_group,uint32_t length)
|
||||
{
|
||||
switch(channel_group){
|
||||
case ADC_REGULAR_CHANNEL:
|
||||
ADC_RSQ0 &= ~(((uint32_t)length - 1U) << 20U);
|
||||
ADC_RSQ0 |= (((uint32_t)length - 1U) << 20U);
|
||||
break;
|
||||
case ADC_INSERTED_CHANNEL:
|
||||
ADC_ISQ &= ~(((uint32_t)length - 1U) << 20U);
|
||||
ADC_ISQ |= (((uint32_t)length - 1U) << 20U);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief ADC regular channel config
|
||||
\param[in] rank: the regular group sequencer rank,this parameter must be between 0 to 15
|
||||
\param[in] channel: the selected ADC channel
|
||||
\arg ADC_CHANNEL_x(x=0..18): ADC Channelx
|
||||
\param[in] sample_time: the sample time value
|
||||
\arg ADC_SAMPLETIME_1POINT5: 1.5 cycles
|
||||
\arg ADC_SAMPLETIME_7POINT5: 7.5 cycles
|
||||
\arg ADC_SAMPLETIME_13POINT5: 13.5 cycles
|
||||
\arg ADC_SAMPLETIME_28POINT5: 28.5 cycles
|
||||
\arg ADC_SAMPLETIME_41POINT5: 41.5 cycles
|
||||
\arg ADC_SAMPLETIME_55POINT5: 55.5 cycles
|
||||
\arg ADC_SAMPLETIME_71POINT5: 71.5 cycles
|
||||
\arg ADC_SAMPLETIME_239POINT5: 239.5 cycles
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void adc_regular_channel_config(uint8_t rank, uint8_t channel,uint32_t sample_time)
|
||||
{
|
||||
uint32_t rsq,sampt;
|
||||
|
||||
#ifdef GD32F130_150
|
||||
if(ADC_CHANNEL_18 == channel){
|
||||
channel = ADC_CHANNEL_0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* configure ADC regular sequence */
|
||||
if(rank < 6U){
|
||||
rsq = ADC_RSQ2;
|
||||
rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (5U*rank)));
|
||||
rsq |= ((uint32_t)channel << (5U*rank));
|
||||
ADC_RSQ2 = rsq;
|
||||
}else if(rank < 12U){
|
||||
rsq = ADC_RSQ1;
|
||||
rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (5U*(rank-6U))));
|
||||
rsq |= ((uint32_t)channel << (5U*(rank-6U)));
|
||||
ADC_RSQ1 = rsq;
|
||||
}else if(rank < 16U){
|
||||
rsq = ADC_RSQ0;
|
||||
rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (5U*(rank-12U))));
|
||||
rsq |= ((uint32_t)channel << (5U*(rank-12U)));
|
||||
ADC_RSQ0 = rsq;
|
||||
}else{
|
||||
/* illegal parameters */
|
||||
}
|
||||
|
||||
/* configure ADC sampling time */
|
||||
if(channel < 10U){
|
||||
sampt = ADC_SAMPT1;
|
||||
sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*channel)));
|
||||
sampt |= (uint32_t)(sample_time << (3U*channel));
|
||||
ADC_SAMPT1 = sampt;
|
||||
}else if(channel < 18U){
|
||||
sampt = ADC_SAMPT0;
|
||||
sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*(channel-10U))));
|
||||
sampt |= (uint32_t)(sample_time << (3U*(channel-10U)));
|
||||
ADC_SAMPT0 = sampt;
|
||||
}else{
|
||||
/* illegal parameters */
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief ADC inserted channel config
|
||||
\param[in] rank: the inserted group sequencer rank,this parameter must be between 0 to 3
|
||||
\param[in] channel: the selected ADC channel
|
||||
\arg ADC_CHANNEL_x(x=0..18): ADC Channelx
|
||||
\param[in] sample_time: The sample time value
|
||||
\arg ADC_SAMPLETIME_1POINT5: 1.5 cycles
|
||||
\arg ADC_SAMPLETIME_7POINT5: 7.5 cycles
|
||||
\arg ADC_SAMPLETIME_13POINT5: 13.5 cycles
|
||||
\arg ADC_SAMPLETIME_28POINT5: 28.5 cycles
|
||||
\arg ADC_SAMPLETIME_41POINT5: 41.5 cycles
|
||||
\arg ADC_SAMPLETIME_55POINT5: 55.5 cycles
|
||||
\arg ADC_SAMPLETIME_71POINT5: 71.5 cycles
|
||||
\arg ADC_SAMPLETIME_239POINT5: 239.5 cycles
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void adc_inserted_channel_config(uint8_t rank, uint8_t channel, uint32_t sample_time)
|
||||
{
|
||||
uint8_t inserted_length;
|
||||
uint32_t isq,sampt;
|
||||
|
||||
inserted_length = (uint8_t)GET_BITS(ADC_ISQ, 20, 21);
|
||||
if(rank < 5U){
|
||||
isq = ADC_ISQ;
|
||||
isq &= ~((uint32_t)(ADC_ISQ_ISQN << (15U - (inserted_length - rank)*5U)));
|
||||
isq |= ((uint32_t)channel << (15U - (inserted_length - rank)*5U));
|
||||
ADC_ISQ = isq;
|
||||
}
|
||||
|
||||
if(channel < 10U){
|
||||
sampt = ADC_SAMPT1;
|
||||
sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*channel)));
|
||||
sampt |= (uint32_t) sample_time << (3U*channel);
|
||||
ADC_SAMPT1 = sampt;
|
||||
}else if(channel < 19U){
|
||||
sampt = ADC_SAMPT0;
|
||||
sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*(channel-10U))));
|
||||
sampt |= ((uint32_t)sample_time << (3U*(channel-10U)));
|
||||
ADC_SAMPT0 = sampt;
|
||||
}else{
|
||||
/* illegal parameters */
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief adc inserted channel offset config
|
||||
\param[in] inserted_channel : insert channel select
|
||||
\arg ADC_INSERTED_CHANNEL_0: inserted channel0
|
||||
\arg ADC_INSERTED_CHANNEL_1: inserted channel1
|
||||
\arg ADC_INSERTED_CHANNEL_2: inserted channel2
|
||||
\arg ADC_INSERTED_CHANNEL_3: inserted channel3
|
||||
\param[in] offset : the offset data
|
||||
\param[out] none
|
||||
\retval the conversion value
|
||||
*/
|
||||
void adc_inserted_channel_offset_config(uint8_t inserted_channel,uint16_t offset)
|
||||
{
|
||||
uint8_t inserted_length;
|
||||
uint32_t num = 0U;
|
||||
|
||||
inserted_length = (uint8_t)GET_BITS(ADC_ISQ, 20U, 21U);
|
||||
num = 3U - (inserted_length - inserted_channel);
|
||||
|
||||
if(num <= 3U){
|
||||
/* calculate the offset of the register */
|
||||
num = num * 4U;
|
||||
/* config the offset of the selected channels */
|
||||
REG32((ADC_BASE) + 0x14U + num) = IOFFX_IOFF((uint32_t)offset);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief adc external trigger enable
|
||||
\param[in] adc_channel_group: select the channel group
|
||||
\arg ADC_REGULAR_CHANNEL: regular channel group
|
||||
\arg ADC_INSERTED_CHANNEL: inserted channel group
|
||||
\param[in] newvalue: ENABLE or DISABLE
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void adc_external_trigger_config(uint8_t channel_group,ControlStatus newvalue)
|
||||
{
|
||||
if(newvalue){
|
||||
if(RESET != (channel_group & ADC_REGULAR_CHANNEL)){
|
||||
ADC_CTL1 |= ADC_CTL1_ETERC;
|
||||
}
|
||||
if(RESET != (channel_group & ADC_INSERTED_CHANNEL)){
|
||||
ADC_CTL1 |= ADC_CTL1_ETEIC;
|
||||
}
|
||||
}else{
|
||||
if(RESET != (channel_group & ADC_REGULAR_CHANNEL)){
|
||||
ADC_CTL1 &= ~ADC_CTL1_ETERC;
|
||||
}
|
||||
if(RESET != (channel_group & ADC_INSERTED_CHANNEL)){
|
||||
ADC_CTL1 &= ~ADC_CTL1_ETEIC;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief adc external trigger source config
|
||||
\param[in] adc_channel_group: select the channel group
|
||||
\arg ADC_REGULAR_CHANNEL: regular channel group
|
||||
\arg ADC_INSERTED_CHANNEL: inserted channel group
|
||||
\param[in] external_trigger_source: regular or inserted group trigger source
|
||||
for regular channel:
|
||||
\arg ADC_EXTTRIG_REGULAR_T0_CH0: external trigger timer 0 CH0 event select for regular channel
|
||||
\arg ADC_EXTTRIG_REGULAR_T0_CH1: external trigger timer 0 CH1 event select for regular channel
|
||||
\arg ADC_EXTTRIG_REGULAR_T0_CH2: external trigger timer 0 CH2 event select for regular channel
|
||||
\arg ADC_EXTTRIG_REGULAR_T1_CH1: external trigger timer 1 CH1 event select for regular channel
|
||||
\arg ADC_EXTTRIG_REGULAR_T2_TRGO: external trigger timer 2 TRGO event select for regular channel
|
||||
\arg ADC_EXTTRIG_REGULAR_T14_CH0: external trigger timer 14 CH0 event select for regular channel
|
||||
\arg ADC_EXTTRIG_REGULAR_EXT_IT11: external trigger extiline 11 select for regular channel
|
||||
\arg ADC_EXTTRIG_REGULAR_SWRCST: software trigger select for regular channel
|
||||
for inserted channel:
|
||||
\arg ADC_EXTTRIG_INSERTED_T0_TRGO: external trigger timer0 TRGO event select for inserted channel
|
||||
\arg ADC_EXTTRIG_INSERTED_T0_CH3: external trigger timer0 CH3 event select for inserted channel
|
||||
\arg ADC_EXTTRIG_INSERTED_T1_TRGO: external trigger timer1 TRGO event select for inserted channel
|
||||
\arg ADC_EXTTRIG_INSERTED_T1_CH0: external trigger timer1 CH0 event select for inserted channel
|
||||
\arg ADC_EXTTRIG_INSERTED_T2_CH3: external trigger timer2 CH3 event select for inserted channel
|
||||
\arg ADC_EXTTRIG_INSERTED_T14_TRGO: external trigger timer14 TRGO event select for inserted channel
|
||||
\arg ADC_EXTTRIG_INSERTED_EXT_IT15: external interrupt line 15 select for inserted channel
|
||||
\arg ADC_EXTTRIG_INSERTED_SWRCST: software trigger select for inserted channel
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void adc_external_trigger_source_config(uint8_t channel_group,uint32_t external_trigger_source)
|
||||
{
|
||||
switch(channel_group){
|
||||
case ADC_REGULAR_CHANNEL:
|
||||
ADC_CTL1 &= ~((uint32_t)ADC_CTL1_ETSRC);
|
||||
ADC_CTL1 |= (uint32_t)external_trigger_source;
|
||||
break;
|
||||
case ADC_INSERTED_CHANNEL:
|
||||
ADC_CTL1 &= ~((uint32_t)ADC_CTL1_ETSIC);
|
||||
ADC_CTL1 |= (uint32_t)external_trigger_source;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief adc software trigger enable
|
||||
\param[in] adc_channel_group: select the channel group
|
||||
\arg ADC_REGULAR_CHANNEL: regular channel group
|
||||
\arg ADC_INSERTED_CHANNEL: inserted channel group
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void adc_software_trigger_enable(uint8_t channel_group)
|
||||
{
|
||||
if(RESET != (channel_group & ADC_REGULAR_CHANNEL)){
|
||||
ADC_CTL1 |= ADC_CTL1_SWRCST;
|
||||
}
|
||||
if(RESET != (channel_group & ADC_INSERTED_CHANNEL)){
|
||||
ADC_CTL1 |= ADC_CTL1_SWICST;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief adc regular group data register read
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval the conversion value
|
||||
*/
|
||||
uint16_t adc_regular_data_read(void)
|
||||
{
|
||||
return (uint16_t)(ADC_RDATA);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief adc inserted group data register read
|
||||
\param[in] inserted_channel : insert channel select
|
||||
\arg ADC_INSERTED_CHANNEL_0: inserted channel0
|
||||
\arg ADC_INSERTED_CHANNEL_1: inserted channel1
|
||||
\arg ADC_INSERTED_CHANNEL_2: inserted channel2
|
||||
\arg ADC_INSERTED_CHANNEL_3: inserted channel3
|
||||
\param[out] none
|
||||
\retval the conversion value
|
||||
*/
|
||||
uint16_t adc_inserted_data_read(uint8_t inserted_channel)
|
||||
{
|
||||
uint32_t idata;
|
||||
/* read the data of the selected channel */
|
||||
switch(inserted_channel){
|
||||
case ADC_INSERTED_CHANNEL_0:
|
||||
idata = ADC_IDATA0;
|
||||
break;
|
||||
case ADC_INSERTED_CHANNEL_1:
|
||||
idata = ADC_IDATA1;
|
||||
break;
|
||||
case ADC_INSERTED_CHANNEL_2:
|
||||
idata = ADC_IDATA2;
|
||||
break;
|
||||
case ADC_INSERTED_CHANNEL_3:
|
||||
idata = ADC_IDATA3;
|
||||
break;
|
||||
default:
|
||||
idata = 0U;
|
||||
break;
|
||||
}
|
||||
return (uint16_t)idata;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the ADC flag bits
|
||||
\param[in] flag: the adc flag bits
|
||||
\arg ADC_FLAG_WDE: analog watchdog event flag
|
||||
\arg ADC_FLAG_EOC: end of group conversion flag
|
||||
\arg ADC_FLAG_EOIC: end of inserted group conversion flag
|
||||
\arg ADC_FLAG_STIC: start flag of inserted channel group
|
||||
\arg ADC_FLAG_STRC: start flag of regular channel group
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus adc_flag_get(uint32_t flag)
|
||||
{
|
||||
FlagStatus reval = RESET;
|
||||
|
||||
if(ADC_STAT & flag){
|
||||
reval = SET;
|
||||
}
|
||||
return reval;
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear the ADC status flag
|
||||
\param[in] flag: the adc flag bits
|
||||
\arg ADC_FLAG_WDE: analog watchdog event flag
|
||||
\arg ADC_FLAG_EOC: end of group conversion flag
|
||||
\arg ADC_FLAG_EOIC: end of inserted group conversion flag
|
||||
\arg ADC_FLAG_STIC: start flag of inserted channel group
|
||||
\arg ADC_FLAG_STRC: start flag of regular channel group
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void adc_flag_clear(uint32_t flag)
|
||||
{
|
||||
ADC_STAT &= ~((uint32_t)flag);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the ADC interrupt bits
|
||||
\param[in] flag: the adc interrupt flag
|
||||
\arg ADC_INT_FLAG_WDE: analog watchdog interrupt flag
|
||||
\arg ADC_INT_FLAG_EOC: end of group conversion interrupt flag
|
||||
\arg ADC_INT_FLAG_EOIC: end of inserted group conversion interrupt flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus adc_interrupt_flag_get(uint32_t flag)
|
||||
{
|
||||
FlagStatus interrupt_flag = RESET;
|
||||
uint32_t state;
|
||||
/* check the interrupt bits */
|
||||
switch(flag){
|
||||
case ADC_INT_FLAG_WDE:
|
||||
state = ADC_STAT & ADC_STAT_WDE;
|
||||
if((ADC_CTL0 & ADC_CTL0_WDEIE) && state){
|
||||
interrupt_flag = SET;
|
||||
}
|
||||
break;
|
||||
case ADC_INT_FLAG_EOC:
|
||||
state = ADC_STAT & ADC_STAT_EOC;
|
||||
if((ADC_CTL0 & ADC_CTL0_EOCIE) && state){
|
||||
interrupt_flag = SET;
|
||||
}
|
||||
break;
|
||||
case ADC_INT_FLAG_EOIC:
|
||||
state = ADC_STAT & ADC_STAT_EOIC;
|
||||
if((ADC_CTL0 & ADC_CTL0_EOICIE) && state){
|
||||
interrupt_flag = SET;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return interrupt_flag;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear the ADC interrupt bits
|
||||
\param[in] adc_interrupt: the adc interrupt bits
|
||||
\arg ADC_INT_FLAG_WDE: analog watchdog interrupt flag
|
||||
\arg ADC_INT_FLAG_EOC: end of group conversion interrupt flag
|
||||
\arg ADC_INT_FLAG_EOIC: end of inserted group conversion interrupt flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void adc_interrupt_flag_clear(uint32_t flag)
|
||||
{
|
||||
ADC_STAT &= ~((uint32_t)flag);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable ADC interrupt
|
||||
\param[in] adc_periph: ADCx, x=0,1,2
|
||||
only one among these parameters can be selected
|
||||
\param[in] interrupt: the adc interrupt
|
||||
one or more parameters can be selected
|
||||
\arg ADC_INT_WDE: analog watchdog interrupt
|
||||
\arg ADC_INT_EOC: end of group conversion interrupt
|
||||
\arg ADC_INT_EOIC: end of inserted group conversion interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void adc_interrupt_enable(uint32_t interrupt)
|
||||
{
|
||||
if(RESET != (interrupt & ADC_INT_WDE)){
|
||||
ADC_CTL0 |= (uint32_t) ADC_CTL0_WDEIE;
|
||||
}
|
||||
|
||||
if(RESET != (interrupt & ADC_INT_EOC)){
|
||||
ADC_CTL0 |= (uint32_t) ADC_CTL0_EOCIE;
|
||||
}
|
||||
|
||||
if(RESET != (interrupt & ADC_INT_EOIC)){
|
||||
ADC_CTL0 |= (uint32_t) ADC_CTL0_EOICIE;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable ADC interrupt
|
||||
\param[in] adc_periph: ADCx,x=0,1,2
|
||||
only one among these parameters can be selected
|
||||
\param[in] interrupt: the adc interrupt flag
|
||||
one or more parameters can be selected
|
||||
\arg ADC_INT_WDE: analog watchdog interrupt flag
|
||||
\arg ADC_INT_EOC: end of group conversion interrupt flag
|
||||
\arg ADC_INT_EOIC: end of inserted group conversion interrupt flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void adc_interrupt_disable(uint32_t interrupt)
|
||||
{
|
||||
if(RESET != (interrupt & ADC_INT_WDE)){
|
||||
ADC_CTL0 &= ~(uint32_t) ADC_CTL0_WDEIE;
|
||||
}
|
||||
|
||||
if(RESET != (interrupt & ADC_INT_EOC)){
|
||||
ADC_CTL0 &= ~(uint32_t) ADC_CTL0_EOCIE;
|
||||
}
|
||||
|
||||
if(RESET != (interrupt & ADC_INT_EOIC)){
|
||||
ADC_CTL0 &= ~(uint32_t) ADC_CTL0_EOICIE;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief ADC analog watchdog single channel config
|
||||
\param[in] channel: the selected ADC channel
|
||||
\arg ADC_CHANNEL_x: ADC Channelx(x=0..18)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void adc_watchdog_single_channel_enable(uint8_t channel)
|
||||
{
|
||||
ADC_CTL0 &= (uint32_t)~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC | ADC_CTL0_WDCHSEL);
|
||||
|
||||
ADC_CTL0 |= (uint32_t)channel;
|
||||
ADC_CTL0 |= (uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief adc analog watchdog group channel config
|
||||
\param[in] adc_channel_group: the channel group use analog watchdog
|
||||
\arg ADC_REGULAR_CHANNEL: regular channel group
|
||||
\arg ADC_INSERTED_CHANNEL: inserted channel group
|
||||
\arg ADC_REGULAR_INSERTED_CHANNEL: both regular and inserted group
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void adc_watchdog_group_channel_enable(uint8_t channel_group)
|
||||
{
|
||||
ADC_CTL0 &= (uint32_t)~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC);
|
||||
/* select the group */
|
||||
switch(channel_group){
|
||||
case ADC_REGULAR_CHANNEL:
|
||||
ADC_CTL0 |= (uint32_t) ADC_CTL0_RWDEN;
|
||||
break;
|
||||
case ADC_INSERTED_CHANNEL:
|
||||
ADC_CTL0 |= (uint32_t) ADC_CTL0_IWDEN;
|
||||
break;
|
||||
case ADC_REGULAR_INSERTED_CHANNEL:
|
||||
ADC_CTL0 |= (uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief ADC analog watchdog disable
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void adc_watchdog_disable(void)
|
||||
{
|
||||
ADC_CTL0 &= (uint32_t)~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC | ADC_CTL0_WDCHSEL);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief ADC analog watchdog threshold config
|
||||
\param[in] low_threshold: analog watchdog low threshold
|
||||
\param[in] high_threshold: analog watchdog high threshold
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void adc_watchdog_threshold_config(uint16_t low_threshold,uint16_t high_threshold)
|
||||
{
|
||||
ADC_WDLT = (uint32_t)low_threshold;
|
||||
ADC_WDHT = (uint32_t)high_threshold;
|
||||
}
|
||||
|
||||
#ifdef GD32F170_190
|
||||
/*!
|
||||
\brief adc resolution config
|
||||
\param[in] resolution: ADC resolution
|
||||
\arg ADC_RESOLUTION_12B: 12-bit ADC resolution
|
||||
\arg ADC_RESOLUTION_10B: 10-bit ADC resolution
|
||||
\arg ADC_RESOLUTION_8B: 8-bit ADC resolution
|
||||
\arg ADC_RESOLUTION_6B: 6-bit ADC resolution
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void adc_resolution_config(uint32_t resolution)
|
||||
{
|
||||
ADC_CTL0 &= ~((uint32_t)ADC_CTL0_DRES);
|
||||
ADC_CTL0 |= (uint32_t)resolution;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief adc oversample mode config
|
||||
\param[in] mode: ADC oversampling mode
|
||||
\arg ADC_OVERSAMPLING_ALL_CONVERT: all oversampled conversions for a channel
|
||||
are done consecutively after a trigger
|
||||
\arg ADC_OVERSAMPLING_ONE_CONVERT: each oversampled conversion for a channel
|
||||
needs a trigger
|
||||
\param[in] shift: ADC oversampling shift
|
||||
\arg ADC_OVERSAMPLING_SHIFT_NONE: no oversampling shift
|
||||
\arg ADC_OVERSAMPLING_SHIFT_1B: 1-bit oversampling shift
|
||||
\arg ADC_OVERSAMPLING_SHIFT_2B: 2-bit oversampling shift
|
||||
\arg ADC_OVERSAMPLING_SHIFT_3B: 3-bit oversampling shift
|
||||
\arg ADC_OVERSAMPLING_SHIFT_4B: 3-bit oversampling shift
|
||||
\arg ADC_OVERSAMPLING_SHIFT_5B: 5-bit oversampling shift
|
||||
\arg ADC_OVERSAMPLING_SHIFT_6B: 6-bit oversampling shift
|
||||
\arg ADC_OVERSAMPLING_SHIFT_7B: 7-bit oversampling shift
|
||||
\arg ADC_OVERSAMPLING_SHIFT_8B: 8-bit oversampling shift
|
||||
\param[in] ratio: ADC oversampling ratio
|
||||
\arg ADC_OVERSAMPLING_RATIO_MUL2: oversampling ratio X2
|
||||
\arg ADC_OVERSAMPLING_RATIO_MUL4: oversampling ratio X4
|
||||
\arg ADC_OVERSAMPLING_RATIO_MUL8: oversampling ratio X8
|
||||
\arg ADC_OVERSAMPLING_RATIO_MUL16: oversampling ratio X16
|
||||
\arg ADC_OVERSAMPLING_RATIO_MUL32: oversampling ratio X32
|
||||
\arg ADC_OVERSAMPLING_RATIO_MUL64: oversampling ratio X64
|
||||
\arg ADC_OVERSAMPLING_RATIO_MUL128: oversampling ratio X128
|
||||
\arg ADC_OVERSAMPLING_RATIO_MUL256: oversampling ratio X256
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void adc_oversample_mode_config(uint8_t mode, uint16_t shift,uint8_t ratio)
|
||||
{
|
||||
if(mode){
|
||||
ADC_OVSAMPCTL |= (uint32_t)ADC_OVSAMPCTL_TOVS;
|
||||
}else{
|
||||
ADC_OVSAMPCTL &= ~((uint32_t)ADC_OVSAMPCTL_TOVS);
|
||||
}
|
||||
/* config the shift and ratio */
|
||||
ADC_OVSAMPCTL &= ~((uint32_t)(ADC_OVSAMPCTL_OVSR | ADC_OVSAMPCTL_OVSS));
|
||||
ADC_OVSAMPCTL |= ((uint32_t)shift | (uint32_t)ratio);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable ADC oversample mode
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void adc_oversample_mode_enable(void)
|
||||
{
|
||||
ADC_OVSAMPCTL |= ADC_OVSAMPCTL_OVSEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable ADC oversample mode
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void adc_oversample_mode_disable(void)
|
||||
{
|
||||
ADC_OVSAMPCTL &= ~((uint32_t)ADC_OVSAMPCTL_OVSEN);
|
||||
}
|
||||
#endif /* GD32F170_190 */
|
893
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_can.c
Normal file
893
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_can.c
Normal file
@@ -0,0 +1,893 @@
|
||||
/*!
|
||||
\file gd32f1x0_can.c
|
||||
\brief CAN driver
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2017 GigaDevice
|
||||
|
||||
2014-12-26, V1.0.0, platform GD32F1x0(x=3,5)
|
||||
2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9)
|
||||
2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
*/
|
||||
|
||||
#ifdef GD32F170_190
|
||||
|
||||
#include "gd32f1x0_can.h"
|
||||
#include "gd32f1x0.h"
|
||||
|
||||
/*!
|
||||
\brief deinitialize CAN
|
||||
\param[in] can_periph
|
||||
\arg CANx(x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void can_deinit(uint32_t can_periph)
|
||||
{
|
||||
if(CAN0 == can_periph){
|
||||
rcu_periph_reset_enable(RCU_CAN0RST);
|
||||
rcu_periph_reset_disable(RCU_CAN0RST);
|
||||
}else{
|
||||
rcu_periph_reset_enable(RCU_CAN1RST);
|
||||
rcu_periph_reset_disable(RCU_CAN1RST);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize CAN
|
||||
\param[in] can_periph
|
||||
\arg CANx(x=0,1)
|
||||
\param[in] can_parameter_init: parameters for CAN initializtion
|
||||
\arg working_mode: CAN_NORMAL_MODE, CAN_LOOPBACK_MODE, CAN_SILENT_MODE, CAN_SILENT_LOOPBACK_MODE
|
||||
\arg resync_jump_width: CAN_BT_SJW_xTQ(x=1, 2, 3, 4)
|
||||
\arg time_segment_1: CAN_BT_BS1_xTQ(1..16)
|
||||
\arg time_segment_2: CAN_BT_BS2_xTQ(1..8)
|
||||
\arg time_triggered: ENABLE or DISABLE
|
||||
\arg auto_bus_off_recovery: ENABLE or DISABLE
|
||||
\arg auto_wake_up: ENABLE or DISABLE
|
||||
\arg auto_retrans: ENABLE or DISABLE
|
||||
\arg rec_fifo_overwrite: ENABLE or DISABLE
|
||||
\arg trans_fifo_order: ENABLE or DISABLE
|
||||
\arg prescaler: 0x0001 - 0x03FF
|
||||
\param[out] none
|
||||
\retval ErrStatus: SUCCESS or ERROR
|
||||
*/
|
||||
ErrStatus can_init(uint32_t can_periph, can_parameter_struct* can_parameter_init)
|
||||
{
|
||||
uint32_t timeout = CAN_TIMEOUT;
|
||||
ErrStatus flag = ERROR;
|
||||
|
||||
/* disable sleep mode */
|
||||
CAN_CTL(can_periph) &= ~CAN_CTL_SLPWMOD;
|
||||
/* enable initialize mode */
|
||||
CAN_CTL(can_periph) |= CAN_CTL_IWMOD;
|
||||
/* wait ACK */
|
||||
while((CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (timeout)){
|
||||
timeout--;
|
||||
}
|
||||
/* check initialize working success */
|
||||
if(CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)){
|
||||
flag = ERROR;
|
||||
}else{
|
||||
/* set the bit timing register */
|
||||
CAN_BT(can_periph) = (BT_MODE((uint32_t)can_parameter_init->working_mode) | \
|
||||
BT_SJW((uint32_t)can_parameter_init->resync_jump_width) | \
|
||||
BT_BS1((uint32_t)can_parameter_init->time_segment_1) | \
|
||||
BT_BS2((uint32_t)can_parameter_init->time_segment_2) | \
|
||||
BT_BAUDPSC(((uint32_t)(can_parameter_init->prescaler) - 1U)));
|
||||
/* time trigger communication mode */
|
||||
if(ENABLE == can_parameter_init->time_triggered){
|
||||
CAN_CTL(can_periph) |= CAN_CTL_TTC;
|
||||
}else{
|
||||
CAN_CTL(can_periph) &= ~CAN_CTL_TTC;
|
||||
}
|
||||
/* automatic bus-off managment */
|
||||
if(ENABLE == can_parameter_init->auto_bus_off_recovery){
|
||||
CAN_CTL(can_periph) |= CAN_CTL_ABOR;
|
||||
}else{
|
||||
CAN_CTL(can_periph) &= ~CAN_CTL_ABOR;
|
||||
}
|
||||
/* automatic wakeup mode */
|
||||
if(ENABLE == can_parameter_init->auto_wake_up){
|
||||
CAN_CTL(can_periph) |= CAN_CTL_AWU;
|
||||
}else{
|
||||
CAN_CTL(can_periph) &= ~CAN_CTL_AWU;
|
||||
}
|
||||
/* automatic retransmission mode */
|
||||
if(ENABLE == can_parameter_init->auto_retrans){
|
||||
CAN_CTL(can_periph) |= CAN_CTL_ARD;
|
||||
}else{
|
||||
CAN_CTL(can_periph) &= ~CAN_CTL_ARD;
|
||||
}
|
||||
/* receive fifo overwrite mode */
|
||||
if(ENABLE == can_parameter_init->rec_fifo_overwrite){
|
||||
CAN_CTL(can_periph) |= CAN_CTL_RFOD;
|
||||
}else{
|
||||
CAN_CTL(can_periph) &= ~CAN_CTL_RFOD;
|
||||
}
|
||||
/* transmit fifo order */
|
||||
if(ENABLE == can_parameter_init->trans_fifo_order){
|
||||
CAN_CTL(can_periph) |= CAN_CTL_TFO;
|
||||
}else{
|
||||
CAN_CTL(can_periph) &= ~CAN_CTL_TFO;
|
||||
}
|
||||
/* disable initialize mode */
|
||||
CAN_CTL(can_periph) &= ~CAN_CTL_IWMOD;
|
||||
timeout = CAN_TIMEOUT;
|
||||
/* wait the ACK */
|
||||
while((CAN_STAT_IWS == (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (timeout)){
|
||||
timeout--;
|
||||
}
|
||||
/* check exit initialize mode */
|
||||
if(CAN_STAT_IWS == (CAN_STAT(can_periph) & CAN_STAT_IWS)){
|
||||
flag = SUCCESS;
|
||||
}
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize CAN filter
|
||||
\param[in] can_filter_parameter_init: struct for CAN filter initialization
|
||||
\arg filter_list_high: 0x0000 - 0xFFFF
|
||||
\arg filter_list_low: 0x0000 - 0xFFFF
|
||||
\arg filter_mask_high: 0x0000 - 0xFFFF
|
||||
\arg filter_mask_low: 0x0000 - 0xFFFF
|
||||
\arg filter_fifo_number: CAN_FIFO0, CAN_FIFO1
|
||||
\arg filter_number: 0 - 27
|
||||
\arg filter_mode: CAN_FILTERMODE_MASK, CAN_FILTERMODE_LIST
|
||||
\arg filter_bits: CAN_FILTERBITS_32BIT, CAN_FILTERBITS_16BIT
|
||||
\arg filter_enable: ENABLE or DISABLE
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void can_filter_init(can_filter_parameter_struct* can_filter_parameter_init)
|
||||
{
|
||||
uint32_t val = 0U;
|
||||
|
||||
val = ((uint32_t)1) << (can_filter_parameter_init->filter_number);
|
||||
/* filter lock disable */
|
||||
CAN_FCTL(CAN0) |= CAN_FCTL_FLD;
|
||||
/* disable filter */
|
||||
CAN_FW(CAN0) &= ~(uint32_t)val;
|
||||
/* filter 16 bits */
|
||||
if(CAN_FILTERBITS_16BIT == can_filter_parameter_init->filter_bits){
|
||||
/* set filter 16 bits */
|
||||
CAN_FSCFG(CAN0) &= ~(uint32_t)val;
|
||||
/* first 16 bits list and first 16 bits mask or first 16 bits list and second 16 bits list */
|
||||
CAN_FDATA0(CAN0, can_filter_parameter_init->filter_number) = \
|
||||
FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_low) & CAN_FILTER_MASK_16BITS) | \
|
||||
FDATA_MASK_LOW((can_filter_parameter_init->filter_list_low) & CAN_FILTER_MASK_16BITS);
|
||||
/* second 16 bits list and second 16 bits mask or third 16 bits list and fourth 16 bits list */
|
||||
CAN_FDATA1(CAN0, can_filter_parameter_init->filter_number) = \
|
||||
FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_high) & CAN_FILTER_MASK_16BITS) | \
|
||||
FDATA_MASK_LOW((can_filter_parameter_init->filter_list_high) & CAN_FILTER_MASK_16BITS);
|
||||
}
|
||||
/* filter 32 bits */
|
||||
if(CAN_FILTERBITS_32BIT == can_filter_parameter_init->filter_bits){
|
||||
/* set filter 32 bits */
|
||||
CAN_FSCFG(CAN0) |= (uint32_t)val;
|
||||
/* 32 bits list or first 32 bits list */
|
||||
CAN_FDATA0(CAN0, can_filter_parameter_init->filter_number) = \
|
||||
FDATA_MASK_HIGH((can_filter_parameter_init->filter_list_high) & CAN_FILTER_MASK_16BITS) |
|
||||
FDATA_MASK_LOW((can_filter_parameter_init->filter_list_low) & CAN_FILTER_MASK_16BITS);
|
||||
/* 32 bits mask or second 32 bits list */
|
||||
CAN_FDATA1(CAN0, can_filter_parameter_init->filter_number) = \
|
||||
FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_high) & CAN_FILTER_MASK_16BITS) |
|
||||
FDATA_MASK_LOW((can_filter_parameter_init->filter_mask_low) & CAN_FILTER_MASK_16BITS);
|
||||
}
|
||||
/* filter mode */
|
||||
if(CAN_FILTERMODE_MASK == can_filter_parameter_init->filter_mode){
|
||||
/* mask mode */
|
||||
CAN_FMCFG(CAN0) &= ~(uint32_t)val;
|
||||
}else{
|
||||
/* list mode */
|
||||
CAN_FMCFG(CAN0) |= (uint32_t)val;
|
||||
}
|
||||
/* filter FIFO */
|
||||
if(CAN_FIFO0 == (can_filter_parameter_init->filter_fifo_number)){
|
||||
/* FIFO0 */
|
||||
CAN_FAFIFO(CAN0) &= ~(uint32_t)val;
|
||||
}else{
|
||||
/* FIFO1 */
|
||||
CAN_FAFIFO(CAN0) |= (uint32_t)val;
|
||||
}
|
||||
/* filter working */
|
||||
if(ENABLE == can_filter_parameter_init->filter_enable){
|
||||
|
||||
CAN_FW(CAN0) |= (uint32_t)val;
|
||||
}
|
||||
/* filter lock enable */
|
||||
CAN_FCTL(CAN0) &= ~CAN_FCTL_FLD;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set CAN1 fliter start bank number
|
||||
\param[in] start_bank: CAN1 start bank number
|
||||
\arg (1..27)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void can1_filter_start_bank(uint8_t start_bank)
|
||||
{
|
||||
/* filter lock disable */
|
||||
CAN_FCTL(CAN0) |= CAN_FCTL_FLD;
|
||||
/* set CAN1 filter start number */
|
||||
CAN_FCTL(CAN0) &= ~(uint32_t)CAN_FCTL_HBC1F;
|
||||
CAN_FCTL(CAN0) |= FCTL_HBC1F(start_bank);
|
||||
/* filter lock enaable */
|
||||
CAN_FCTL(CAN0) &= ~CAN_FCTL_FLD;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable CAN debug freeze
|
||||
\param[in] can_periph
|
||||
\arg CANx(x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void can_debug_freeze_enable(uint32_t can_periph)
|
||||
{
|
||||
CAN_CTL(can_periph) |= CAN_CTL_DFZ;
|
||||
|
||||
if(CAN0 == can_periph){
|
||||
dbg_periph_enable(DBG_CAN0_HOLD);
|
||||
}else{
|
||||
dbg_periph_enable(DBG_CAN1_HOLD);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable CAN debug freeze
|
||||
\param[in] can_periph
|
||||
\arg CANx(x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void can_debug_freeze_disable(uint32_t can_periph)
|
||||
{
|
||||
CAN_CTL(can_periph) |= CAN_CTL_DFZ;
|
||||
|
||||
if(CAN0 == can_periph){
|
||||
dbg_periph_disable(DBG_CAN0_HOLD);
|
||||
}else{
|
||||
dbg_periph_disable(DBG_CAN1_HOLD);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable CAN time trigger mode
|
||||
\param[in] can_periph
|
||||
\arg CANx(x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void can_time_trigger_mode_enable(uint32_t can_periph)
|
||||
{
|
||||
uint8_t mailbox_number;
|
||||
|
||||
/* enable the tcc mode */
|
||||
CAN_CTL(can_periph) |= CAN_CTL_TTC;
|
||||
/* enable time stamp */
|
||||
for(mailbox_number=0U; mailbox_number<3U; mailbox_number++){
|
||||
CAN_TMP(can_periph, mailbox_number) |= CAN_TMP_TSEN;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable CAN time trigger mode
|
||||
\param[in] can_periph
|
||||
\arg CANx(x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void can_time_trigger_mode_disable(uint32_t can_periph)
|
||||
{
|
||||
uint8_t mailbox_number;
|
||||
|
||||
/* disable the TCC mode */
|
||||
CAN_CTL(can_periph) &= ~CAN_CTL_TTC;
|
||||
/* reset TSEN bits */
|
||||
for(mailbox_number=0U; mailbox_number<3U; mailbox_number++){
|
||||
CAN_TMP(can_periph, mailbox_number) &= ~CAN_TMP_TSEN;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief transmit CAN message
|
||||
\param[in] can_periph
|
||||
\arg CANx(x=0,1)
|
||||
\param[in] transmit_message: struct for CAN transmit message
|
||||
\arg tx_sfid: 0x00000000 - 0x000007FF
|
||||
\arg tx_efid: 0x00000000 - 0x1FFFFFFF
|
||||
\arg tx_ff: CAN_FF_STANDARD, CAN_FF_EXTENDED
|
||||
\arg tx_ft: CAN_FT_DATA, CAN_FT_REMOTE
|
||||
\arg tx_dlenc: 1 - 7
|
||||
\arg tx_data[]: 0x00 - 0xFF
|
||||
\param[out] none
|
||||
\retval mailbox_number
|
||||
*/
|
||||
uint8_t can_message_transmit(uint32_t can_periph, can_trasnmit_message_struct* transmit_message)
|
||||
{
|
||||
uint8_t mailbox_number = CAN_MAILBOX0;
|
||||
|
||||
/* select one empty mailbox */
|
||||
if(CAN_TSTAT_TME0 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME0)){
|
||||
mailbox_number = CAN_MAILBOX0;
|
||||
}else if(CAN_TSTAT_TME1 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME1)){
|
||||
mailbox_number = CAN_MAILBOX1;
|
||||
}else if(CAN_TSTAT_TME2 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME2)){
|
||||
mailbox_number = CAN_MAILBOX2;
|
||||
}else{
|
||||
mailbox_number = CAN_NOMAILBOX;
|
||||
}
|
||||
if(CAN_NOMAILBOX == mailbox_number){
|
||||
return CAN_NOMAILBOX;
|
||||
}
|
||||
|
||||
CAN_TMI(can_periph, mailbox_number) &= CAN_TMI_TEN;
|
||||
if(CAN_FF_STANDARD == transmit_message->tx_ff){
|
||||
/* set transmit mailbox standard identifier */
|
||||
CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_SFID(transmit_message->tx_sfid) | \
|
||||
transmit_message->tx_ft);
|
||||
}else{
|
||||
/* set transmit mailbox extended identifier */
|
||||
CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_EFID(transmit_message->tx_efid) | \
|
||||
transmit_message->tx_ff | \
|
||||
transmit_message->tx_ft);
|
||||
}
|
||||
/* set the data length */
|
||||
CAN_TMP(can_periph, mailbox_number) &= ((uint32_t)~CAN_TMP_DLENC);
|
||||
CAN_TMP(can_periph, mailbox_number) |= transmit_message->tx_dlen;
|
||||
/* set the data */
|
||||
CAN_TMDATA0(can_periph, mailbox_number) = TMDATA0_DB3(transmit_message->tx_data[3]) | \
|
||||
TMDATA0_DB2(transmit_message->tx_data[2]) | \
|
||||
TMDATA0_DB1(transmit_message->tx_data[1]) | \
|
||||
TMDATA0_DB0(transmit_message->tx_data[0]);
|
||||
CAN_TMDATA1(can_periph, mailbox_number) = TMDATA1_DB7(transmit_message->tx_data[7]) | \
|
||||
TMDATA1_DB6(transmit_message->tx_data[6]) | \
|
||||
TMDATA1_DB5(transmit_message->tx_data[5]) | \
|
||||
TMDATA1_DB4(transmit_message->tx_data[4]);
|
||||
/* enable transmission */
|
||||
CAN_TMI(can_periph, mailbox_number) |= CAN_TMI_TEN;
|
||||
|
||||
return mailbox_number;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get CAN transmit state
|
||||
\param[in] can_periph
|
||||
\arg CANx(x=0,1)
|
||||
\param[in] mailbox_number
|
||||
\arg CAN_MAILBOX(x=0,1,2)
|
||||
\param[out] none
|
||||
\retval can_transmit_state_enum
|
||||
*/
|
||||
can_transmit_state_enum can_transmit_states(uint32_t can_periph, uint8_t mailbox_number)
|
||||
{
|
||||
can_transmit_state_enum state = CAN_TRANSMIT_FAILED;
|
||||
uint32_t val = 0U;
|
||||
|
||||
switch(mailbox_number){
|
||||
case CAN_MAILBOX0:
|
||||
val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF0 | CAN_TSTAT_MTFNERR0 | CAN_TSTAT_TME0);
|
||||
break;
|
||||
case CAN_MAILBOX1:
|
||||
val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF1 | CAN_TSTAT_MTFNERR1 | CAN_TSTAT_TME1);
|
||||
break;
|
||||
case CAN_MAILBOX2:
|
||||
val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF2 | CAN_TSTAT_MTFNERR2 | CAN_TSTAT_TME2);
|
||||
break;
|
||||
default:
|
||||
val = CAN_TRANSMIT_FAILED;
|
||||
break;
|
||||
}
|
||||
switch(val){
|
||||
/* transmit pending */
|
||||
case (CAN_STATE_PENDING):
|
||||
state = CAN_TRANSMIT_PENDING;
|
||||
break;
|
||||
/* transmit succeeded */
|
||||
case (CAN_TSTAT_MTF0 | CAN_TSTAT_MTFNERR0 | CAN_TSTAT_TME0):
|
||||
state = CAN_TRANSMIT_OK;
|
||||
break;
|
||||
case (CAN_TSTAT_MTF1 | CAN_TSTAT_MTFNERR1 | CAN_TSTAT_TME1):
|
||||
state = CAN_TRANSMIT_OK;
|
||||
break;
|
||||
case (CAN_TSTAT_MTF2 | CAN_TSTAT_MTFNERR2 | CAN_TSTAT_TME2):
|
||||
state = CAN_TRANSMIT_OK;
|
||||
break;
|
||||
default:
|
||||
state = CAN_TRANSMIT_FAILED;
|
||||
break;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief stop CAN transmission
|
||||
\param[in] can_periph
|
||||
\arg CANx(x=0,1)
|
||||
\param[in] mailbox_number
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CAN_MAILBOXx(x=0,1,2)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void can_transmission_stop(uint32_t can_periph, uint8_t mailbox_number)
|
||||
{
|
||||
if(CAN_MAILBOX0 == mailbox_number){
|
||||
CAN_TSTAT(can_periph) |= CAN_TSTAT_MST0;
|
||||
}else if(CAN_MAILBOX1 == mailbox_number){
|
||||
CAN_TSTAT(can_periph) |= CAN_TSTAT_MST1;
|
||||
}else if(CAN_MAILBOX2 == mailbox_number){
|
||||
CAN_TSTAT(can_periph) |= CAN_TSTAT_MST2;
|
||||
}else{
|
||||
/* illegal parameters */
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief CAN receive message
|
||||
\param[in] can_periph
|
||||
\arg CANx(x=0,1)
|
||||
\param[in] fifo_number
|
||||
\arg CAN_FIFOx(x=0,1)
|
||||
\param[out] receive_message: struct for CAN receive message
|
||||
\arg rx_sfid: 0x00000000 - 0x000007FF
|
||||
\arg rx_efid: 0x00000000 - 0x1FFFFFFF
|
||||
\arg rx_ff: CAN_FF_STANDARD, CAN_FF_EXTENDED
|
||||
\arg rx_ft: CAN_FT_DATA, CAN_FT_REMOTE
|
||||
\arg rx_dlenc: 1 - 7
|
||||
\arg rx_data[]: 0x00 - 0xFF
|
||||
\arg rx_fi: 0 - 27
|
||||
\retval none
|
||||
*/
|
||||
void can_message_receive(uint32_t can_periph, uint8_t fifo_number, can_receive_message_struct* receive_message)
|
||||
{
|
||||
/* get the frame format */
|
||||
receive_message->rx_ff = (uint8_t)(CAN_RFIFOMI_FF & CAN_RFIFOMI(can_periph, fifo_number));
|
||||
if(CAN_FF_STANDARD == receive_message->rx_ff){
|
||||
/* get standard identifier */
|
||||
receive_message -> rx_sfid = (uint32_t)(RFIFOMI_SFID(CAN_RFIFOMI(can_periph, fifo_number)));
|
||||
}else{
|
||||
/* get extended identifier */
|
||||
receive_message -> rx_efid = (uint32_t)(RFIFOMI_EFID(CAN_RFIFOMI(can_periph, fifo_number)));
|
||||
}
|
||||
|
||||
/* get frame type */
|
||||
receive_message -> rx_ft = (uint8_t)(CAN_RFIFOMI_FT & CAN_RFIFOMI(can_periph, fifo_number));
|
||||
/* get recevie data length */
|
||||
receive_message -> rx_dlen = (uint8_t)(RFIFOMP_DLENC(CAN_RFIFOMP(can_periph, fifo_number)));
|
||||
/* filtering index */
|
||||
receive_message -> rx_fi = (uint8_t)(RFIFOMP_FI(CAN_RFIFOMP(can_periph, fifo_number)));
|
||||
|
||||
/* receive data */
|
||||
receive_message -> rx_data[0] = (uint8_t)(RFIFOMDATA0_DB0(CAN_RFIFOMDATA0(can_periph, fifo_number)));
|
||||
receive_message -> rx_data[1] = (uint8_t)(RFIFOMDATA0_DB1(CAN_RFIFOMDATA0(can_periph, fifo_number)));
|
||||
receive_message -> rx_data[2] = (uint8_t)(RFIFOMDATA0_DB2(CAN_RFIFOMDATA0(can_periph, fifo_number)));
|
||||
receive_message -> rx_data[3] = (uint8_t)(RFIFOMDATA0_DB3(CAN_RFIFOMDATA0(can_periph, fifo_number)));
|
||||
receive_message -> rx_data[4] = (uint8_t)(RFIFOMDATA1_DB4(CAN_RFIFOMDATA1(can_periph, fifo_number)));
|
||||
receive_message -> rx_data[5] = (uint8_t)(RFIFOMDATA1_DB5(CAN_RFIFOMDATA1(can_periph, fifo_number)));
|
||||
receive_message -> rx_data[6] = (uint8_t)(RFIFOMDATA1_DB6(CAN_RFIFOMDATA1(can_periph, fifo_number)));
|
||||
receive_message -> rx_data[7] = (uint8_t)(RFIFOMDATA1_DB7(CAN_RFIFOMDATA1(can_periph, fifo_number)));
|
||||
|
||||
/* release FIFO */
|
||||
if(CAN_FIFO0 == fifo_number){
|
||||
CAN_RFIFO0(can_periph) |= CAN_RFIFO0_RFD0;
|
||||
}else{
|
||||
CAN_RFIFO1(can_periph) |= CAN_RFIFO1_RFD1;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief release FIFO0
|
||||
\param[in] can_periph
|
||||
\arg CANx(x=0,1)
|
||||
\param[in] fifo_number
|
||||
\arg CAN_FIFOx(x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void can_fifo_release(uint32_t can_periph, uint8_t fifo_number)
|
||||
{
|
||||
if(CAN_FIFO0 == fifo_number){
|
||||
CAN_RFIFO0(can_periph) |= CAN_RFIFO0_RFD0;
|
||||
}else if(CAN_FIFO1 == fifo_number){
|
||||
CAN_RFIFO1(can_periph) |= CAN_RFIFO1_RFD1;
|
||||
}else{
|
||||
/* illegal parameters */
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief CAN receive message length
|
||||
\param[in] can_periph
|
||||
\arg CANx(x=0,1)
|
||||
\param[in] fifo_number
|
||||
\arg CAN_FIFOx(x=0,1)
|
||||
\param[out] none
|
||||
\retval message length
|
||||
*/
|
||||
uint8_t can_receive_message_length_get(uint32_t can_periph, uint8_t fifo_number)
|
||||
{
|
||||
uint8_t val = 0U;
|
||||
|
||||
if(CAN_FIFO0 == fifo_number){
|
||||
val = (uint8_t)(CAN_RFIFO0(can_periph) & CAN_RFIF_RFL_MASK);
|
||||
}else if(CAN_FIFO1 == fifo_number){
|
||||
val = (uint8_t)(CAN_RFIFO1(can_periph) & CAN_RFIF_RFL_MASK);
|
||||
}else{
|
||||
/* illegal parameters */
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set CAN working mode
|
||||
\param[in] can_periph
|
||||
\arg CANx(x=0,1)
|
||||
\param[in] can_working_mode
|
||||
\arg CAN_MODE_INITIALIZE
|
||||
\arg CAN_MODE_NORMAL
|
||||
\arg CAN_MODE_SLEEP
|
||||
\param[out] none
|
||||
\retval ErrStatus: SUCCESS or ERROR
|
||||
*/
|
||||
ErrStatus can_working_mode_set(uint32_t can_periph, uint8_t working_mode)
|
||||
{
|
||||
ErrStatus flag = ERROR;
|
||||
/* timeout for IWS or also for SLPWS bits */
|
||||
uint32_t timeout = CAN_TIMEOUT;
|
||||
|
||||
if(CAN_MODE_INITIALIZE == working_mode){
|
||||
/* disable sleep mode */
|
||||
CAN_CTL(can_periph) &= (~(uint32_t)CAN_CTL_SLPWMOD);
|
||||
/* set initialize mode */
|
||||
CAN_CTL(can_periph) |= (uint8_t)CAN_CTL_IWMOD;
|
||||
/* wait the acknowledge */
|
||||
while((CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)){
|
||||
timeout--;
|
||||
}
|
||||
if(CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)){
|
||||
flag = ERROR;
|
||||
}else{
|
||||
flag = SUCCESS;
|
||||
}
|
||||
}else if(CAN_MODE_NORMAL == working_mode){
|
||||
/* enter normal mode */
|
||||
CAN_CTL(can_periph) &= ~(uint32_t)(CAN_CTL_SLPWMOD | CAN_CTL_IWMOD);
|
||||
/* wait the acknowledge */
|
||||
while((0U != (CAN_STAT(can_periph) & (CAN_STAT_IWS | CAN_STAT_SLPWS))) && (0U != timeout)){
|
||||
timeout--;
|
||||
}
|
||||
if(0U != (CAN_STAT(can_periph) & (CAN_STAT_IWS | CAN_STAT_SLPWS))){
|
||||
flag = ERROR;
|
||||
}else{
|
||||
flag = SUCCESS;
|
||||
}
|
||||
}else if(CAN_MODE_SLEEP == working_mode){
|
||||
/* disable initialize mode */
|
||||
CAN_CTL(can_periph) &= (~(uint32_t)CAN_CTL_IWMOD);
|
||||
/* set sleep mode */
|
||||
CAN_CTL(can_periph) |= (uint8_t)CAN_CTL_SLPWMOD;
|
||||
/* wait the acknowledge */
|
||||
while((CAN_STAT_SLPWS != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)) && (0U != timeout)){
|
||||
timeout--;
|
||||
}
|
||||
if(CAN_STAT_SLPWS != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)){
|
||||
flag = ERROR;
|
||||
}else{
|
||||
flag = SUCCESS;
|
||||
}
|
||||
}else{
|
||||
flag = ERROR;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief wake up CAN
|
||||
\param[in] can_periph
|
||||
\arg CANx(x=0,1)
|
||||
\param[out] none
|
||||
\retval ErrStatus: SUCCESS or ERROR
|
||||
*/
|
||||
ErrStatus can_wakeup(uint32_t can_periph)
|
||||
{
|
||||
ErrStatus flag = ERROR;
|
||||
uint32_t timeout = CAN_TIMEOUT;
|
||||
|
||||
/* wakeup */
|
||||
CAN_CTL(can_periph) &= ~CAN_CTL_SLPWMOD;
|
||||
|
||||
while((0U != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)) && (0x00U != timeout)){
|
||||
timeout--;
|
||||
}
|
||||
if(0U != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)){
|
||||
flag = ERROR;
|
||||
}else{
|
||||
flag = SUCCESS;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get CAN error type
|
||||
\param[in] can_periph
|
||||
\arg CANx(x=0,1)
|
||||
\param[out] none
|
||||
\retval can_error_enum
|
||||
*/
|
||||
can_error_enum can_error_get(uint32_t can_periph)
|
||||
{
|
||||
can_error_enum error;
|
||||
error = CAN_ERROR_NONE;
|
||||
|
||||
/* get error type */
|
||||
error = (can_error_enum)((CAN_ERR(can_periph) & CAN_ERR_ERRN) >> 4U);
|
||||
return error;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get CAN receive error number
|
||||
\param[in] can_periph
|
||||
\arg CANx(x=0,1)
|
||||
\param[out] none
|
||||
\retval error number
|
||||
*/
|
||||
uint8_t can_receive_error_number_get(uint32_t can_periph)
|
||||
{
|
||||
uint8_t val;
|
||||
|
||||
val = (uint8_t)((CAN_ERR(can_periph) & CAN_ERR_RECNT) >> 24U);
|
||||
return val;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get CAN transmit error number
|
||||
\param[in] can_periph
|
||||
\arg CANx(x=0,1)
|
||||
\param[out] none
|
||||
\retval error number
|
||||
*/
|
||||
uint8_t can_transmit_error_number_get(uint32_t can_periph)
|
||||
{
|
||||
uint8_t val;
|
||||
|
||||
val = (uint8_t)((CAN_ERR(can_periph) & CAN_ERR_TECNT) >> 16U);
|
||||
return val;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable CAN interrupt
|
||||
\param[in] can_periph
|
||||
\arg CANx(x=0,1)
|
||||
\param[in] interrupt
|
||||
\arg CAN_INT_TME: transmit mailbox empty interrupt enable
|
||||
\arg CAN_INT_RFNE0: receive FIFO0 not empty interrupt enable
|
||||
\arg CAN_INT_RFF0: receive FIFO0 full interrupt enable
|
||||
\arg CAN_INT_RFO0: receive FIFO0 overfull interrupt enable
|
||||
\arg CAN_INT_RFNE1: receive FIFO1 not empty interrupt enable
|
||||
\arg CAN_INT_RFF1: receive FIFO1 full interrupt enable
|
||||
\arg CAN_INT_RFO1: receive FIFO1 overfull interrupt enable
|
||||
\arg CAN_INT_WERR: warning error interrupt enable
|
||||
\arg CAN_INT_PERR: passive error interrupt enable
|
||||
\arg CAN_INT_BO: bus-off interrupt enable
|
||||
\arg CAN_INT_ERRN: error number interrupt enable
|
||||
\arg CAN_INT_ERR: error interrupt enable
|
||||
\arg CAN_INT_WU: wakeup interrupt enable
|
||||
\arg CAN_INT_SLPW: sleep working interrupt enable
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void can_interrupt_enable(uint32_t can_periph, uint32_t interrupt)
|
||||
{
|
||||
CAN_INTEN(can_periph) |= interrupt;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable CAN interrupt
|
||||
\param[in] can_periph
|
||||
\arg CANx(x=0,1)
|
||||
\param[in] interrupt
|
||||
\arg CAN_INT_TME: transmit mailbox empty interrupt enable
|
||||
\arg CAN_INT_RFNE0: receive FIFO0 not empty interrupt enable
|
||||
\arg CAN_INT_RFF0: receive FIFO0 full interrupt enable
|
||||
\arg CAN_INT_RFO0: receive FIFO0 overfull interrupt enable
|
||||
\arg CAN_INT_RFNE1: receive FIFO1 not empty interrupt enable
|
||||
\arg CAN_INT_RFF1: receive FIFO1 full interrupt enable
|
||||
\arg CAN_INT_RFO1: receive FIFO1 overfull interrupt enable
|
||||
\arg CAN_INT_WERR: warning error interrupt enable
|
||||
\arg CAN_INT_PERR: passive error interrupt enable
|
||||
\arg CAN_INT_BO: bus-off interrupt enable
|
||||
\arg CAN_INT_ERRN: error number interrupt enable
|
||||
\arg CAN_INT_ERR: error interrupt enable
|
||||
\arg CAN_INT_WU: wakeup interrupt enable
|
||||
\arg CAN_INT_SLPW: sleep working interrupt enable
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void can_interrupt_disable(uint32_t can_periph, uint32_t interrupt)
|
||||
{
|
||||
CAN_INTEN(can_periph) &= ~interrupt;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get CAN flag state
|
||||
\param[in] can_periph
|
||||
\arg CANx(x=0,1)
|
||||
\param[in] flag: CAN flags, refer to can_flag_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CAN_FLAG_MTE2: mailbox 2 transmit error
|
||||
\arg CAN_FLAG_MTE1: mailbox 1 transmit error
|
||||
\arg CAN_FLAG_MTE0: mailbox 0 transmit error
|
||||
\arg CAN_FLAG_MTF2: mailbox 2 transmit finished
|
||||
\arg CAN_FLAG_MTF1: mailbox 1 transmit finished
|
||||
\arg CAN_FLAG_MTF0: mailbox 0 transmit finished
|
||||
\arg CAN_FLAG_RFO0: receive FIFO0 overfull
|
||||
\arg CAN_FLAG_RFF0: receive FIFO0 full
|
||||
\arg CAN_FLAG_RFO1: receive FIFO1 overfull
|
||||
\arg CAN_FLAG_RFF1: receive FIFO1 full
|
||||
\arg CAN_FLAG_BOERR: bus-off error
|
||||
\arg CAN_FLAG_PERR: passive error
|
||||
\arg CAN_FLAG_WERR: warning error
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus can_flag_get(uint32_t can_periph, can_flag_enum flag)
|
||||
{
|
||||
if(RESET != (CAN_REG_VAL(can_periph, flag) & BIT(CAN_BIT_POS(flag)))){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear CAN flag state
|
||||
\param[in] can_periph
|
||||
\arg CANx(x=0,1)
|
||||
\param[in] flag: CAN flags, refer to can_flag_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CAN_FLAG_MTE2: mailbox 2 transmit error
|
||||
\arg CAN_FLAG_MTE1: mailbox 1 transmit error
|
||||
\arg CAN_FLAG_MTE0: mailbox 0 transmit error
|
||||
\arg CAN_FLAG_MTF2: mailbox 2 transmit finished
|
||||
\arg CAN_FLAG_MTF1: mailbox 1 transmit finished
|
||||
\arg CAN_FLAG_MTF0: mailbox 0 transmit finished
|
||||
\arg CAN_FLAG_RFO0: receive FIFO0 overfull
|
||||
\arg CAN_FLAG_RFF0: receive FIFO0 full
|
||||
\arg CAN_FLAG_RFO1: receive FIFO1 overfull
|
||||
\arg CAN_FLAG_RFF1: receive FIFO1 full
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void can_flag_clear(uint32_t can_periph, can_flag_enum flag)
|
||||
{
|
||||
CAN_REG_VAL(can_periph, flag) |= BIT(CAN_BIT_POS(flag));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get CAN interrupt flag state
|
||||
\param[in] can_periph
|
||||
\arg CANx(x=0,1)
|
||||
\param[in] flag: CAN interrupt flags, refer to can_interrupt_flag_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CAN_INT_FLAG_SLPIF: status change interrupt flag of sleep working mode entering
|
||||
\arg CAN_INT_FLAG_WUIF: status change interrupt flag of wakeup from sleep working mode
|
||||
\arg CAN_INT_FLAG_ERRIF: error interrupt flag
|
||||
\arg CAN_INT_FLAG_MTF2: mailbox 2 transmit finished interrupt flag
|
||||
\arg CAN_INT_FLAG_MTF1: mailbox 1 transmit finished interrupt flag
|
||||
\arg CAN_INT_FLAG_MTF0: mailbox 0 transmit finished interrupt flag
|
||||
\arg CAN_INT_FLAG_RFO0: receive FIFO0 overfull interrupt flag
|
||||
\arg CAN_INT_FLAG_RFF0: receive FIFO0 full interrupt flag
|
||||
\arg CAN_INT_FLAG_RFO1: receive FIFO1 overfull interrupt flag
|
||||
\arg CAN_INT_FLAG_RFF1: receive FIFO1 full interrupt flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus can_interrupt_flag_get(uint32_t can_periph, can_interrupt_flag_enum flag)
|
||||
{
|
||||
FlagStatus ret1 = RESET;
|
||||
FlagStatus ret2 = RESET;
|
||||
|
||||
/* get the staus of interrupt flag */
|
||||
ret1 = (FlagStatus)(CAN_REG_VALS(can_periph, flag) & BIT(CAN_BIT_POS0(flag)));
|
||||
/* get the staus of interrupt enale bit */
|
||||
ret2 = (FlagStatus)(CAN_INTEN(can_periph) & BIT(CAN_BIT_POS1(flag)));
|
||||
if(ret1 && ret2){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear CAN interrupt flag state
|
||||
\param[in] can_periph
|
||||
\arg CANx(x=0,1)
|
||||
\param[in] flag: CAN interrupt flags, refer to can_interrupt_flag_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg CAN_INT_FLAG_SLPIF: status change interrupt flag of sleep working mode entering
|
||||
\arg CAN_INT_FLAG_WUIF: status change interrupt flag of wakeup from sleep working mode
|
||||
\arg CAN_INT_FLAG_ERRIF: error interrupt flag
|
||||
\arg CAN_INT_FLAG_MTF2: mailbox 2 transmit finished interrupt flag
|
||||
\arg CAN_INT_FLAG_MTF1: mailbox 1 transmit finished interrupt flag
|
||||
\arg CAN_INT_FLAG_MTF0: mailbox 0 transmit finished interrupt flag
|
||||
\arg CAN_INT_FLAG_RFO0: receive FIFO0 overfull interrupt flag
|
||||
\arg CAN_INT_FLAG_RFF0: receive FIFO0 full interrupt flag
|
||||
\arg CAN_INT_FLAG_RFO1: receive FIFO1 overfull interrupt flag
|
||||
\arg CAN_INT_FLAG_RFF1: receive FIFO1 full interrupt flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void can_interrupt_flag_clear(uint32_t can_periph, can_interrupt_flag_enum flag)
|
||||
{
|
||||
CAN_REG_VALS(can_periph, flag) |= BIT(CAN_BIT_POS0(flag));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable CAN phy
|
||||
\param[in] can_periph
|
||||
\arg CANx(x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void can_phy_enable(uint32_t can_periph)
|
||||
{
|
||||
CAN_PHYCTL(can_periph) |= CAN_PHYCTL_PHYEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable CAN phy
|
||||
\param[in] can_periph
|
||||
\arg CANx(x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void can_phy_disable(uint32_t can_periph)
|
||||
{
|
||||
CAN_PHYCTL(can_periph) &= ~CAN_PHYCTL_PHYEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set CAN phy mode
|
||||
\param[in] can_periph
|
||||
\arg CANx(x=0,1)
|
||||
\param[in] can_phy_mode
|
||||
\arg CAN_PHYMODE_LOW_SLOPE
|
||||
\arg CAN_PHYMODE_MIDDLE_SLOPE
|
||||
\arg CAN_PHYMODE_HIGH_SLOPE
|
||||
\arg CAN_PHYMODE_HIGH_SPEED
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void can_phy_mode(uint32_t can_periph, uint32_t phy_mode)
|
||||
{
|
||||
CAN_PHYCTL(can_periph) &= (~CAN_PHYCTL_POMODE_MASK);
|
||||
switch(phy_mode){
|
||||
case CAN_PHYCTL_POMODE_0:
|
||||
/*!< CAN PHY low slope mode */
|
||||
CAN_PHYCTL(can_periph) |= CAN_PHYCTL_POMODE_0;
|
||||
break;
|
||||
case CAN_PHYCTL_POMODE_1:
|
||||
/*!< CAN PHY middle slope mode */
|
||||
CAN_PHYCTL(can_periph) |= CAN_PHYCTL_POMODE_1;
|
||||
break;
|
||||
case CAN_PHYCTL_POMODE_2:
|
||||
/*!< CAN PHY high slope mode */
|
||||
CAN_PHYCTL(can_periph) |= CAN_PHYCTL_POMODE_2;
|
||||
break;
|
||||
case CAN_PHYCTL_POMODE_3:
|
||||
/*!< CAN PHY high speed mode */
|
||||
CAN_PHYCTL(can_periph) |= CAN_PHYCTL_POMODE_3;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* GD32F170_190 */
|
452
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_cec.c
Normal file
452
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_cec.c
Normal file
@@ -0,0 +1,452 @@
|
||||
/*!
|
||||
\file gd32f1x0_cec.c
|
||||
\brief CEC driver
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2017 GigaDevice
|
||||
|
||||
2014-12-26, V1.0.0, platform GD32F1x0(x=3,5)
|
||||
2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9)
|
||||
2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
*/
|
||||
|
||||
#include "gd32f1x0_cec.h"
|
||||
#include "gd32f1x0_rcu.h"
|
||||
|
||||
/*!
|
||||
\brief reset HDMI-CEC controller
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cec_deinit(void)
|
||||
{
|
||||
rcu_periph_reset_enable(RCU_CECRST);
|
||||
rcu_periph_reset_disable(RCU_CECRST);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure signal free time,the signal free time counter start option,own address
|
||||
\param[in] sftmopt: signal free time counter start option
|
||||
\arg CEC_SFT_START_STAOM: signal free time counter starts counting when STAOM is asserted
|
||||
\arg CEC_SFT_START_LAST: signal free time counter starts automatically after transmission/reception end
|
||||
\param[in] sft: signal free time
|
||||
\arg CEC_SFT_PROTOCOL_PERIOD: the signal free time will perform as HDMI-CEC protocol description
|
||||
\arg CEC_SFT_1POINT5_PERIOD: 1.5 nominal data bit periods
|
||||
\arg CEC_SFT_2POINT5_PERIOD: 2.5 nominal data bit periods
|
||||
\arg CEC_SFT_3POINT5_PERIOD: 3.5 nominal data bit periods
|
||||
\arg CEC_SFT_4POINT5_PERIOD: 4.5 nominal data bit periods
|
||||
\arg CEC_SFT_5POINT5_PERIOD: 5.5 nominal data bit periods
|
||||
\arg CEC_SFT_6POINT5_PERIOD: 6.5 nominal data bit periods
|
||||
\arg CEC_SFT_7POINT5_PERIOD: 7.5 nominal data bit periods
|
||||
\param[in] address: own address
|
||||
\arg CEC_OWN_ADDRESS_CLEAR: own address is cleared
|
||||
\arg CEC_OWN_ADDRESSx(x=0..14): own address is x
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cec_init(uint32_t sftopt, uint32_t sft, uint32_t address)
|
||||
{
|
||||
uint32_t cfg;
|
||||
cfg = CEC_CFG;
|
||||
/* clear SFTOPT bit,SFT[2:0] */
|
||||
cfg &= ~(CEC_CFG_SFTOPT | CEC_CFG_SFT);
|
||||
/* assign SFTOPT bit,SFT[2:0] */
|
||||
cfg |= (sftopt | sft);
|
||||
CEC_CFG = cfg;
|
||||
if(CEC_OWN_ADDRESS_CLEAR == address){
|
||||
CEC_CFG &= ~CEC_CFG_OAD;
|
||||
}else{
|
||||
CEC_CFG |= address;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure generate Error-bit when detected some abnormal situation or not,
|
||||
whether stop receive message when detected bit rising error
|
||||
\param[in] broadcast:
|
||||
\arg CEC_BROADCAST_ERROR_BIT_ON:generate Error-bit in broadcast
|
||||
\arg CEC_BROADCAST_ERROR_BIT_OFF:do not generate Error-bit in broadcast
|
||||
\param[in] singlecast_lbpe:
|
||||
\arg CEC_LONG_PERIOD_ERROR_BIT_ON:generate Error-bit on long bit period error
|
||||
\arg CEC_LONG_PERIOD_ERROR_BIT_OFF:do not generate Error-bit on long bit period error
|
||||
\param[in] singlecast_bre:
|
||||
\arg CEC_RISING_PERIOD_ERROR_BIT_ON:generate Error-bit on bit rising error
|
||||
\arg CEC_RISING_PERIOD_ERROR_BIT_OFF:do not generate Error-bit on bit rising error
|
||||
\param[in] rxbrestp:
|
||||
\arg CEC_STOP_RISING_ERROR_BIT_ON: stop reception when detected bit rising error
|
||||
\arg CEC_STOP_RISING_ERROR_BIT_OFF: do not stop reception when detected bit rising error
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cec_error_config(uint32_t broadcast, uint32_t singlecast_lbpe, uint32_t singlecast_bre, uint32_t rxbrestp)
|
||||
{
|
||||
uint32_t cfg;
|
||||
cfg = CEC_CFG;
|
||||
/* clear BCNG bit, BPLEG bit, BREG bit */
|
||||
cfg &= ~(CEC_CFG_BCNG | CEC_CFG_BPLEG | CEC_CFG_BREG);
|
||||
/* assign BCNG bit, BPLEG bit, BREG bit */
|
||||
cfg |= (broadcast | singlecast_lbpe | singlecast_bre);
|
||||
CEC_CFG = cfg;
|
||||
if(CEC_STOP_RISING_ERROR_BIT_ON == rxbrestp){
|
||||
CEC_CFG |= CEC_CFG_BRES;
|
||||
}else{
|
||||
CEC_CFG &= ~CEC_CFG_BRES;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable HDMI-CEC controller
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cec_enable(void)
|
||||
{
|
||||
CEC_CTL |= CEC_CTL_CECEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable HDMI-CEC controller
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cec_disable(void)
|
||||
{
|
||||
CEC_CTL &= ~CEC_CTL_CECEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief start CEC message transmission
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cec_transmission_start(void)
|
||||
{
|
||||
CEC_CTL |= CEC_CTL_STAOM;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief end CEC message transmission
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cec_transmission_end(void)
|
||||
{
|
||||
CEC_CTL |= CEC_CTL_ENDOM;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable CEC listen mode.
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cec_listen_mode_enable(void)
|
||||
{
|
||||
CEC_CFG |= CEC_CFG_LMEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable CEC listen mode.
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cec_listen_mode_disable(void)
|
||||
{
|
||||
CEC_CFG &= ~CEC_CFG_LMEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure and clear own address.the controller can be configured to multiple own address
|
||||
\param[in] address: own address
|
||||
\arg CEC_OWN_ADDRESS_CLEAR: own address is cleared
|
||||
\arg CEC_OWN_ADDRESSx(x=0..14): own address is x
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cec_own_address_config(uint32_t address)
|
||||
{
|
||||
if(CEC_OWN_ADDRESS_CLEAR == address){
|
||||
CEC_CFG &= ~CEC_CFG_OAD;
|
||||
} else {
|
||||
CEC_CFG |= address;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure signal free time and the signal free time counter start option
|
||||
\param[in] sftopt: signal free time counter start option
|
||||
\arg CEC_SFT_START_STAOM: signal free time counter starts counting when STAOM is asserted
|
||||
\arg CEC_SFT_START_LAST: signal free time counter starts automatically after transmission/reception end
|
||||
\param[in] sft: signal free time
|
||||
\arg CEC_SFT_PROTOCOL_PERIOD: the signal free time will perform as HDMI-CEC protocol description
|
||||
\arg CEC_SFT_1POINT5_PERIOD: 1.5 nominal data bit periods
|
||||
\arg CEC_SFT_2POINT5_PERIOD: 2.5 nominal data bit periods
|
||||
\arg CEC_SFT_3POINT5_PERIOD: 3.5 nominal data bit periods
|
||||
\arg CEC_SFT_4POINT5_PERIOD: 4.5 nominal data bit periods
|
||||
\arg CEC_SFT_5POINT5_PERIOD: 5.5 nominal data bit periods
|
||||
\arg CEC_SFT_6POINT5_PERIOD: 6.5 nominal data bit periods
|
||||
\arg CEC_SFT_7POINT5_PERIOD: 7.5 nominal data bit periods
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cec_sft_config(uint32_t sftopt, uint32_t sft)
|
||||
{
|
||||
uint32_t cfg;
|
||||
cfg = CEC_CFG;
|
||||
/* clear SFTOPT bit,SFT[2:0] */
|
||||
cfg &= ~(CEC_CFG_SFTOPT | CEC_CFG_SFT);
|
||||
/* assign SFTOPT bit,SFT[2:0] */
|
||||
cfg |= (sftopt | sft);
|
||||
CEC_CFG = cfg;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure generate Error-bit when detected some abnormal situation or not
|
||||
\param[in] broadcast:
|
||||
\arg CEC_BROADCAST_ERROR_BIT_ON:generate Error-bit in broadcast
|
||||
\arg CEC_BROADCAST_ERROR_BIT_OFF:do not generate Error-bit in broadcast
|
||||
\param[in] singlecast_lbpe:
|
||||
\arg CEC_LONG_PERIOD_ERROR_BIT_ON:generate Error-bit on long bit period error
|
||||
\arg CEC_LONG_PERIOD_ERROR_BIT_OFF:do not generate Error-bit on long bit period error
|
||||
\param[in] singlecast_bre:
|
||||
\arg CEC_RISING_PERIOD_ERROR_BIT_ON:generate Error-bit on bit rising error
|
||||
\arg CEC_RISING_PERIOD_ERROR_BIT_OFF:do not generate Error-bit on bit rising error
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cec_generate_errorbit_config(uint32_t broadcast, uint32_t singlecast_lbpe, uint32_t singlecast_bre)
|
||||
{
|
||||
uint32_t cfg;
|
||||
cfg = CEC_CFG;
|
||||
/* clear BCNG bit, BPLEG bit, BREG bit */
|
||||
cfg &= ~(CEC_CFG_BCNG | CEC_CFG_BPLEG | CEC_CFG_BREG);
|
||||
/* assign BCNG bit, BPLEG bit, BREG bit */
|
||||
cfg |= (broadcast | singlecast_lbpe | singlecast_bre);
|
||||
CEC_CFG = cfg;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief whether stop receive message when detected bit rising error
|
||||
\param[in] rxbrestp:
|
||||
\arg CEC_STOP_RISING_ERROR_BIT_ON: stop reception when detected bit rising error
|
||||
\arg CEC_STOP_RISING_ERROR_BIT_OFF: do not stop reception when detected bit rising error
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cec_stop_receive_bre_config(uint32_t rxbrestp)
|
||||
{
|
||||
if(CEC_STOP_RISING_ERROR_BIT_ON == rxbrestp){
|
||||
CEC_CFG |= CEC_CFG_BRES;
|
||||
} else {
|
||||
CEC_CFG &= ~CEC_CFG_BRES;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable reception bit timing tolerance
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cec_reception_tolerance_enable(void)
|
||||
{
|
||||
CEC_CFG |= CEC_CFG_RTOL;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable reception bit timing tolerance
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cec_reception_tolerance_disable(void)
|
||||
{
|
||||
CEC_CFG &= ~CEC_CFG_RTOL;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief send a data by the CEC peripheral
|
||||
\param[in] data: the data to transmit
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cec_data_send(uint8_t data)
|
||||
{
|
||||
CEC_TDATA = (uint32_t)data;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief receive a data by the CEC peripheral
|
||||
\param[in] data: the data to receive
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
uint8_t cec_data_receive(void)
|
||||
{
|
||||
return (uint8_t)CEC_RDATA;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get CEC int flag
|
||||
\param[in] flag: specify which flag
|
||||
\arg CEC_INT_FLAG_BR: Rx-byte data received
|
||||
\arg CEC_INT_FLAG_REND: end of reception
|
||||
\arg CEC_INT_FLAG_RO: RX overrun
|
||||
\arg CEC_INT_FLAG_BRE: bit rising error
|
||||
\arg CEC_INT_FLAG_BPSE: short bit period error
|
||||
\arg CEC_INT_FLAG_BPLE: long bit period error
|
||||
\arg CEC_INT_FLAG_RAE: Rx ACK error
|
||||
\arg CEC_INT_FLAG_ARBF: arbitration lost
|
||||
\arg CEC_INT_FLAG_TBR: Tx-byte data request
|
||||
\arg CEC_INT_FLAG_TEND: transmission successfully end
|
||||
\arg CEC_INT_FLAG_TU: Tx data buffer underrun
|
||||
\arg CEC_INT_FLAG_TERR: Tx-error
|
||||
\arg CEC_INT_FLAG_TAERR: Tx ACK error flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus cec_interrupt_flag_get(uint32_t flag)
|
||||
{
|
||||
uint32_t interrupt_enable = 0U,interrupt_flag = 0U;
|
||||
interrupt_flag = (CEC_INTF & flag);
|
||||
interrupt_enable = (CEC_INTEN & flag);
|
||||
if(interrupt_flag && interrupt_enable){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear CEC int flag and status
|
||||
\param[in] flag: specify which flag
|
||||
\arg CEC_INT_FLAG_BR: Rx-byte data received
|
||||
\arg CEC_INT_FLAG_REND: end of reception
|
||||
\arg CEC_INT_FLAG_RO: RX overrun
|
||||
\arg CEC_INT_FLAG_BRE: bit rising error
|
||||
\arg CEC_INT_FLAG_BPSE: short bit period error
|
||||
\arg CEC_INT_FLAG_BPLE: long bit period error
|
||||
\arg CEC_INT_FLAG_RAE: Rx ACK error
|
||||
\arg CEC_INT_FLAG_ARBF: arbitration lost
|
||||
\arg CEC_INT_FLAG_TBR: Tx-byte data request
|
||||
\arg CEC_INT_FLAG_TEND: transmission successfully end
|
||||
\arg CEC_INT_FLAG_TU: Tx data buffer underrun
|
||||
\arg CEC_INT_FLAG_TERR: Tx-error
|
||||
\arg CEC_INT_FLAG_TAERR: Tx ACK error flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cec_interrupt_flag_clear(uint32_t flag)
|
||||
{
|
||||
CEC_INTF = flag;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable interrupt
|
||||
\param[in] flag: specify which flag
|
||||
\arg CEC_INT_BR: enable Rx-byte data received interrupt
|
||||
\arg CEC_INT_REND: enable end of reception interrupt
|
||||
\arg CEC_INT_RO: enable RX overrun interrupt
|
||||
\arg CEC_INT_BRE: enable bit rising error interrupt
|
||||
\arg CEC_INT_BPSE: enable short bit period error interrupt
|
||||
\arg CEC_INT_BPLE: enable long bit period error interrupt
|
||||
\arg CEC_INT_RAE: enable Rx ACK error interrupt
|
||||
\arg CEC_INT_ARBF: enable arbitration lost interrupt
|
||||
\arg CEC_INT_TBR: enable Tx-byte data request interrupt
|
||||
\arg CEC_INT_TEND: enable transmission successfully end interrupt
|
||||
\arg CEC_INT_TU: enable Tx data buffer underrun interrupt
|
||||
\arg CEC_INT_TERR: enable Tx-error interrupt
|
||||
\arg CEC_INT_TAERR: enable Tx ACK error interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cec_interrupt_enable(uint32_t flag)
|
||||
{
|
||||
CEC_INTEN |= flag;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable interrupt
|
||||
\param[in] flag: specify which flag
|
||||
\arg CEC_INT_BR: disable Rx-byte data received interrupt
|
||||
\arg CEC_INT_REND: disable end of reception interrupt
|
||||
\arg CEC_INT_RO: disable RX overrun interrupt
|
||||
\arg CEC_INT_BRE: disable bit rising error interrupt
|
||||
\arg CEC_INT_BPSE: disable short bit period error interrupt
|
||||
\arg CEC_INT_BPLE: disable long bit period error interrupt
|
||||
\arg CEC_INT_RAE: disable Rx ACK error interrupt
|
||||
\arg CEC_INT_ARBF: disable arbitration lost interrupt
|
||||
\arg CEC_INT_TBR: disable Tx-byte data request interrupt
|
||||
\arg CEC_INT_TEND: disable transmission successfully end interrupt
|
||||
\arg CEC_INT_TU: disable Tx data buffer underrun interrupt
|
||||
\arg CEC_INT_TERR: disable Tx-error interrupt
|
||||
\arg CEC_INT_TAERR: disable Tx ACK error interrupt
|
||||
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cec_interrupt_disable(uint32_t flag)
|
||||
{
|
||||
CEC_INTEN &= ~flag;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get CEC status
|
||||
\param[in] flag: specify which flag
|
||||
\arg CEC_FLAG_BR: Rx-byte data received
|
||||
\arg CEC_FLAG_REND: end of reception
|
||||
\arg CEC_FLAG_RO: RX overrun
|
||||
\arg CEC_FLAG_BRE: bit rising error
|
||||
\arg CEC_FLAG_BPSE: short bit period error
|
||||
\arg CEC_FLAG_BPLE: long bit period error
|
||||
\arg CEC_FLAG_RAE: Rx ACK error
|
||||
\arg CEC_FLAG_ARBF: arbitration lost
|
||||
\arg CEC_FLAG_TBR: Tx-byte data request
|
||||
\arg CEC_FLAG_TEND: transmission successfully end
|
||||
\arg CEC_FLAG_TU: Tx data buffer underrun
|
||||
\arg CEC_FLAG_TERR: Tx-error
|
||||
\arg CEC_FLAG_TAERR Tx ACK error flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus cec_flag_get(uint32_t flag)
|
||||
{
|
||||
if(CEC_INTF & flag){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear CEC status
|
||||
\param[in] flag: specify which flag
|
||||
\arg CEC_FLAG_BR: Rx-byte data received
|
||||
\arg CEC_FLAG_REND: end of reception
|
||||
\arg CEC_FLAG_RO: RX overrun
|
||||
\arg CEC_FLAG_BRE: bit rising error
|
||||
\arg CEC_FLAG_BPSE: short bit period error
|
||||
\arg CEC_FLAG_BPLE: long bit period error
|
||||
\arg CEC_FLAG_RAE: Rx ACK error
|
||||
\arg CEC_FLAG_ARBF: arbitration lost
|
||||
\arg CEC_FLAG_TBR: Tx-byte data request
|
||||
\arg CEC_FLAG_TEND: transmission successfully end
|
||||
\arg CEC_FLAG_TU: Tx data buffer underrun
|
||||
\arg CEC_FLAG_TERR: Tx-error
|
||||
\arg CEC_FLAG_TAERR Tx ACK error flag
|
||||
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
void cec_flag_clear(uint32_t flag)
|
||||
{
|
||||
CEC_INTF |= flag;
|
||||
}
|
244
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_cmp.c
Normal file
244
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_cmp.c
Normal file
@@ -0,0 +1,244 @@
|
||||
/*!
|
||||
\file gd32f1x0_cmp.c
|
||||
\brief CMP driver
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2017 GigaDevice
|
||||
|
||||
2014-12-26, V1.0.0, platform GD32F1x0(x=5)
|
||||
2016-01-15, V2.0.0, platform GD32F1x0(x=5,9)
|
||||
2016-04-30, V3.0.0, firmware update for GD32F1x0(x=5,9)
|
||||
2017-06-19, V3.1.0, firmware update for GD32F1x0(x=5,9)
|
||||
*/
|
||||
|
||||
#include "gd32f1x0_cmp.h"
|
||||
|
||||
/*!
|
||||
\brief deinitialize comparator
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cmp_deinit(void)
|
||||
{
|
||||
CMP_CS = ((uint32_t)0x00000000);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize comparator mode
|
||||
\param[in] cmp_periph
|
||||
\arg CMP0: comparator 0
|
||||
\arg CMP1: comparator 1
|
||||
\param[in] cmp_operating_mode
|
||||
\arg CMP_HIGHSPEED: high speed mode
|
||||
\arg CMP_MIDDLESPEED: medium speed mode
|
||||
\arg CMP_LOWSPEED: low speed mode
|
||||
\arg CMP_VERYLOWSPEED: very-low speed mode
|
||||
\param[in] cmp_inverting_input
|
||||
\arg CMP_1_4VREFINT: VREFINT *1/4 input
|
||||
\arg CMP_1_2VREFINT: VREFINT *1/2 input
|
||||
\arg CMP_3_4VREFINT: VREFINT *3/4 input
|
||||
\arg CMP_VREFINT: VREFINT input
|
||||
\arg CMP_DAC: PA4 (DAC) input
|
||||
\arg CMP_PA5: PA5 input
|
||||
\arg CMP_PA_0_2: PA0 or PA2 input
|
||||
\param[in] cmp_hysteresis
|
||||
\arg CMP_HYSTERESIS_NO: output no hysteresis
|
||||
\arg CMP_HYSTERESIS_LOW: output low hysteresis
|
||||
\arg CMP_HYSTERESIS_MIDDLE: output middle hysteresis
|
||||
\arg CMP_HYSTERESIS_HIGH: output high hysteresis
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cmp_mode_init(uint32_t cmp_periph, operating_mode_enum cmp_operating_mode, inverting_input_enum cmp_inverting_input, cmp_hysteresis_enum output_hysteresis)
|
||||
{
|
||||
if(CMP0 == cmp_periph){
|
||||
/* initialize comparator 0 mode */
|
||||
CMP_CS |= CS_CMP0M(cmp_operating_mode) | CS_CMP0MSEL(cmp_inverting_input) | CS_CMP0HST(output_hysteresis);
|
||||
}else{
|
||||
/* initialize comparator 1 mode */
|
||||
CMP_CS |= CS_CMP1M(cmp_operating_mode) | CS_CMP1MSEL(cmp_inverting_input) | CS_CMP1HST(output_hysteresis);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize comparator output
|
||||
\param[in] cmp_periph
|
||||
\arg CMP0: comparator 0
|
||||
\arg CMP1: comparator 1
|
||||
\param[in] cmp_output
|
||||
\arg CMP_OUTPUT_NONE: output no selection
|
||||
\arg CMP_OUTPUT_TIMER0BKIN: TIMER 0 break input
|
||||
\arg CMP_OUTPUT_TIMER0IC0: TIMER 0 channel0 input capture
|
||||
\arg CMP_OUTPUT_TIMER0OCPRECLR: TIMER 0 OCPRE_CLR input
|
||||
\arg CMP_OUTPUT_TIMER1IC3: TIMER 1 channel3 input capture
|
||||
\arg CMP_OUTPUT_TIMER1OCPRECLR: TIMER 1 OCPRE_CLR input
|
||||
\arg CMP_OUTPUT_TIMER2IC0: TIMER 2 channel0 input capture
|
||||
\arg CMP_OUTPUT_TIMER2OCPRECLR: TIMER 2 OCPRE_CLR input
|
||||
\param[in] cmp_output_polarity
|
||||
\arg CMP_OUTPUT_POLARITY_INVERTED: output is inverted
|
||||
\arg CMP_OUTPUT_POLARITY_NOINVERTED: output is not inverted
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cmp_output_init(uint32_t cmp_periph, cmp_output_enum cmp_output_slection, uint32_t cmp_output_polarity)
|
||||
{
|
||||
/* initialize comparator 0 output */
|
||||
if(CMP0 == cmp_periph){
|
||||
CMP_CS |= CS_CMP0OSEL(cmp_output_slection);
|
||||
/* output polarity */
|
||||
if(CMP_OUTPUT_POLARITY_INVERTED == cmp_output_polarity){
|
||||
CMP_CS |= CMP_CS_CMP0PL;
|
||||
}else{
|
||||
CMP_CS &= ~CMP_CS_CMP0PL;
|
||||
}
|
||||
}else{
|
||||
CMP_CS |= CS_CMP1OSEL(cmp_output_slection);
|
||||
|
||||
if(CMP_OUTPUT_POLARITY_INVERTED == cmp_output_polarity){
|
||||
CMP_CS |= CMP_CS_CMP1PL;
|
||||
}else{
|
||||
CMP_CS &= ~CMP_CS_CMP1PL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable comparator
|
||||
\param[in] cmp_periph
|
||||
\arg CMP0: comparator 0
|
||||
\arg CMP1: comparator 1
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cmp_enable(uint32_t cmp_periph)
|
||||
{
|
||||
if(CMP0 == cmp_periph){
|
||||
CMP_CS |= CMP_CS_CMP0EN;
|
||||
}else{
|
||||
CMP_CS |= CMP_CS_CMP1EN;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable comparator
|
||||
\param[in] cmp_periph
|
||||
\arg CMP0: comparator 0
|
||||
\arg CMP1: comparator 1
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cmp_disable(uint32_t cmp_periph)
|
||||
{
|
||||
if(CMP0 == cmp_periph){
|
||||
CMP_CS &= ~CMP_CS_CMP0EN;
|
||||
}else{
|
||||
CMP_CS &= ~CMP_CS_CMP1EN;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable comparator switch
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cmp_switch_enable(void)
|
||||
{
|
||||
CMP_CS |= CMP_CS_CMP0SW;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable comparator switch
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cmp_switch_disable(void)
|
||||
{
|
||||
CMP_CS &= ~CMP_CS_CMP0SW;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief enable the window mode
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cmp_window_enable(void)
|
||||
{
|
||||
CMP_CS |= CMP_CS_WNDEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the window mode
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cmp_window_disable(void)
|
||||
{
|
||||
CMP_CS &= ~CMP_CS_WNDEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief lock the comparator
|
||||
\param[in] cmp_periph
|
||||
\arg CMP0: comparator 0
|
||||
\arg CMP1: comparator 1
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cmp_lock_enable(uint32_t cmp_periph)
|
||||
{
|
||||
if(CMP0 == cmp_periph){
|
||||
CMP_CS |= CMP_CS_CMP0LK;
|
||||
}else{
|
||||
CMP_CS |= CMP_CS_CMP1LK;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief unlock the comparator
|
||||
\param[in] cmp_periph
|
||||
\arg CMP0: comparator 0
|
||||
\arg CMP1: comparator 1
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void cmp_lock_disable(uint32_t cmp_periph)
|
||||
{
|
||||
if(CMP0 == cmp_periph){
|
||||
CMP_CS &= ~CMP_CS_CMP0LK;
|
||||
}else{
|
||||
CMP_CS &= ~CMP_CS_CMP1LK;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get output level
|
||||
\param[in] cmp_periph
|
||||
\arg CMP0: comparator 0
|
||||
\arg CMP1: comparator 1
|
||||
\param[out] none
|
||||
\retval the output level
|
||||
*/
|
||||
uint32_t cmp_output_level_get(uint32_t cmp_periph)
|
||||
{
|
||||
if(CMP0 == cmp_periph){
|
||||
if(CMP_CS & CMP_CS_CMP0O){
|
||||
return CMP_OUTPUTLEVEL_HIGH;
|
||||
}else{
|
||||
return CMP_OUTPUTLEVEL_LOW;
|
||||
}
|
||||
}else{
|
||||
if(CMP_CS & CMP_CS_CMP1O){
|
||||
return CMP_OUTPUTLEVEL_HIGH;
|
||||
}else{
|
||||
return CMP_OUTPUTLEVEL_LOW;
|
||||
}
|
||||
}
|
||||
}
|
155
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_crc.c
Normal file
155
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_crc.c
Normal file
@@ -0,0 +1,155 @@
|
||||
/*!
|
||||
\file gd32f1x0_crc.c
|
||||
\brief CRC driver
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2017 GigaDevice
|
||||
|
||||
2014-12-26, V1.0.0, platform GD32F1x0(x=3,5)
|
||||
2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9)
|
||||
2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
*/
|
||||
|
||||
#include "gd32f1x0_crc.h"
|
||||
|
||||
/*!
|
||||
\brief deinit CRC calculation unit
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void crc_deinit(void)
|
||||
{
|
||||
CRC_IDATA = (uint32_t)0xFFFFFFFFU;
|
||||
CRC_DATA = (uint32_t)0xFFFFFFFFU;
|
||||
CRC_FDATA = (uint32_t)0x00000000U;
|
||||
CRC_CTL = CRC_CTL_RST;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the reverse operation of output data
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void crc_reverse_output_data_enable(void)
|
||||
{
|
||||
CRC_CTL &= (uint32_t)(~ CRC_CTL_REV_O);
|
||||
CRC_CTL |= (uint32_t)CRC_CTL_REV_O;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the reverse operation of output data
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void crc_reverse_output_data_disable(void)
|
||||
{
|
||||
CRC_CTL &= (uint32_t)(~ CRC_CTL_REV_O);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief reset data register to the value of initializaiton data register
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void crc_data_register_reset(void)
|
||||
{
|
||||
CRC_CTL |= (uint32_t)CRC_CTL_RST;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief read the data register
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval 32-bit value of the data register
|
||||
*/
|
||||
uint32_t crc_data_register_read(void)
|
||||
{
|
||||
uint32_t data;
|
||||
data = CRC_DATA;
|
||||
return (data);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief read the free data register
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval 8-bit value of the free data register
|
||||
*/
|
||||
uint8_t crc_free_data_register_read(void)
|
||||
{
|
||||
uint8_t fdata;
|
||||
fdata = (uint8_t)CRC_FDATA;
|
||||
return (fdata);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief write the free data register
|
||||
\param[in] free_data: specify 8-bit data
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void crc_free_data_register_write(uint8_t free_data)
|
||||
{
|
||||
CRC_FDATA = (uint32_t)free_data;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief write the initializaiton data register
|
||||
\param[in] init_data:specify 32-bit data
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void crc_init_data_register_write(uint32_t init_data)
|
||||
{
|
||||
CRC_IDATA = (uint32_t)init_data;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the CRC input data function
|
||||
\param[in] data_reverse: specify input data reverse function
|
||||
\arg CRC_INPUT_DATA_NOT: input data is not reversed
|
||||
\arg CRC_INPUT_DATA_BYTE: input data is reversed on 8 bits
|
||||
\arg CRC_INPUT_DATA_HALFWORD: input data is reversed on 16 bits
|
||||
\arg CRC_INPUT_DATA_WORD: input data is reversed on 32 bits
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void crc_input_data_reverse_config(uint32_t data_reverse)
|
||||
{
|
||||
CRC_CTL &= (uint32_t)(~CRC_CTL_REV_I);
|
||||
CRC_CTL |= (uint32_t)data_reverse;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief CRC calculate a 32-bit data
|
||||
\param[in] sdata: specify 32-bit data
|
||||
\param[out] none
|
||||
\retval 32-bit CRC calculate value
|
||||
*/
|
||||
uint32_t crc_single_data_calculate(uint32_t sdata)
|
||||
{
|
||||
CRC_DATA = sdata;
|
||||
return (CRC_DATA);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief CRC calculate a 32-bit data array
|
||||
\param[in] array: pointer to an array of 32 bit data words
|
||||
\param[in] size: size of the array
|
||||
\param[out] none
|
||||
\retval 32-bit CRC calculate value
|
||||
*/
|
||||
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);
|
||||
}
|
792
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_dac.c
Normal file
792
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_dac.c
Normal file
@@ -0,0 +1,792 @@
|
||||
/*!
|
||||
\file gd32f1x0_dac.c
|
||||
\brief DAC driver
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2017 GigaDevice
|
||||
|
||||
2014-12-26, V1.0.0, platform GD32F1x0(x=3,5)
|
||||
2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9)
|
||||
2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
*/
|
||||
|
||||
|
||||
#include "gd32f1x0_dac.h"
|
||||
|
||||
/*!
|
||||
\brief deinit DAC
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_deinit(void)
|
||||
{
|
||||
rcu_periph_reset_enable(RCU_DACRST);
|
||||
rcu_periph_reset_disable(RCU_DACRST);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DAC0
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac0_enable(void)
|
||||
{
|
||||
DAC_CTL |= DAC_CTL_DEN0;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DAC0
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac0_disable(void)
|
||||
{
|
||||
DAC_CTL &= ~DAC_CTL_DEN0;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DAC0 DMA
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac0_dma_enable(void)
|
||||
{
|
||||
DAC_CTL |= DAC_CTL_DDMAEN0;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DAC0 DMA
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac0_dma_disable(void)
|
||||
{
|
||||
DAC_CTL &= ~DAC_CTL_DDMAEN0;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DAC0 output buffer
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac0_output_buffer_enable(void)
|
||||
{
|
||||
DAC_CTL &= ~DAC_CTL_DBOFF0;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DAC0 output buffer
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac0_output_buffer_disable(void)
|
||||
{
|
||||
DAC_CTL |= DAC_CTL_DBOFF0;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DAC0 trigger
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac0_trigger_enable(void)
|
||||
{
|
||||
DAC_CTL |= DAC_CTL_DTEN0;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DAC0 trigger
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac0_trigger_disable(void)
|
||||
{
|
||||
DAC_CTL &= ~DAC_CTL_DTEN0;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DAC0 software trigger
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac0_software_trigger_enable(void)
|
||||
{
|
||||
DAC_SWT |= DAC_SWT_SWTR0;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DAC0 software trigger
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac0_software_trigger_disable(void)
|
||||
{
|
||||
DAC_SWT &= ~DAC_SWT_SWTR0;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DAC0 interrupt(DAC0 DMA underrun interrupt)
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac0_interrupt_enable(void)
|
||||
{
|
||||
DAC_CTL |= DAC_CTL_DDUDRIE0;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DAC0 interrupt(DAC0 DMA underrun interrupt)
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac0_interrupt_disable(void)
|
||||
{
|
||||
DAC_CTL &= ~DAC_CTL_DDUDRIE0;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set DAC0 tgigger source
|
||||
\param[in] triggersource: external triggers of DAC
|
||||
\arg DAC_TRIGGER_T1_TRGO: trigger source is timer1 trgo
|
||||
\arg DAC_TRIGGER_T2_TRGO: trigger source is timer2 trgo
|
||||
\arg DAC_TRIGGER_T5_TRGO: trigger source is timer5 trgo
|
||||
\arg DAC_TRIGGER_T14_TRGO: trigger source is timer14 trgo
|
||||
\arg DAC_TRIGGER_EXTI_IT9: trigger source is exti interrupt line 9
|
||||
\arg DAC_TRIGGER_SOFTWARE: trigger source is software
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac0_trigger_source_config(uint32_t triggersource)
|
||||
{
|
||||
DAC_CTL &= ~DAC_CTL_DTSEL0;
|
||||
DAC_CTL |= triggersource;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the last data output value of DAC0
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval DAC output data
|
||||
*/
|
||||
uint16_t dac0_output_value_get(void)
|
||||
{
|
||||
uint16_t data = 0U;
|
||||
data = (uint16_t)DAC0_DO;
|
||||
return data;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the specified DAC0 flag(DAC0 DMA underrun flag)
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval the state of dac bit(SET or RESET)
|
||||
*/
|
||||
FlagStatus dac0_flag_get(void)
|
||||
{
|
||||
/* check the DMA underrun flag */
|
||||
if((uint8_t)RESET != (DAC_STAT & DAC_STAT_DDUDR0)){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear the specified DAC0 flag(DAC0 DMA underrun flag)
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac0_flag_clear(void)
|
||||
{
|
||||
DAC_STAT &= ~DAC_STAT_DDUDR0;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the specified DAC0 interrupt flag(DAC0 DMA underrun interrupt flag)
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval the state of DAC interrupt flag(SET or RESET)
|
||||
*/
|
||||
FlagStatus dac0_interrupt_flag_get(void)
|
||||
{
|
||||
uint32_t ddudr_flag = 0U, ddudrie_flag = 0U;
|
||||
ddudr_flag = (DAC_STAT & DAC_STAT_DDUDR0);
|
||||
ddudrie_flag = DAC_CTL & DAC_CTL_DDUDRIE0;
|
||||
/* check the DMA underrun flag and DAC DMA underrun interrupt enable flag */
|
||||
if((RESET != ddudr_flag) && (RESET != ddudrie_flag)){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear the specified DAC0 interrupt flag(DAC0 DMA underrun interrupt flag)
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac0_interrupt_flag_clear(void)
|
||||
{
|
||||
DAC_CTL &= ~DAC_CTL_DDUDRIE0;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set DAC0 data holding register value
|
||||
\param[in] dac_align
|
||||
\arg DAC_ALIGN_8B_R: data right 8b alignment
|
||||
\arg DAC_ALIGN_12B_R: data right 12b alignment
|
||||
\arg DAC_ALIGN_12B_L: data left 12b alignment
|
||||
\param[in] data: data to be loaded
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac0_data_set(uint32_t dac_align, uint16_t data)
|
||||
{
|
||||
switch(dac_align){
|
||||
/* data right 12b alignment */
|
||||
case DAC_ALIGN_12B_R:
|
||||
DAC0_R12DH = data;
|
||||
break;
|
||||
/* data left 12b alignment */
|
||||
case DAC_ALIGN_12B_L:
|
||||
DAC0_L12DH = data;
|
||||
break;
|
||||
/* data right 8b alignment */
|
||||
case DAC_ALIGN_8B_R:
|
||||
DAC0_R8DH = data;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef GD32F170_190
|
||||
/*!
|
||||
\brief enable DAC
|
||||
\param[in] dac_periph
|
||||
\arg DACx(x =0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_enable(uint32_t dac_periph)
|
||||
{
|
||||
if(DAC0 == dac_periph){
|
||||
DAC_CTL |= DAC_CTL_DEN0;
|
||||
}else{
|
||||
DAC_CTL |= DAC_CTL_DEN1;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DAC
|
||||
\param[in] dac_periph
|
||||
\arg DACx(x =0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_disable(uint32_t dac_periph)
|
||||
{
|
||||
if(DAC0 == dac_periph){
|
||||
DAC_CTL &= ~DAC_CTL_DEN0;
|
||||
}else{
|
||||
DAC_CTL &= ~DAC_CTL_DEN1;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DAC DMA function
|
||||
\param[in] dac_periph
|
||||
\arg DACx(x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_dma_enable(uint32_t dac_periph)
|
||||
{
|
||||
if(DAC0 == dac_periph){
|
||||
DAC_CTL |= DAC_CTL_DDMAEN0;
|
||||
}else{
|
||||
DAC_CTL |= DAC_CTL_DDMAEN1;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DAC DMA function
|
||||
\param[in] dac_periph
|
||||
\arg DACx(x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_dma_disable(uint32_t dac_periph)
|
||||
{
|
||||
if(DAC0 == dac_periph){
|
||||
DAC_CTL &= ~DAC_CTL_DDMAEN0;
|
||||
}else{
|
||||
DAC_CTL &= ~DAC_CTL_DDMAEN1;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DAC output buffer
|
||||
\param[in] dac_periph
|
||||
\arg DACx(x =0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_output_buffer_enable(uint32_t dac_periph)
|
||||
{
|
||||
if(DAC0 == dac_periph){
|
||||
DAC_CTL &= ~DAC_CTL_DBOFF0;
|
||||
}else{
|
||||
DAC_CTL &= ~DAC_CTL_DBOFF1;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DAC output buffer
|
||||
\param[in] dac_periph
|
||||
\arg DACx(x =0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_output_buffer_disable(uint32_t dac_periph)
|
||||
{
|
||||
if(DAC0 == dac_periph){
|
||||
DAC_CTL |= DAC_CTL_DBOFF0;
|
||||
}else{
|
||||
DAC_CTL |= DAC_CTL_DBOFF1;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DAC trigger
|
||||
\param[in] dac_periph
|
||||
\arg DACx(x =0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_trigger_enable(uint32_t dac_periph)
|
||||
{
|
||||
if(DAC0 == dac_periph){
|
||||
DAC_CTL |= DAC_CTL_DTEN0;
|
||||
}else{
|
||||
DAC_CTL |= DAC_CTL_DTEN1;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DAC trigger
|
||||
\param[in] dac_periph
|
||||
\arg DACx(x =0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_trigger_disable(uint32_t dac_periph)
|
||||
{
|
||||
if(DAC0 == dac_periph){
|
||||
DAC_CTL &= ~DAC_CTL_DTEN0;
|
||||
}else{
|
||||
DAC_CTL &= ~DAC_CTL_DTEN1;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DAC software trigger
|
||||
\param[in] dac_periph
|
||||
\arg DACx(x =0,1)
|
||||
\retval none
|
||||
*/
|
||||
void dac_software_trigger_enable(uint32_t dac_periph)
|
||||
{
|
||||
if(DAC0 == dac_periph){
|
||||
DAC_SWT |= DAC_SWT_SWTR0;
|
||||
}else{
|
||||
DAC_SWT |= DAC_SWT_SWTR1;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DAC software trigger
|
||||
\param[in] dac_periph
|
||||
\arg DACx(x =0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_software_trigger_disable(uint32_t dac_periph)
|
||||
{
|
||||
if(DAC0 == dac_periph){
|
||||
DAC_SWT &= ~DAC_SWT_SWTR0;
|
||||
}else{
|
||||
DAC_SWT &= ~DAC_SWT_SWTR1;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get DAC output value
|
||||
\param[in] dac_periph
|
||||
\arg DACx(x=0,1)
|
||||
\param[out] none
|
||||
\retval DAC output data
|
||||
*/
|
||||
uint16_t dac_output_value_get(uint32_t dac_periph)
|
||||
{
|
||||
uint16_t data = 0U;
|
||||
if(DAC0 == dac_periph){
|
||||
data = (uint16_t)DAC0_DO;
|
||||
}else{
|
||||
data = (uint16_t)DAC1_DO;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DAC interrupt(DAC0 DMA underrun interrupt)
|
||||
\param[in] dac_periph
|
||||
\arg DACx(x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_interrupt_enable(uint32_t dac_periph)
|
||||
{
|
||||
if(DAC0 == dac_periph){
|
||||
DAC_CTL |= DAC_CTL_DDUDRIE0;
|
||||
}else{
|
||||
DAC_CTL |= DAC_CTL_DDUDRIE1;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DAC interrupt(DAC0 DMA underrun interrupt)
|
||||
\param[in] dac_periph
|
||||
\arg DACx(x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_interrupt_disable(uint32_t dac_periph)
|
||||
{
|
||||
if(DAC0 == dac_periph){
|
||||
DAC_CTL &= ~DAC_CTL_DDUDRIE0;
|
||||
}else{
|
||||
DAC_CTL &= ~DAC_CTL_DDUDRIE1;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set DAC trigger source
|
||||
\param[in] dac_periph
|
||||
\arg DACx(x =0,1)
|
||||
\param[in] triggersource: external triggers of DAC
|
||||
\arg DAC_TRIGGER_T1_TRGO: trigger source is timer1 trgo
|
||||
\arg DAC_TRIGGER_T2_TRGO: trigger source is timer2 trgo
|
||||
\arg DAC_TRIGGER_T5_TRGO: trigger source is timer5 trgo
|
||||
\arg DAC_TRIGGER_T14_TRGO: trigger source is timer14 trgo
|
||||
\arg DAC_TRIGGER_EXTI_IT9: trigger source is exti interrupt line 9
|
||||
\arg DAC_TRIGGER_SOFTWARE: trigger source is software
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_trigger_source_config(uint32_t dac_periph,uint32_t triggersource)
|
||||
{
|
||||
if(DAC0 == dac_periph){
|
||||
DAC_CTL &= ~DAC_CTL_DTSEL0;
|
||||
DAC_CTL |= triggersource;
|
||||
}else{
|
||||
DAC_CTL &= ~DAC_CTL_DTSEL1;
|
||||
DAC_CTL |= (triggersource <<16);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the specified DAC flag(DAC DMA underrun flag)
|
||||
\param[in] dac_periph
|
||||
\arg DACx(x=0,1)
|
||||
\param[out] none
|
||||
\retval the state of dac bit(SET or RESET)
|
||||
*/
|
||||
FlagStatus dac_flag_get(uint32_t dac_periph)
|
||||
{
|
||||
if(DAC0 == dac_periph){
|
||||
/* check the DMA underrun flag */
|
||||
if(RESET != (DAC_STAT & DAC_STAT_DDUDR0)){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}else{
|
||||
/* check the DMA underrun flag */
|
||||
if(RESET != (DAC_STAT & DAC_STAT_DDUDR1)){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear the specified DAC flag(DAC DMA underrun flag)
|
||||
\param[in] dac_periph
|
||||
\arg DACx(x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_flag_clear(uint32_t dac_periph)
|
||||
{
|
||||
if(DAC0 == dac_periph){
|
||||
DAC_STAT |= DAC_STAT_DDUDR0;
|
||||
}else{
|
||||
DAC_STAT |= DAC_STAT_DDUDR1;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the specified DAC interrupt flag(DAC DMA underrun interrupt flag)
|
||||
\param[in] dac_periph
|
||||
\arg DACx(x=0,1)
|
||||
\param[out] none
|
||||
\retval the state of DAC interrupt flag(SET or RESET)
|
||||
*/
|
||||
FlagStatus dac_interrupt_flag_get(uint32_t dac_periph)
|
||||
{
|
||||
uint32_t ddudr_flag = 0U, ddudrie_flag = 0U;
|
||||
if(DAC0 == dac_periph){
|
||||
ddudr_flag = DAC_STAT & DAC_STAT_DDUDR0;
|
||||
ddudrie_flag = DAC_CTL & DAC_CTL_DDUDRIE0;
|
||||
/* check the DMA underrun flag and DAC DMA underrun interrupt enable flag */
|
||||
if((RESET != ddudr_flag) && (RESET != ddudrie_flag)){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}else{
|
||||
ddudr_flag = DAC_STAT & DAC_STAT_DDUDR1;
|
||||
ddudrie_flag = DAC_CTL & DAC_CTL_DDUDRIE1;
|
||||
/* check the DMA underrun flag and DAC DMA underrun interrupt enable flag */
|
||||
if((RESET != ddudr_flag) && (RESET != ddudrie_flag)){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear the specified DAC interrupt flag(DAC DMA underrun interrupt flag)
|
||||
\param[in] dac_periph
|
||||
\arg DACx(x=0,1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_interrupt_flag_clear(uint32_t dac_periph)
|
||||
{
|
||||
if(DAC0 == dac_periph){
|
||||
DAC_STAT |= DAC_STAT_DDUDR0;
|
||||
}else{
|
||||
DAC_STAT |= DAC_STAT_DDUDR1;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DAC concurrent mode
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_concurrent_enable(void)
|
||||
{
|
||||
uint32_t ctl = 0U;
|
||||
ctl = DAC_CTL_DEN0 | DAC_CTL_DEN1;
|
||||
DAC_CTL |= (ctl);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DAC concurrent mode
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_concurrent_disable(void)
|
||||
{
|
||||
uint32_t ctl = 0U;
|
||||
ctl = DAC_CTL_DEN0 | DAC_CTL_DEN1;
|
||||
DAC_CTL &= (~ctl);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DAC concurrent software trigger function
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_concurrent_software_trigger_enable(void)
|
||||
{
|
||||
uint32_t swt = 0U;
|
||||
swt = DAC_SWT_SWTR0 | DAC_SWT_SWTR1;
|
||||
DAC_SWT |= (swt);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DAC concurrent software trigger function
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_concurrent_software_trigger_disable(void)
|
||||
{
|
||||
uint32_t swt = 0U;
|
||||
swt = DAC_SWT_SWTR0 | DAC_SWT_SWTR1;
|
||||
DAC_SWT &= (~swt);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DAC concurrent buffer funcution
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_concurrent_output_buffer_enable(void)
|
||||
{
|
||||
uint32_t ctl = 0U;
|
||||
ctl = DAC_CTL_DBOFF0 | DAC_CTL_DBOFF1;
|
||||
DAC_CTL &= (~ctl);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DAC concurrent buffer funcution
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_concurrent_output_buffer_disable(void)
|
||||
{
|
||||
uint32_t ctl = 0U;
|
||||
ctl = DAC_CTL_DBOFF0 | DAC_CTL_DBOFF1;
|
||||
DAC_CTL |= (ctl);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DAC concurrent interrupt funcution
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_concurrent_interrupt_enable(void)
|
||||
{
|
||||
DAC_CTL |= DAC_CTL_DDUDRIE0;
|
||||
DAC_CTL |= DAC_CTL_DDUDRIE1;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DAC concurrent interrupt funcution
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_concurrent_interrupt_disable(void)
|
||||
{
|
||||
DAC_CTL &= ~DAC_CTL_DDUDRIE0;
|
||||
DAC_CTL &= ~DAC_CTL_DDUDRIE1;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set the DAC specified data holding register value
|
||||
\param[in] dac_periph
|
||||
\arg DACx(x=0,1)
|
||||
\param[in] dac_align
|
||||
\arg DAC_ALIGN_8B_R: data right 8b alignment
|
||||
\arg DAC_ALIGN_12B_R: data right 12b alignment
|
||||
\arg DAC_ALIGN_12B_L: data left 12b alignment
|
||||
\param[in] data: data to be loaded
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_data_set(uint32_t dac_periph, uint32_t dac_align, uint16_t data)
|
||||
{
|
||||
if(DAC0 == dac_periph){
|
||||
switch(dac_align){
|
||||
/* data right 12b alignment */
|
||||
case DAC_ALIGN_12B_R:
|
||||
DAC0_R12DH = data;
|
||||
break;
|
||||
/* data left 12b alignment */
|
||||
case DAC_ALIGN_12B_L:
|
||||
DAC0_L12DH = data;
|
||||
break;
|
||||
/* data right 8b alignment */
|
||||
case DAC_ALIGN_8B_R:
|
||||
DAC0_R8DH = data;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
switch(dac_align){
|
||||
/* data right 12b alignment */
|
||||
case DAC_ALIGN_12B_R:
|
||||
DAC1_R12DH = data;
|
||||
break;
|
||||
/* data left 12b alignment */
|
||||
case DAC_ALIGN_12B_L:
|
||||
DAC1_L12DH = data;
|
||||
break;
|
||||
/* data right 8b alignment */
|
||||
case DAC_ALIGN_8B_R:
|
||||
DAC1_R8DH = data;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set DAC concurrent mode data holding register value
|
||||
\param[in] dac_align
|
||||
\arg DAC_ALIGN_8B_R: data right 8b alignment
|
||||
\arg DAC_ALIGN_12B_R: data right 12b alignment
|
||||
\arg DAC_ALIGN_12B_L: data left 12b alignment
|
||||
\param[in] data1: data to be loaded
|
||||
\param[in] data2: data to be loaded
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dac_concurrent_data_set(uint32_t dac_align, uint16_t data1, uint16_t data2)
|
||||
{
|
||||
uint32_t data = 0U;
|
||||
switch(dac_align){
|
||||
/* data right 12b alignment */
|
||||
case DAC_ALIGN_12B_R:
|
||||
data = ((uint32_t)data2 << 16U) | data1;
|
||||
DACC_R12DH = data;
|
||||
break;
|
||||
/* data left 12b alignment */
|
||||
case DAC_ALIGN_12B_L:
|
||||
data = ((uint32_t)data2 << 16U) | data1;
|
||||
DACC_L12DH = data;
|
||||
break;
|
||||
/* data right 8b alignment */
|
||||
case DAC_ALIGN_8B_R:
|
||||
data = ((uint32_t)data2 << 8U) | data1;
|
||||
DACC_R8DH = data;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* GD32F170_190 */
|
106
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_dbg.c
Normal file
106
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_dbg.c
Normal file
@@ -0,0 +1,106 @@
|
||||
/*!
|
||||
\file gd32f1x0_dbg.c
|
||||
\brief DBG driver
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2017 GigaDevice
|
||||
|
||||
2014-12-26, V1.0.0, platform GD32F1x0(x=3,5)
|
||||
2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9)
|
||||
2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
*/
|
||||
|
||||
#include "gd32f1x0_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: refer to dbg_periph_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DBG_FWDGT_HOLD : debug FWDGT kept when core is halted
|
||||
\arg DBG_WWDGT_HOLD : debug WWDGT kept when core is halted
|
||||
\arg DBG_CANx_HOLD (x=0,1): hold CANx counter when core is halted(170_190 series only)
|
||||
\arg DBG_I2Cx_HOLD (x=0,1,2): hold I2Cx smbus when core is halted
|
||||
\arg DBG_TIMERx_HOLD (x=0,1,2,5,13,14,15,16): hold TIMERx counter when core is halted
|
||||
\arg DBG_RTC_HOLD : hold RTC calendar and wakeup counter when core is halted
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dbg_periph_enable(dbg_periph_enum dbg_periph)
|
||||
{
|
||||
DBG_REG_VAL(dbg_periph) |= BIT(DBG_BIT_POS(dbg_periph));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable peripheral behavior when the mcu is in debug mode
|
||||
\param[in] dbg_periph: refer to dbg_periph_enum
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DBG_FWDGT_HOLD : debug FWDGT kept when core is halted
|
||||
\arg DBG_WWDGT_HOLD : debug WWDGT kept when core is halted
|
||||
\arg DBG_CANx_HOLD (x=0,1): hold CANx counter when core is halted(170_190 series only)
|
||||
\arg DBG_I2Cx_HOLD (x=0,1,2): hold I2Cx smbus when core is halted
|
||||
\arg DBG_TIMERx_HOLD (x=0,1,2,5,13,14,15,16): hold TIMERx counter when core is halted
|
||||
\arg DBG_RTC_HOLD : hold RTC calendar and wakeup counter when core is halted
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dbg_periph_disable(dbg_periph_enum dbg_periph)
|
||||
{
|
||||
DBG_REG_VAL(dbg_periph) &= ~BIT(DBG_BIT_POS(dbg_periph));
|
||||
}
|
492
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_dma.c
Normal file
492
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_dma.c
Normal file
@@ -0,0 +1,492 @@
|
||||
/*!
|
||||
\file gd32f1x0_dma.c
|
||||
\brief DMA driver
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2017 GigaDevice
|
||||
|
||||
2014-12-26, V1.0.0, platform GD32F1x0(x=3,5)
|
||||
2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9)
|
||||
2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
*/
|
||||
|
||||
#include "gd32f1x0_dma.h"
|
||||
|
||||
/*!
|
||||
\brief deinitialize DMA a channel registers
|
||||
\param[in] channelx: specify which DMA channel is deinitialized
|
||||
\arg DMA_CHx(x=0..6)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_deinit(dma_channel_enum channelx)
|
||||
{
|
||||
/* disable DMA a channel */
|
||||
DMA_CHCTL(channelx) &= ~DMA_CHXCTL_CHEN;
|
||||
/* reset DMA channel registers */
|
||||
DMA_CHCTL(channelx) = DMA_CHCTL_RESET_VALUE;
|
||||
DMA_CHCNT(channelx) = DMA_CHCNT_RESET_VALUE;
|
||||
DMA_CHPADDR(channelx) = DMA_CHPADDR_RESET_VALUE;
|
||||
DMA_CHMADDR(channelx) = DMA_CHMADDR_RESET_VALUE;
|
||||
DMA_INTC |= DMA_FLAG_ADD(DMA_CHINTF_RESET_VALUE,channelx);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize DMA channel
|
||||
\param[in] channelx: specify which DMA channel is initialized
|
||||
\arg DMA_CHx(x=0..6)
|
||||
\param[in] init_struct: the data needed to initialize DMA channel
|
||||
periph_addr: peripheral base address
|
||||
periph_width: DMA_PERIPHERAL_WIDTH_8BIT, DMA_PERIPHERAL_WIDTH_16BIT, DMA_PERIPHERAL_WIDTH_32BIT
|
||||
periph_inc: DMA_PERIPH_INCREASE_ENABLE, DMA_PERIPH_INCREASE_DISABLE
|
||||
memory_addr: memory 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
|
||||
direction: DMA_PERIPHERAL_TO_MEMORY, DMA_MEMORY_TO_PERIPHERAL
|
||||
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_init(dma_channel_enum channelx, dma_parameter_struct init_struct)
|
||||
{
|
||||
uint32_t ctl;
|
||||
/* configure peripheral base address */
|
||||
DMA_CHPADDR(channelx) = init_struct.periph_addr;
|
||||
|
||||
/* configure memory base address */
|
||||
DMA_CHMADDR(channelx) = init_struct.memory_addr;
|
||||
|
||||
/* configure the number of remaining data to be transferred */
|
||||
DMA_CHCNT(channelx) = init_struct.number;
|
||||
|
||||
/* configure peripheral transfer width,memory transfer width, */
|
||||
ctl = DMA_CHCTL(channelx);
|
||||
ctl &= ~(DMA_CHXCTL_PWIDTH | DMA_CHXCTL_MWIDTH | DMA_CHXCTL_PRIO);
|
||||
ctl |= (init_struct.periph_width | init_struct.memory_width | init_struct.priority);
|
||||
DMA_CHCTL(channelx)=ctl;
|
||||
|
||||
/* configure peripheral increasing mode */
|
||||
if(DMA_PERIPH_INCREASE_ENABLE == init_struct.periph_inc){
|
||||
DMA_CHCTL(channelx) |= DMA_CHXCTL_PNAGA;
|
||||
}else{
|
||||
DMA_CHCTL(channelx) &= ~DMA_CHXCTL_PNAGA;
|
||||
}
|
||||
|
||||
/* configure memory increasing mode */
|
||||
if(DMA_MEMORY_INCREASE_ENABLE == init_struct.memory_inc){
|
||||
DMA_CHCTL(channelx) |= DMA_CHXCTL_MNAGA;
|
||||
}else{
|
||||
DMA_CHCTL(channelx) &= ~DMA_CHXCTL_MNAGA;
|
||||
}
|
||||
|
||||
/* configure the direction of data transfer */
|
||||
if(DMA_PERIPHERAL_TO_MEMORY == init_struct.direction){
|
||||
DMA_CHCTL(channelx) &= ~DMA_CHXCTL_DIR;
|
||||
}else{
|
||||
DMA_CHCTL(channelx) |= DMA_CHXCTL_DIR;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DMA circulation mode
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..6)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_circulation_enable(dma_channel_enum channelx)
|
||||
{
|
||||
DMA_CHCTL(channelx) |= DMA_CHXCTL_CMEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DMA circulation mode
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..6)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_circulation_disable(dma_channel_enum channelx)
|
||||
{
|
||||
DMA_CHCTL(channelx) &= ~DMA_CHXCTL_CMEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable memory to memory mode
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..6)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_memory_to_memory_enable(dma_channel_enum channelx)
|
||||
{
|
||||
DMA_CHCTL(channelx) |= DMA_CHXCTL_M2M;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable memory to memory mode
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..6)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_memory_to_memory_disable(dma_channel_enum channelx)
|
||||
{
|
||||
DMA_CHCTL(channelx) &= ~DMA_CHXCTL_M2M;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DMA channel
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..6)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_channel_enable(dma_channel_enum channelx)
|
||||
{
|
||||
DMA_CHCTL(channelx) |= DMA_CHXCTL_CHEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DMA channel
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..6)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_channel_disable(dma_channel_enum channelx)
|
||||
{
|
||||
DMA_CHCTL(channelx) &= ~DMA_CHXCTL_CHEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set DMA peripheral base address
|
||||
\param[in] channelx: specify which DMA channel to set peripheral base address
|
||||
\arg DMA_CHx(x=0..6)
|
||||
\param[in] address: peripheral base address
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_periph_address_config(dma_channel_enum channelx, uint32_t address)
|
||||
{
|
||||
DMA_CHPADDR(channelx) = address;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set DMA Memory base address
|
||||
\param[in] channelx: specify which DMA channel to set Memory base address
|
||||
\arg DMA_CHx(x=0..6)
|
||||
\param[in] address: Memory base address
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_memory_address_config(dma_channel_enum channelx, uint32_t address)
|
||||
{
|
||||
DMA_CHMADDR(channelx) = address;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set the number of remaining data to be transferred by the DMA
|
||||
\param[in] channelx: specify which DMA channel to set number
|
||||
\arg DMA_CHx(x=0..6)
|
||||
\param[in] number: the number of remaining data to be transferred by the DMA
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_transfer_number_config(dma_channel_enum channelx, uint32_t number)
|
||||
{
|
||||
DMA_CHCNT(channelx) = number;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the number of remaining data to be transferred by the DMA
|
||||
\param[in] channelx: specify which DMA channel to set number
|
||||
\arg DMA_CHx(x=0..6)
|
||||
\param[out] none
|
||||
\retval uint32_t: the number of remaining data to be transferred by the DMA
|
||||
*/
|
||||
uint32_t dma_transfer_number_get(dma_channel_enum channelx)
|
||||
{
|
||||
return (uint32_t)DMA_CHCNT(channelx);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure priority level of DMA channel
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..6)
|
||||
\param[in] priority: priority Level of this channel
|
||||
\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(dma_channel_enum channelx, uint32_t priority)
|
||||
{
|
||||
uint32_t ctl;
|
||||
/* acquire DMA_CHxCTL register */
|
||||
ctl = DMA_CHCTL(channelx);
|
||||
/* assign regiser */
|
||||
ctl &= ~DMA_CHXCTL_PRIO;
|
||||
ctl |= priority;
|
||||
DMA_CHCTL(channelx) = ctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure transfer data size of memory
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..6)
|
||||
\param[in] msize: transfer data size of memory
|
||||
\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 (dma_channel_enum channelx, uint32_t msize)
|
||||
{
|
||||
uint32_t ctl;
|
||||
/* acquire DMA_CHxCTL register */
|
||||
ctl = DMA_CHCTL(channelx);
|
||||
/* assign regiser */
|
||||
ctl &= ~DMA_CHXCTL_MWIDTH;
|
||||
ctl |= msize;
|
||||
DMA_CHCTL(channelx) = ctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure transfer data size of peripheral
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..6)
|
||||
\param[in] msize: transfer data size of peripheral
|
||||
\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 (dma_channel_enum channelx, uint32_t psize)
|
||||
{
|
||||
uint32_t ctl;
|
||||
/* acquire DMA_CHxCTL register */
|
||||
ctl = DMA_CHCTL(channelx);
|
||||
/* assign regiser */
|
||||
ctl &= ~DMA_CHXCTL_PWIDTH;
|
||||
ctl |= psize;
|
||||
DMA_CHCTL(channelx) = ctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable next address increasement algorithm of memory
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..6)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_memory_increase_enable(dma_channel_enum channelx)
|
||||
{
|
||||
DMA_CHCTL(channelx) |= DMA_CHXCTL_MNAGA;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable next address increasement algorithm of memory
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..6)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_memory_increase_disable(dma_channel_enum channelx)
|
||||
{
|
||||
DMA_CHCTL(channelx) &= ~DMA_CHXCTL_MNAGA;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable next address increasement algorithm of peripheral
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..6)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_periph_increase_enable(dma_channel_enum channelx)
|
||||
{
|
||||
DMA_CHCTL(channelx) |= DMA_CHXCTL_PNAGA;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable next address increasement algorithm of peripheral
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..6)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_periph_increase_disable(dma_channel_enum channelx)
|
||||
{
|
||||
DMA_CHCTL(channelx) &= ~DMA_CHXCTL_PNAGA;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the direction of data transfer on the channel
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..6)
|
||||
\param[in] direction: specify the direction of data transfer
|
||||
\arg DMA_PERIPHERAL_TO_MEMORY: read from peripheral and write to memory
|
||||
\arg DMA_MEMORY_TO_PERIPHERAL: read from memory and write to peripheral
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_transfer_direction_config(dma_channel_enum channelx, uint8_t direction)
|
||||
{
|
||||
if(DMA_PERIPHERAL_TO_MEMORY == direction){
|
||||
DMA_CHCTL(channelx) &= ~DMA_CHXCTL_DIR;
|
||||
} else {
|
||||
DMA_CHCTL(channelx) |= DMA_CHXCTL_DIR;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief check DMA flag and interrupt enable bit is set or not
|
||||
\param[in] channelx: specify which DMA channel to get flag
|
||||
\arg DMA_CHx(x=0..6)
|
||||
\param[in] flag: specify get which flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DMA_INT_FLAG_G: global interrupt flag of channel
|
||||
\arg DMA_INT_FLAG_FTF: full transfer finish interrupt flag of channel
|
||||
\arg DMA_INT_FLAG_HTF: half transfer finish interrupt flag of channel
|
||||
\arg DMA_INT_FLAG_ERR: error interrupt flag of channel
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus dma_interrupt_flag_get(dma_channel_enum channelx, uint32_t flag)
|
||||
{
|
||||
uint32_t interrupt_enable = 0U, interrupt_flag = 0U;
|
||||
uint32_t gif_check = 0x0FU, gif_enable = 0x0EU;
|
||||
|
||||
switch(flag){
|
||||
case DMA_INT_FLAG_FTF:
|
||||
interrupt_flag = DMA_INTF & DMA_FLAG_ADD(flag, channelx);
|
||||
interrupt_flag = interrupt_flag >> ((channelx) * 4U);
|
||||
interrupt_enable = DMA_CHCTL(channelx) & DMA_CHXCTL_FTFIE;
|
||||
break;
|
||||
case DMA_INT_FLAG_HTF:
|
||||
interrupt_flag = DMA_INTF & DMA_FLAG_ADD(flag, channelx);
|
||||
interrupt_flag = interrupt_flag >> ((channelx) * 4U);
|
||||
interrupt_enable = DMA_CHCTL(channelx) & DMA_CHXCTL_HTFIE;
|
||||
break;
|
||||
case DMA_INT_FLAG_ERR:
|
||||
interrupt_flag = DMA_INTF & DMA_FLAG_ADD(flag, channelx);
|
||||
interrupt_flag = interrupt_flag >> ((channelx) * 4U);
|
||||
interrupt_enable = DMA_CHCTL( channelx) & DMA_CHXCTL_ERRIE;
|
||||
break;
|
||||
case DMA_INT_FLAG_G:
|
||||
interrupt_flag = DMA_INTF & DMA_FLAG_ADD(gif_check, channelx);
|
||||
interrupt_flag = interrupt_flag >> ((channelx) * 4U);
|
||||
interrupt_enable = DMA_CHCTL(channelx) & gif_enable;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(interrupt_flag & interrupt_enable){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear DMA a channel flag
|
||||
\param[in] channelx: specify which DMA channel to clear flag
|
||||
\arg DMA_CHx(x=0..6)
|
||||
\param[in] flag: specify get which flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DMA_INT_FLAG_G: global interrupt flag of channel
|
||||
\arg DMA_INT_FLAG_FTF: full transfer finish interrupt flag of channel
|
||||
\arg DMA_INT_FLAG_HTF: half transfer finish interrupt flag of channel
|
||||
\arg DMA_INT_FLAG_ERR: error interrupt flag of channel
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_interrupt_flag_clear(dma_channel_enum channelx, uint32_t flag)
|
||||
{
|
||||
DMA_INTC |= DMA_FLAG_ADD(flag, channelx);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable DMA interrupt
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..6)
|
||||
\param[in] source: specify which interrupt to enbale
|
||||
\arg DMA_INT_ERR: channel error interrupt
|
||||
\arg DMA_INT_HTF: channel transfer half complete interrupt
|
||||
\arg DMA_INT_FTF: channel transfer complete interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_interrupt_enable(dma_channel_enum channelx, uint32_t source)
|
||||
{
|
||||
DMA_CHCTL(channelx) |= source;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable DMA interrupt
|
||||
\param[in] channelx: specify which DMA channel
|
||||
\arg DMA_CHx(x=0..6)
|
||||
\param[in] source: specify which interrupt to disbale
|
||||
\arg DMA_INT_ERR: channel error interrupt
|
||||
\arg DMA_INT_HTF: channel transfer half complete interrupt
|
||||
\arg DMA_INT_FTF: for channel transfer complete interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_interrupt_disable(dma_channel_enum channelx, uint32_t source)
|
||||
{
|
||||
DMA_CHCTL(channelx) &= ~source;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief check DMA flag is set or not
|
||||
\param[in] channelx: specify which DMA channel to get flag
|
||||
\arg DMA_CHx(x=0..6)
|
||||
\param[in] flag: specify get which flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DMA_FLAG_G: global interrupt flag of channel
|
||||
\arg DMA_FLAG_FTF: full transfer finish flag of channel
|
||||
\arg DMA_FLAG_HTF: half transfer finish flag of channel
|
||||
\arg DMA_FLAG_ERR: error flag of channel
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus dma_flag_get(dma_channel_enum channelx, uint32_t flag)
|
||||
{
|
||||
FlagStatus reval;
|
||||
|
||||
if(RESET != (DMA_INTF & DMA_FLAG_ADD(flag, channelx))){
|
||||
reval = SET;
|
||||
}else{
|
||||
reval = RESET;
|
||||
}
|
||||
|
||||
return reval;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear DMA a channel flag
|
||||
\param[in] channelx: specify which DMA channel to clear flag
|
||||
\arg DMA_CHx(x=0..6)
|
||||
\param[in] flag: specify get which flag
|
||||
only one parameter can be selected which is shown as below:
|
||||
\arg DMA_FLAG_G: global interrupt flag of channel
|
||||
\arg DMA_FLAG_FTF: full transfer finish flag of channel
|
||||
\arg DMA_FLAG_HTF: half transfer finish flag of channel
|
||||
\arg DMA_FLAG_ERR: error flag of channel
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dma_flag_clear(dma_channel_enum channelx, uint32_t flag)
|
||||
{
|
||||
DMA_INTC |= DMA_FLAG_ADD(flag, channelx);
|
||||
}
|
247
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_exti.c
Normal file
247
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_exti.c
Normal file
@@ -0,0 +1,247 @@
|
||||
/*!
|
||||
\file gd32f1x0_exti.c
|
||||
\brief EXTI driver
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2017 GigaDevice
|
||||
|
||||
2014-12-26, V1.0.0, platform GD32F1x0(x=3,5)
|
||||
2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9)
|
||||
2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
*/
|
||||
|
||||
#include "gd32f1x0_exti.h"
|
||||
|
||||
#define EXTI_INTEN_RESET_VAL 0x0F900000U
|
||||
#define EXTI_EVEN_RESET_VAL 0x00000000U
|
||||
#define EXTI_RTEN_RESET_VAL 0x00000000U
|
||||
#define EXTI_FTEN_RESET_VAL 0x00000000U
|
||||
#define EXTI_SWIEV_RESET_VAL 0x00000000U
|
||||
|
||||
/*!
|
||||
\brief deinitialize the EXTI
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exti_deinit(void)
|
||||
{
|
||||
/* reset the value of the EXTI registers */
|
||||
EXTI_INTEN = EXTI_INTEN_RESET_VAL;
|
||||
EXTI_EVEN = EXTI_EVEN_RESET_VAL;
|
||||
EXTI_RTEN = EXTI_RTEN_RESET_VAL;
|
||||
EXTI_FTEN = EXTI_FTEN_RESET_VAL;
|
||||
EXTI_SWIEV = EXTI_SWIEV_RESET_VAL;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the EXTI
|
||||
\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..19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices)
|
||||
\arg EXTI_x (x=0..17,19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices)
|
||||
\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
|
||||
\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;
|
||||
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..19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices)
|
||||
\arg EXTI_x (x=0..17,19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exti_interrupt_enable(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..19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices)
|
||||
\arg EXTI_x (x=0..17,19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exti_event_enable(exti_line_enum linex)
|
||||
{
|
||||
EXTI_EVEN |= (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..19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices)
|
||||
\arg EXTI_x (x=0..17,19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exti_interrupt_disable(exti_line_enum linex)
|
||||
{
|
||||
EXTI_INTEN &= ~(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..19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices)
|
||||
\arg EXTI_x (x=0..17,19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exti_event_disable(exti_line_enum linex)
|
||||
{
|
||||
EXTI_EVEN &= ~(uint32_t)linex;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get EXTI lines 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..19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices)
|
||||
\arg EXTI_x (x=0..17,19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices)
|
||||
\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 lines 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..19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices)
|
||||
\arg EXTI_x (x=0..17,19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exti_flag_clear(exti_line_enum linex)
|
||||
{
|
||||
EXTI_PD = (uint32_t)linex;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get EXTI lines flag when the interrupt flag is set
|
||||
\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..19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices)
|
||||
\arg EXTI_x (x=0..17,19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices)
|
||||
\param[out] none
|
||||
\retval FlagStatus: status of flag (RESET or SET)
|
||||
*/
|
||||
FlagStatus exti_interrupt_flag_get(exti_line_enum linex)
|
||||
{
|
||||
uint32_t flag_left, flag_right;
|
||||
flag_left = EXTI_PD & (uint32_t)linex;
|
||||
flag_right = EXTI_INTEN & (uint32_t)linex;
|
||||
if((RESET != flag_left) && (RESET != flag_right)){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear EXTI lines 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..19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices)
|
||||
\arg EXTI_x (x=0..17,19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exti_interrupt_flag_clear(exti_line_enum linex)
|
||||
{
|
||||
EXTI_PD = (uint32_t)linex;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable EXTI software interrupt event
|
||||
\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..19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices)
|
||||
\arg EXTI_x (x=0..17,19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exti_software_interrupt_enable(exti_line_enum linex)
|
||||
{
|
||||
EXTI_SWIEV |= (uint32_t)linex;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable EXTI software interrupt event
|
||||
\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..19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices)
|
||||
\arg EXTI_x (x=0..17,19,21,22,25,27): EXTI line x (for GD32F130xx and GD32F150xx devices)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void exti_software_interrupt_disable(exti_line_enum linex)
|
||||
{
|
||||
EXTI_SWIEV &= ~(uint32_t)linex;
|
||||
}
|
664
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_fmc.c
Normal file
664
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_fmc.c
Normal file
@@ -0,0 +1,664 @@
|
||||
/*!
|
||||
\file gd32f1x0_fmc.c
|
||||
\brief FMC driver
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2017 GigaDevice
|
||||
|
||||
2014-12-26, V1.0.0, platform GD32F1x0(x=3,5)
|
||||
2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9)
|
||||
2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
*/
|
||||
|
||||
#include "gd32f1x0_fmc.h"
|
||||
|
||||
/* FMC main memory programming functions */
|
||||
|
||||
/*!
|
||||
\brief unlock the main FMC operation
|
||||
it is better to used in pairs with fmc_lock
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fmc_unlock(void)
|
||||
{
|
||||
if((RESET != (FMC_CTL & FMC_CTL_LK))){
|
||||
/* write the FMC key */
|
||||
FMC_KEY = UNLOCK_KEY0;
|
||||
FMC_KEY = UNLOCK_KEY1;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief lock the main FMC operation
|
||||
it is better to used in pairs with fmc_unlock after an operation
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fmc_lock(void)
|
||||
{
|
||||
/* set the LK bit*/
|
||||
FMC_CTL |= FMC_CTL_LK;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set the wait state counter value
|
||||
\param[in] wscnt: wait state counter value
|
||||
\arg WS_WSCNT_0: 0 wait state added
|
||||
\arg WS_WSCNT_1: 1 wait state added
|
||||
\arg WS_WSCNT_2: 2 wait state added
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fmc_wscnt_set(uint8_t wscnt)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
reg = FMC_WS;
|
||||
/* set the wait state counter value */
|
||||
reg &= ~FMC_WS_WSCNT;
|
||||
FMC_WS = (reg | wscnt);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief fmc wait state enable
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fmc_wait_state_enable(void)
|
||||
{
|
||||
/* unlock the main flash */
|
||||
fmc_unlock();
|
||||
|
||||
/* set the WSEN bit in register FMC_WSEN */
|
||||
FMC_WSEN |= FMC_WSEN_WSEN;
|
||||
|
||||
/* lock the main flash after operation */
|
||||
fmc_lock();
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief fmc wait state disable
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fmc_wait_state_disable(void)
|
||||
{
|
||||
/* unlock the main flash */
|
||||
fmc_unlock();
|
||||
|
||||
/* reset the WSEN bit in register FMC_WSEN */
|
||||
FMC_WSEN &= ~FMC_WSEN_WSEN;
|
||||
|
||||
/* lock the main flash after operation */
|
||||
fmc_lock();
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief erase page
|
||||
\param[in] page_address: target page start address
|
||||
\param[out] none
|
||||
\retval fmc_state
|
||||
*/
|
||||
fmc_state_enum fmc_page_erase(uint32_t page_address)
|
||||
{
|
||||
fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
|
||||
|
||||
if(FMC_READY == fmc_state){
|
||||
/* start page erase */
|
||||
FMC_CTL |= FMC_CTL_PER;
|
||||
FMC_ADDR = page_address;
|
||||
FMC_CTL |= FMC_CTL_START;
|
||||
|
||||
/* wait for the FMC ready */
|
||||
fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
|
||||
|
||||
/* reset the PER bit */
|
||||
FMC_CTL &= ~FMC_CTL_PER;
|
||||
}
|
||||
|
||||
/* return the FMC state */
|
||||
return fmc_state;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief erase whole chip
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval fmc_state
|
||||
*/
|
||||
fmc_state_enum fmc_mass_erase(void)
|
||||
{
|
||||
fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
|
||||
|
||||
if(FMC_READY == fmc_state){
|
||||
/* start chip erase */
|
||||
FMC_CTL |= FMC_CTL_MER;
|
||||
FMC_CTL |= FMC_CTL_START;
|
||||
|
||||
/* wait for the FMC ready */
|
||||
fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
|
||||
|
||||
/* reset the MER bit */
|
||||
FMC_CTL &= ~FMC_CTL_MER;
|
||||
}
|
||||
|
||||
/* return the fmc state */
|
||||
return fmc_state;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief program a word at the corresponding address
|
||||
\param[in] address: address to program
|
||||
\param[in] data: word to program
|
||||
\param[out] none
|
||||
\retval fmc_state
|
||||
*/
|
||||
fmc_state_enum fmc_word_program(uint32_t address, uint32_t data)
|
||||
{
|
||||
fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
|
||||
|
||||
if(FMC_READY == fmc_state){
|
||||
/* set the PG bit to start program */
|
||||
FMC_CTL |= FMC_CTL_PG;
|
||||
|
||||
REG32(address) = data;
|
||||
|
||||
/* wait for the FMC ready */
|
||||
fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
|
||||
|
||||
/* reset the PG bit */
|
||||
FMC_CTL &= ~FMC_CTL_PG;
|
||||
}
|
||||
|
||||
/* return the FMC state */
|
||||
return fmc_state;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief program a half word at the corresponding address
|
||||
\param[in] address: address to program
|
||||
\param[in] data: word to program
|
||||
\param[out] none
|
||||
\retval fmc_state
|
||||
*/
|
||||
fmc_state_enum fmc_halfword_program(uint32_t address, uint16_t data)
|
||||
{
|
||||
fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
|
||||
|
||||
if(FMC_READY == fmc_state){
|
||||
/* set the PG bit to start program */
|
||||
FMC_CTL |= FMC_CTL_PG;
|
||||
|
||||
REG16(address) = data;
|
||||
|
||||
/* wait for the FMC ready */
|
||||
fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
|
||||
|
||||
/* reset the PG bit */
|
||||
FMC_CTL &= ~FMC_CTL_PG;
|
||||
}
|
||||
|
||||
/* return the FMC state */
|
||||
return fmc_state;
|
||||
}
|
||||
|
||||
#ifdef GD32F170_190
|
||||
/*!
|
||||
\brief program a word at the corresponding address without erasing
|
||||
\param[in] address: address to program
|
||||
\param[in] data: word to program
|
||||
\param[out] none
|
||||
\retval fmc_state
|
||||
*/
|
||||
fmc_state_enum fmc_word_reprogram(uint32_t address, uint32_t data)
|
||||
{
|
||||
fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
|
||||
FMC_WSEN |= FMC_WSEN_BPEN;
|
||||
|
||||
if(FMC_READY == fmc_state){
|
||||
/* set the PG bit to start program */
|
||||
FMC_CTL |= FMC_CTL_PG;
|
||||
|
||||
REG32(address) = data;
|
||||
|
||||
/* wait for the FMC ready */
|
||||
fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
|
||||
|
||||
/* reset the PG bit */
|
||||
FMC_CTL &= ~FMC_CTL_PG;
|
||||
}
|
||||
|
||||
/* return the FMC state */
|
||||
return fmc_state;
|
||||
}
|
||||
#endif /* GD32F170_190 */
|
||||
|
||||
/* FMC option bytes programming functions */
|
||||
|
||||
/*!
|
||||
\brief unlock the option byte operation
|
||||
it is better to used in pairs with ob_lock
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ob_unlock(void)
|
||||
{
|
||||
if(RESET == (FMC_CTL & FMC_CTL_OBWEN)){
|
||||
/* write the FMC key */
|
||||
FMC_OBKEY = UNLOCK_KEY0;
|
||||
FMC_OBKEY = UNLOCK_KEY1;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief lock the option byte operation
|
||||
it is better to used in pairs with ob_unlock after an operation
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ob_lock(void)
|
||||
{
|
||||
/* reset the OBWE bit */
|
||||
FMC_CTL &= ~FMC_CTL_OBWEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief reload the option byte and generate a system reset
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ob_reset(void)
|
||||
{
|
||||
/* set the OBRLD bit */
|
||||
FMC_CTL |= FMC_CTL_OBRLD;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief erase the option byte
|
||||
programmer must ensure FMC & option byte are both unlocked before calling this function
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval fmc_state
|
||||
*/
|
||||
fmc_state_enum ob_erase(void)
|
||||
{
|
||||
uint16_t fmc_spc;
|
||||
uint32_t fmc_plevel = ob_obstat_plevel_get();
|
||||
fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
|
||||
|
||||
/* get the original option byte security protection code */
|
||||
if(OB_OBSTAT_PLEVEL_NO == fmc_plevel){
|
||||
fmc_spc = FMC_NSPC;
|
||||
}else if(OB_OBSTAT_PLEVEL_LOW == fmc_plevel){
|
||||
fmc_spc = FMC_LSPC;
|
||||
}else{
|
||||
fmc_spc = FMC_HSPC;
|
||||
fmc_state = FMC_OB_HSPC;
|
||||
}
|
||||
|
||||
if(FMC_READY == fmc_state){
|
||||
/* start erase the option byte */
|
||||
FMC_CTL |= FMC_CTL_OBER;
|
||||
FMC_CTL |= FMC_CTL_START;
|
||||
|
||||
/* wait for the FMC ready */
|
||||
fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
|
||||
|
||||
if(FMC_READY == fmc_state){
|
||||
/* reset the OBER bit */
|
||||
FMC_CTL &= ~FMC_CTL_OBER;
|
||||
|
||||
/* set the OBPG bit */
|
||||
FMC_CTL |= FMC_CTL_OBPG;
|
||||
|
||||
/* restore the last get option byte security protection code */
|
||||
OB_SPC = fmc_spc;
|
||||
|
||||
/* wait for the FMC ready */
|
||||
fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
|
||||
|
||||
if(FMC_TOERR != fmc_state){
|
||||
/* reset the OBPG bit */
|
||||
FMC_CTL &= ~FMC_CTL_OBPG;
|
||||
}
|
||||
}else{
|
||||
if(FMC_TOERR != fmc_state){
|
||||
/* reset the OBPG bit */
|
||||
FMC_CTL &= ~FMC_CTL_OBPG;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* return the FMC state */
|
||||
return fmc_state;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable option byte write protection (OB_WP)
|
||||
\param[in] ob_wp: write protection configuration data
|
||||
\param[out] none
|
||||
\retval fmc_state
|
||||
*/
|
||||
fmc_state_enum ob_write_protection_enable(uint32_t ob_wp)
|
||||
{
|
||||
uint16_t ob_wrp0, ob_wrp1;
|
||||
|
||||
fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
|
||||
|
||||
ob_wp = (uint32_t)(~ob_wp);
|
||||
ob_wrp0 = (uint16_t)(ob_wp & OB_LWP);
|
||||
ob_wrp1 = (uint16_t)((ob_wp & OB_HWP) >> 8);
|
||||
|
||||
if(FMC_READY == fmc_state){
|
||||
/* set the OBPG bit*/
|
||||
FMC_CTL |= FMC_CTL_OBPG;
|
||||
|
||||
if(0xFFU != ob_wrp0){
|
||||
OB_WP0 = ob_wrp0;
|
||||
|
||||
/* wait for the FMC ready */
|
||||
fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
|
||||
}
|
||||
if((FMC_READY == fmc_state) && (0xFFU != ob_wrp1)){
|
||||
OB_WP1 = ob_wrp1;
|
||||
|
||||
/* wait for the FMC ready */
|
||||
fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
|
||||
}
|
||||
if(FMC_TOERR != fmc_state){
|
||||
/* reset the OBPG bit */
|
||||
FMC_CTL &= ~FMC_CTL_OBPG;
|
||||
}
|
||||
}
|
||||
/* return the FMC state */
|
||||
return fmc_state;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure security protection
|
||||
\param[in] ob_spc: specify security protection code
|
||||
\arg FMC_NSPC: no security protection
|
||||
\arg FMC_LSPC: low security protection
|
||||
\arg FMC_HSPC: high security protection
|
||||
\param[out] none
|
||||
\retval fmc_state
|
||||
*/
|
||||
fmc_state_enum ob_security_protection_config(uint8_t ob_spc)
|
||||
{
|
||||
fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
|
||||
|
||||
/* the OB_SPC byte cannot be reprogrammed if protection level is high */
|
||||
if(OB_OBSTAT_PLEVEL_HIGH == ob_obstat_plevel_get()){
|
||||
fmc_state = FMC_OB_HSPC;
|
||||
}
|
||||
|
||||
if(FMC_READY == fmc_state){
|
||||
/* start erase the option byte */
|
||||
FMC_CTL |= FMC_CTL_OBER;
|
||||
FMC_CTL |= FMC_CTL_START;
|
||||
|
||||
/* wait for the FMC ready */
|
||||
fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
|
||||
|
||||
if(FMC_READY == fmc_state){
|
||||
|
||||
/* reset the OBER bit */
|
||||
FMC_CTL &= ~FMC_CTL_OBER;
|
||||
|
||||
/* enable the option bytes programming */
|
||||
FMC_CTL |= FMC_CTL_OBPG;
|
||||
|
||||
OB_SPC = ob_spc;
|
||||
|
||||
/* wait for the FMC ready */
|
||||
fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
|
||||
|
||||
if(FMC_TOERR != fmc_state){
|
||||
/* reset the OBPG bit */
|
||||
FMC_CTL &= ~FMC_CTL_OBPG;
|
||||
}
|
||||
}else{
|
||||
if(FMC_TOERR != fmc_state){
|
||||
/* reset the OBER bit */
|
||||
FMC_CTL &= ~FMC_CTL_OBER;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* return the FMC state */
|
||||
return fmc_state;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief program the FMC user option byte
|
||||
\param[in] ob_user: user option byte
|
||||
\arg OB_FWDGT_SW: software free watchdog timer
|
||||
\arg OB_FWDGT_HW: hardware free watchdog timer
|
||||
\arg OB_DEEPSLEEP_NRST: generate a reset instead of entering deepsleep mode
|
||||
\arg OB_DEEPSLEEP_RST: no reset when entering deepsleep mode
|
||||
\arg OB_STDBY_NRST: generate a reset instead of entering standby mode
|
||||
\arg OB_STDBY_RST: no reset when entering deepsleep mode
|
||||
\arg OB_BOOT1_SET_1: BOOT1 bit is 1
|
||||
\arg OB_BOOT1_SET_0: BOOT1 bit is 0
|
||||
\arg OB_VDDA_DISABLE: disable VDDA monitor
|
||||
\arg OB_VDDA_ENABLE: enable VDDA monitor
|
||||
\arg OB_SRAM_PARITY_DISABLE: disable sram parity check
|
||||
\arg OB_SRAM_PARITY_ENABLE: enable sram parity check
|
||||
\param[out] none
|
||||
\retval fmc_state
|
||||
*/
|
||||
fmc_state_enum ob_user_write(uint8_t ob_user)
|
||||
{
|
||||
fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
|
||||
|
||||
if(FMC_READY == fmc_state){
|
||||
/* set the OBPG bit */
|
||||
FMC_CTL |= FMC_CTL_OBPG;
|
||||
|
||||
OB_USER = (uint8_t)(ob_user | OB_USER_MASK);
|
||||
|
||||
/* wait for the FMC ready */
|
||||
fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
|
||||
|
||||
if(FMC_TOERR != fmc_state){
|
||||
/* reset the OBPG bit */
|
||||
FMC_CTL &= ~FMC_CTL_OBPG;
|
||||
}
|
||||
}
|
||||
/* return the FMC state */
|
||||
return fmc_state;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief program the FMC data option byte
|
||||
\param[in] address: OB_DATA_ADDR0 or OB_DATA_ADDR1
|
||||
\arg OB_DATA_ADDR0: option byte data address 0
|
||||
\arg OB_DATA_ADDR1: option byte data address 1
|
||||
\param[in] data: the byte to be programmed
|
||||
\param[out] none
|
||||
\retval fmc_state
|
||||
*/
|
||||
fmc_state_enum ob_data_program(uint32_t address, uint8_t data)
|
||||
{
|
||||
fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
|
||||
|
||||
if(FMC_READY == fmc_state){
|
||||
/* set the OBPG bit */
|
||||
FMC_CTL |= FMC_CTL_OBPG;
|
||||
REG16(address) = data;
|
||||
|
||||
/* wait for the FMC ready */
|
||||
fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT);
|
||||
|
||||
if(FMC_TOERR != fmc_state){
|
||||
/* reset the OBPG bit */
|
||||
FMC_CTL &= ~FMC_CTL_OBPG;
|
||||
}
|
||||
}
|
||||
/* return the FMC state */
|
||||
return fmc_state;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get OB_USER in register FMC_OBSTAT
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval ob_user
|
||||
*/
|
||||
uint8_t ob_user_get(void)
|
||||
{
|
||||
return (uint8_t)(FMC_OBSTAT >> 8);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get OB_DATA in register FMC_OBSTAT
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval ob_data
|
||||
*/
|
||||
uint16_t ob_data_get(void)
|
||||
{
|
||||
return (uint16_t)(FMC_OBSTAT >> 16);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the FMC option byte write protection (OB_WP) in register FMC_WP
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval OB_WP
|
||||
*/
|
||||
uint16_t ob_write_protection_get(void)
|
||||
{
|
||||
return (uint16_t)(FMC_WP);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the value of FMC option byte security protection level (PLEVEL) in FMC_OBSTAT register
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval the value of PLEVEL
|
||||
*/
|
||||
uint32_t ob_obstat_plevel_get(void)
|
||||
{
|
||||
return (FMC_OBSTAT & (FMC_OBSTAT_PLVL_BIT0 | FMC_OBSTAT_PLVL_BIT1));
|
||||
}
|
||||
|
||||
/* FMC interrupts and flags management functions */
|
||||
/*!
|
||||
\brief enable FMC interrupt
|
||||
\param[in] interrupt: the FMC interrupt source
|
||||
\arg FMC_INTEN_END: FMC end of operation interrupt
|
||||
\arg FMC_INTEN_ERR: FMC error interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fmc_interrupt_enable(uint32_t interrupt)
|
||||
{
|
||||
FMC_CTL |= interrupt;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable FMC interrupt
|
||||
\param[in] interrupt: the FMC interrupt source
|
||||
\arg FMC_INTEN_END: FMC end of operation interrupt
|
||||
\arg FMC_INTEN_ERR: FMC error interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fmc_interrupt_disable(uint32_t interrupt)
|
||||
{
|
||||
FMC_CTL &= ~(uint32_t)interrupt;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get flag set or reset
|
||||
\param[in] flag: check FMC flag
|
||||
\arg FMC_FLAG_BUSY: FMC busy flag
|
||||
\arg FMC_FLAG_PGERR: FMC programming error flag
|
||||
\arg FMC_FLAG_WPERR: FMC write protection error flag
|
||||
\arg FMC_FLAG_END: FMC end of programming flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus fmc_flag_get(uint32_t flag)
|
||||
{
|
||||
FlagStatus status = RESET;
|
||||
|
||||
if(FMC_STAT & flag){
|
||||
status = SET;
|
||||
}
|
||||
/* return the state of corresponding FMC flag */
|
||||
return status;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear the FMC pending flag by writing 1
|
||||
\param[in] flag: clear FMC flag
|
||||
\arg FMC_FLAG_PGERR: FMC programming error flag
|
||||
\arg FMC_FLAG_WPERR: FMC write protection error flag
|
||||
\arg FMC_FLAG_END: fmc end of programming flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fmc_flag_clear(uint32_t flag)
|
||||
{
|
||||
/* clear the flags */
|
||||
FMC_STAT = flag;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the FMC state
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval fmc_state
|
||||
*/
|
||||
fmc_state_enum fmc_state_get(void)
|
||||
{
|
||||
fmc_state_enum fmc_state = FMC_READY;
|
||||
|
||||
if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_BUSY)){
|
||||
fmc_state = FMC_BUSY;
|
||||
}else{
|
||||
if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_WPERR)){
|
||||
fmc_state = FMC_WPERR;
|
||||
}else{
|
||||
if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_PGERR)){
|
||||
fmc_state = FMC_PGERR;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* return the FMC state */
|
||||
return fmc_state;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief check whether FMC is ready or not
|
||||
\param[in] timeout: timeout count
|
||||
\param[out] none
|
||||
\retval fmc_state
|
||||
*/
|
||||
fmc_state_enum fmc_ready_wait(uint32_t timeout)
|
||||
{
|
||||
fmc_state_enum fmc_state = FMC_BUSY;
|
||||
|
||||
/* wait for FMC ready */
|
||||
do{
|
||||
/* get FMC state */
|
||||
fmc_state = fmc_state_get();
|
||||
timeout--;
|
||||
}while((FMC_BUSY == fmc_state) && (0U != timeout));
|
||||
|
||||
if(FMC_BUSY == fmc_state){
|
||||
fmc_state = FMC_TOERR;
|
||||
}
|
||||
/* return the FMC state */
|
||||
return fmc_state;
|
||||
}
|
146
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_fwdgt.c
Normal file
146
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_fwdgt.c
Normal file
@@ -0,0 +1,146 @@
|
||||
/*!
|
||||
\file gd32f1x0_fwdgt.c
|
||||
\brief FWDGT driver
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2017 GigaDevice
|
||||
|
||||
2014-12-26, V1.0.0, platform GD32F1x0(x=3,5)
|
||||
2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9)
|
||||
2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
*/
|
||||
|
||||
#include "gd32f1x0_fwdgt.h"
|
||||
|
||||
/*!
|
||||
\brief disable write access to FWDGT_PSC,FWDGT_RLD and FWDGT_WND
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fwdgt_write_disable(void)
|
||||
{
|
||||
FWDGT_CTL = FWDGT_WRITEACCESS_DISABLE;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief reload the counter of FWDGT
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void fwdgt_counter_reload(void)
|
||||
{
|
||||
FWDGT_CTL = FWDGT_KEY_RELOAD;
|
||||
}
|
||||
|
||||
/*!
|
||||
\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 window value
|
||||
\param[in] window_value: specify window value(0x0000 - 0x0FFF)
|
||||
\param[out] none
|
||||
\retval ErrStatus: ERROR or SUCCESS
|
||||
*/
|
||||
ErrStatus fwdgt_window_value_config(uint16_t window_value)
|
||||
{
|
||||
uint32_t time_index = FWDGT_WND_TIMEOUT;
|
||||
uint32_t flag_status = RESET;
|
||||
|
||||
/* enable write access to FWDGT_WND */
|
||||
FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE;
|
||||
|
||||
/* wait until the WUD flag to be reset */
|
||||
do{
|
||||
flag_status = FWDGT_STAT & FWDGT_STAT_WUD;
|
||||
}while((--time_index > 0U) && ((uint32_t)RESET != flag_status));
|
||||
|
||||
if ((uint32_t)RESET != flag_status){
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
FWDGT_WND = WND_WND(window_value);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\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
|
||||
\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
|
||||
\arg FWDGT_FLAG_PUD: a write operation to FWDGT_PSC register is on going
|
||||
\arg FWDGT_FLAG_RUD: a write operation to FWDGT_RLD register is on going
|
||||
\arg FWDGT_FLAG_WUD: a write operation to FWDGT_WND register is on going
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus fwdgt_flag_get(uint16_t flag)
|
||||
{
|
||||
if(FWDGT_STAT & flag){
|
||||
return SET;
|
||||
}
|
||||
|
||||
return RESET;
|
||||
}
|
337
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_gpio.c
Normal file
337
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_gpio.c
Normal file
@@ -0,0 +1,337 @@
|
||||
/*!
|
||||
\file gd32f1x0_gpio.c
|
||||
\brief GPIO driver
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2017 GigaDevice
|
||||
|
||||
2014-12-26, V1.0.0, platform for GD32F1x0(x=3,5)
|
||||
2016-01-15, V2.0.0, platform for GD32F1x0(x=3,5,7,9)
|
||||
2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
*/
|
||||
|
||||
#include "gd32f1x0_gpio.h"
|
||||
|
||||
/*!
|
||||
\brief reset GPIO port
|
||||
\param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
|
||||
\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 GPIOF:
|
||||
/* reset GPIOF */
|
||||
rcu_periph_reset_enable(RCU_GPIOFRST);
|
||||
rcu_periph_reset_disable(RCU_GPIOFRST);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set GPIO output mode
|
||||
\param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
|
||||
\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: without weak pull-up and pull-down resistors
|
||||
\arg GPIO_PUPD_PULLUP: with weak pull-up resistor
|
||||
\arg GPIO_PUPD_PULLDOWN:with weak pull-down resistor
|
||||
\param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void gpio_mode_set(uint32_t gpio_periph,uint32_t mode,uint32_t pull_up_down,uint32_t pin)
|
||||
{
|
||||
uint16_t i;
|
||||
uint32_t ctl, pupd;
|
||||
|
||||
ctl = GPIO_CTL(gpio_periph);
|
||||
pupd = GPIO_PUD(gpio_periph);
|
||||
|
||||
for (i = 0U; i < 16U; i++){
|
||||
if((1U << i) & pin){
|
||||
/* clear the specified pin mode bits */
|
||||
ctl &= ~GPIO_MODE_MASK(i);
|
||||
/* set the specified pin mode bits */
|
||||
ctl |= GPIO_MODE_SET(i, mode);
|
||||
|
||||
/* clear the specified pin pupd bits */
|
||||
pupd &= ~GPIO_PUPD_MASK(i);
|
||||
/* set the specified pin pupd bits */
|
||||
pupd |= GPIO_PUPD_SET(i, pull_up_down);
|
||||
}
|
||||
}
|
||||
|
||||
GPIO_CTL(gpio_periph) = ctl;
|
||||
GPIO_PUD(gpio_periph) = pupd;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set GPIO output type and speed
|
||||
\param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
|
||||
\param[in] otype: gpio pin output mode
|
||||
\arg GPIO_OTYPE_PP: push pull mode
|
||||
\arg GPIO_OTYPE_OD: open drain mode
|
||||
\param[in] speed
|
||||
\arg GPIO_OSPEED_2MHZ: output max speed 2M
|
||||
\arg GPIO_OSPEED_10MHZ: output max speed 10M
|
||||
\arg GPIO_OSPEED_50MHZ: output max speed 50M
|
||||
\param[in] pin: 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(0x1U == 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
|
||||
\param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
|
||||
\param[in] pin: 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
|
||||
\param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
|
||||
\param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void gpio_bit_reset(uint32_t gpio_periph,uint32_t pin)
|
||||
{
|
||||
GPIO_BC(gpio_periph) = (uint32_t)pin;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief write data to the specified GPIO pin
|
||||
\param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
|
||||
\param[in] pin: 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: GPIOx(x = A,B,C,D,F)
|
||||
\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: GPIOx(x = A,B,C,D,F)
|
||||
\param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
|
||||
\param[out] none
|
||||
\retval input state 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: GPIOx(x = A,B,C,D,F)
|
||||
\param[out] none
|
||||
\retval input state of gpio all pins
|
||||
*/
|
||||
uint16_t gpio_input_port_get(uint32_t gpio_periph)
|
||||
{
|
||||
return (uint16_t)(GPIO_ISTAT(gpio_periph));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get GPIO pin output status
|
||||
\param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
|
||||
\param[in] pin: GPIO_PIN_x(x=0..15), GPIO_PIN_ALL
|
||||
\param[out] none
|
||||
\retval output state 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 all pins output status
|
||||
\param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
|
||||
\param[out] none
|
||||
\retval output state of gpio all pins
|
||||
*/
|
||||
uint16_t gpio_output_port_get(uint32_t gpio_periph)
|
||||
{
|
||||
return ((uint16_t)GPIO_OCTL(gpio_periph));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set GPIO alternate function
|
||||
\param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
|
||||
\param[in] alt_func_num: gpio pin af function, please refer to specific device datasheet
|
||||
\arg GPIO_AF_0: TIMER2, TIMER13, TIMER14, TIMER16, SPI0, I2S0, SPI1, SPI2, I2S2, CK_OUT,
|
||||
SWDIO, SWCLK, USART0, CEC, IFRP, I2C0, I2C1, TSI, EVENTOUT
|
||||
\arg GPIO_AF_1: USART0, USART1, IFRP, CEC, TIMER2, TIMER14, I2C0, I2C1, I2C2, EVENTOUT
|
||||
\arg GPIO_AF_2: TIMER0, TIMER1, TIMER15, TIMER16, EVENTOUT
|
||||
\arg GPIO_AF_3: TSI, I2C0, TIMER14, EVENTOUT
|
||||
\arg GPIO_AF_4(port A,B only): TIMER13, I2C0, I2C1, I2C2, USART1
|
||||
\arg GPIO_AF_5(port A,B only): TIMER15, TIMER16, SPI2, I2S2, I2C0, I2C1
|
||||
\arg GPIO_AF_6(port A,B only): SPI1, EVENTOUT
|
||||
\arg GPIO_AF_7(port A,B only): CMP0, CMP1
|
||||
\arg GPIO_AF_9(port A,B only): CAN0, CAN1 (for GD32F170xx and GD32F190xx devices)
|
||||
\arg GPIO_AF_11: SLCD (for GD32F170xx and GD32F190xx devices)
|
||||
\param[in] pin: 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
|
||||
\param[in] gpio_periph: GPIOx(x = A,B)
|
||||
\param[in] pin: 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);
|
||||
}
|
||||
|
||||
#ifdef GD32F170_190
|
||||
/*!
|
||||
\brief toggle GPIO pin
|
||||
\param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
|
||||
\param[in] pin: 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
|
||||
\param[in] gpio_periph: GPIOx(x = A,B,C,D,F)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void gpio_port_toggle(uint32_t gpio_periph)
|
||||
{
|
||||
GPIO_TG(gpio_periph) = 0x0000FFFFU;
|
||||
}
|
||||
|
||||
#endif /* GD32F170_190 */
|
795
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_i2c.c
Normal file
795
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_i2c.c
Normal file
@@ -0,0 +1,795 @@
|
||||
/*!
|
||||
\file gd32f1x0_i2c.c
|
||||
\brief I2C driver
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2017 GigaDevice
|
||||
|
||||
2014-12-26, V1.0.0, platform GD32F1x0(x=3,5)
|
||||
2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9)
|
||||
2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
*/
|
||||
|
||||
#include "gd32f1x0_i2c.h"
|
||||
|
||||
#define I2CCLK_MAX 0x3fU /*!< i2cclk max value */
|
||||
#define I2C_FLAG_MASK 0x0000FFFFU /*!< i2c flag mask */
|
||||
|
||||
/*!
|
||||
\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;
|
||||
#ifdef GD32F170_190
|
||||
case I2C2:
|
||||
/* reset I2C2 */
|
||||
rcu_periph_reset_enable(RCU_I2C2RST);
|
||||
rcu_periph_reset_disable(RCU_I2C2RST);
|
||||
break;
|
||||
#endif /* GD32F170_190 */
|
||||
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)
|
||||
and fast mode plus (up to 1MHz)
|
||||
\param[in] dutycyc: duty cycle in fast mode or fast mode plus
|
||||
\arg I2C_DTCY_2: T_low/T_high=2
|
||||
\arg I2C_DTCY_16_9: T_low/T_high=16/9
|
||||
\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{
|
||||
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{
|
||||
/* illegal parameters */
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure I2C address
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] mode:
|
||||
\arg I2C_I2CMODE_ENABLE: I2C mode
|
||||
\arg I2C_SMBUSMODE_ENABLE: SMBus mode
|
||||
\param[in] addformat: 7bits or 10bits
|
||||
\arg I2C_ADDFORMAT_7BITS: 7bits
|
||||
\arg I2C_ADDFORMAT_10BITS: 10bits
|
||||
\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 */
|
||||
I2C_SADDR0(i2c_periph) = (addformat | addr);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief SMBus type selection
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] ack:
|
||||
\arg I2C_SMBUS_DEVICE: device
|
||||
\arg I2C_SMBUS_HOST: host
|
||||
\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:
|
||||
\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)
|
||||
{
|
||||
if(I2C_ACK_ENABLE == ack){
|
||||
I2C_CTL0(i2c_periph) |= I2C_CTL0_ACKEN;
|
||||
}else{
|
||||
I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_ACKEN);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief I2C POAP position configure
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] pos:
|
||||
\arg I2C_ACKPOS_CURRENT: whether to send ACK or not for the current
|
||||
\arg I2C_ACKPOS_NEXT: whether to send ACK or not for the next byte
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_ackpos_config(uint32_t i2c_periph, uint32_t pos)
|
||||
{
|
||||
/* configure I2C POAP position */
|
||||
if(I2C_ACKPOS_NEXT == pos){
|
||||
I2C_CTL0(i2c_periph) |= I2C_CTL0_POAP;
|
||||
}else{
|
||||
I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_POAP);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief master send slave address
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] addr: slave address
|
||||
\param[in] trandirection: transmitter or receiver
|
||||
\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)
|
||||
{
|
||||
if(I2C_TRANSMITTER == trandirection){
|
||||
addr = addr & I2C_TRANSMITTER;
|
||||
}else{
|
||||
addr = addr | I2C_RECEIVER;
|
||||
}
|
||||
I2C_DATA(i2c_periph) = addr;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief dual-address mode switch
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] dualaddr:
|
||||
\arg I2C_DUADEN_DISABLE: disable dual-address mode
|
||||
\arg I2C_DUADEN_ENABLE: enable dual-address mode
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_dualaddr_enable(uint32_t i2c_periph, uint32_t dualaddr)
|
||||
{
|
||||
if(I2C_DUADEN_ENABLE == dualaddr){
|
||||
I2C_SADDR1(i2c_periph) |= I2C_SADDR1_DUADEN;
|
||||
}else{
|
||||
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 enable I2C DMA mode
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] dmastate:
|
||||
\arg I2C_DMA_ON: DMA mode enable
|
||||
\arg I2C_DMA_OFF: DMA mode disable
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_dma_enable(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 flag indicating DMA last transfer
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] dmalast:
|
||||
\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_enable(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:
|
||||
\arg I2C_SCLSTRETCH_ENABLE: SCL stretching is enabled
|
||||
\arg I2C_SCLSTRETCH_DISABLE: SCL stretching is disabled
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_stretch_scl_low_config(uint32_t i2c_periph, uint32_t stretchpara)
|
||||
{
|
||||
/* configure I2C SCL strerching enable or disable */
|
||||
uint32_t ctl = 0U;
|
||||
ctl = I2C_CTL0(i2c_periph);
|
||||
ctl &= ~(I2C_CTL0_DISSTRC);
|
||||
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:
|
||||
\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 software reset I2C
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] sreset:
|
||||
\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 check I2C flag is set or not
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] flag:
|
||||
\arg I2C_FLAG_SBSEND: start condition send out
|
||||
\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: overrun or underrun 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_TRS: 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_DUMODF: dual flag in slave mode indicating which address is matched in dual-address mode
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus i2c_flag_get(uint32_t i2c_periph, uint32_t flag)
|
||||
{
|
||||
uint32_t reg = 0U;
|
||||
FlagStatus reval = RESET;
|
||||
/* get the flag in which register */
|
||||
reg = (BIT(31) & flag);
|
||||
if((BIT(31) == reg)){
|
||||
if((I2C_STAT1(i2c_periph)&(flag & I2C_FLAG_MASK))){
|
||||
reval = SET;
|
||||
}else{
|
||||
reval = RESET;
|
||||
}
|
||||
}else{
|
||||
if((I2C_STAT0(i2c_periph)&(flag & I2C_FLAG_MASK))){
|
||||
reval = SET;
|
||||
}else{
|
||||
reval = RESET;
|
||||
}
|
||||
}
|
||||
/* return the flag status */
|
||||
return reval;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear I2C flag
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] flag: flag type
|
||||
\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
|
||||
\arg I2C_FLAG_ADDSEND: cleared by reading I2C_STAT0 and reading I2C_STAT1
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_flag_clear(uint32_t i2c_periph, uint32_t 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_STAT0(i2c_periph) &= ~(flag);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable I2C interrupt
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] inttype: interrupt type
|
||||
\arg I2C_INT_ERR: error interrupt enable
|
||||
\arg I2C_INT_EV: event interrupt enable
|
||||
\arg I2C_INT_BUF: buffer interrupt enable
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_interrupt_enable(uint32_t i2c_periph, uint32_t inttype)
|
||||
{
|
||||
I2C_CTL1(i2c_periph) |= (inttype);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable I2C interrupt
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] inttype: interrupt type
|
||||
\arg I2C_INT_ERR: error interrupt enable
|
||||
\arg I2C_INT_EV: event interrupt enable
|
||||
\arg I2C_INT_BUF: buffer interrupt enable
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_interrupt_disable(uint32_t i2c_periph, uint32_t inttype)
|
||||
{
|
||||
I2C_CTL1(i2c_periph) &= ~(inttype);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief check I2C interrupt flag
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] int_flag: interrupt flag
|
||||
\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
|
||||
\arg I2C_INT_FLAG_ADD10SEND: header of 10-bit address is sent in master mode interrupt flag
|
||||
\arg I2C_INT_FLAG_STPDET: etop 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
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
FlagStatus i2c_interrupt_flag_get(uint32_t i2c_periph, uint32_t intflag)
|
||||
{
|
||||
uint32_t evie, errie, bufie;
|
||||
|
||||
evie = I2C_CTL1(i2c_periph)&I2C_CTL1_EVIE;
|
||||
errie = I2C_CTL1(i2c_periph)&I2C_CTL1_ERRIE;
|
||||
/* check I2C event interrupt enable bit */
|
||||
if((intflag&0x00ffU) && evie){
|
||||
if(intflag&0x001fU){
|
||||
/* check I2C event flags except TBE and RBNE */
|
||||
if(intflag & I2C_STAT0(i2c_periph)){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}else{
|
||||
/* check I2C event flags TBE and RBNE */
|
||||
bufie = I2C_CTL1(i2c_periph)&I2C_CTL1_BUFIE;
|
||||
if(bufie){
|
||||
if(intflag & I2C_STAT0(i2c_periph)){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
/* check I2C error interrupt enable bit */
|
||||
}else if((intflag&0xff00U) && errie){
|
||||
/* check I2C error flags */
|
||||
if(intflag & I2C_STAT0(i2c_periph)){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear I2C interrupt flag
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] intflag: 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_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
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_interrupt_flag_clear(uint32_t i2c_periph, uint32_t intflag)
|
||||
{
|
||||
if(I2C_INT_FLAG_ADDSEND == intflag){
|
||||
/* read I2C_STAT0 and then read I2C_STAT1 to clear ADDSEND */
|
||||
I2C_STAT0(i2c_periph);
|
||||
I2C_STAT1(i2c_periph);
|
||||
}else{
|
||||
I2C_STAT0(i2c_periph) &= ~(intflag);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief I2C PEC calculation on or off
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] pecpara:
|
||||
\arg I2C_PEC_ENABLE: PEC calculation on
|
||||
\arg I2C_PEC_DISABLE: PEC calculation off
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_pec_enable(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 I2C whether to transfer PEC value
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] pecpara:
|
||||
\arg I2C_PECTRANS_ENABLE: transfer PEC
|
||||
\arg I2C_PECTRANS_DISABLE: not transfer PEC
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_pec_transfer_enable(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_ECV)>>8);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief I2C issue alert through SMBA pin
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] smbuspara:
|
||||
\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_issue_alert(uint32_t i2c_periph, uint32_t smbuspara)
|
||||
{
|
||||
/* issue alert through SMBA pin configure*/
|
||||
uint32_t ctl = 0U;
|
||||
ctl = I2C_CTL0(i2c_periph);
|
||||
ctl &= ~(I2C_CTL0_SALT);
|
||||
ctl |= smbuspara;
|
||||
I2C_CTL0(i2c_periph) = ctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable or disable I2C ARP protocol in SMBus switch
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] smbuspara:
|
||||
\arg I2C_ARP_ENABLE: enable ARP
|
||||
\arg I2C_ARP_DISABLE: disable ARP
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_smbus_arp_enable(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;
|
||||
}
|
||||
|
||||
#ifdef GD32F170_190
|
||||
|
||||
/*!
|
||||
\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 enable the specified I2C SAM interrupt
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] inttype: interrupt type
|
||||
\@arg I2C_SAMCS_TFFIE: txframe fall interrupt
|
||||
\@arg I2C_SAMCS_TFRIE: txframe rise interrupt
|
||||
\@arg I2C_SAMCS_RFFIE: rxframe fall interrupt
|
||||
\@arg I2C_SAMCS_RFRIE: rxframe rise interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_sam_interrupt_enable(uint32_t i2c_periph, uint32_t inttype)
|
||||
{
|
||||
I2C_SAMCS(i2c_periph) |= (inttype);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable i2c interrupt
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] inttype: interrupt type
|
||||
\@arg I2C_SAMCS_TFFIE: txframe fall interrupt
|
||||
\@arg I2C_SAMCS_TFRIE: txframe rise interrupt
|
||||
\@arg I2C_SAMCS_RFFIE: rxframe fall interrupt
|
||||
\@arg I2C_SAMCS_RFRIE: rxframe rise interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_sam_interrupt_disable(uint32_t i2c_periph, uint32_t inttype)
|
||||
{
|
||||
I2C_SAMCS(i2c_periph) &= ~(inttype);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief check i2c SAM state
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] samstate: state type
|
||||
\@arg I2C_SAMCS_TXF: level of txframe signal
|
||||
\@arg I2C_SAMCS_RXF: level of rxframe signal
|
||||
\@arg I2C_SAMCS_TFF: txframe fall flag
|
||||
\@arg I2C_SAMCS_TFR: txframe rise flag
|
||||
\@arg I2C_SAMCS_RFF: rxframe fall flag
|
||||
\@arg I2C_SAMCS_RFR: rxframe rise flag
|
||||
\param[out] none
|
||||
\retval state of i2c SAM
|
||||
*/
|
||||
FlagStatus i2c_sam_flag_get(uint32_t i2c_periph, uint32_t samstate)
|
||||
{
|
||||
if(I2C_SAMCS(i2c_periph) & samstate){
|
||||
return SET;
|
||||
}
|
||||
|
||||
return RESET;
|
||||
}
|
||||
/*!
|
||||
\brief clear i2c SAM state
|
||||
\param[in] i2c_periph: I2Cx(x=0,1,2)
|
||||
\param[in] samstate: state type
|
||||
\@arg I2C_SAMCS_TFF: txframe fall flag
|
||||
\@arg I2C_SAMCS_TFR: txframe rise flag
|
||||
\@arg I2C_SAMCS_RFF: rxframe fall flag
|
||||
\@arg I2C_SAMCS_RFR: rxframe rise flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2c_sam_flag_clear(uint32_t i2c_periph, uint32_t samstate)
|
||||
{
|
||||
I2C_SAMCS(i2c_periph) &= ~(samstate);
|
||||
|
||||
}
|
||||
|
||||
#endif /* GD32F170_190 */
|
180
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_ivref.c
Normal file
180
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_ivref.c
Normal file
@@ -0,0 +1,180 @@
|
||||
/*!
|
||||
\file gd32f1x0_ivref.c
|
||||
\brief IVREF driver
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2017 GigaDevice
|
||||
|
||||
2014-12-26, V1.0.0, platform GD32F1x0(x=3,5)
|
||||
2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9)
|
||||
2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
*/
|
||||
|
||||
#ifdef GD32F170_190
|
||||
|
||||
#include "gd32f1x0_ivref.h"
|
||||
|
||||
/*!
|
||||
\brief deinit IVREF
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void ivref_deinit(void)
|
||||
{
|
||||
rcu_periph_reset_enable(RCU_OPAIVREFRST);
|
||||
rcu_periph_reset_disable(RCU_OPAIVREFRST);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable VREF
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void vref_enable(void)
|
||||
{
|
||||
IVREF_CTL |= IVREF_CTL_VREN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable VREF
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void vref_disable(void)
|
||||
{
|
||||
IVREF_CTL &= ~IVREF_CTL_VREN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set VREF mode
|
||||
\param[in] vrefmode
|
||||
\arg VREF_CONNECT_EXTERNAL_CAP: vref connect external capacitor
|
||||
\arg VREF_DISCONNECT_EXTERNAL_CAP: vref disconnect external capacitor
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void vref_mode_set(uint32_t vrefmode)
|
||||
{
|
||||
uint32_t ctl = 0U;
|
||||
ctl = IVREF_CTL;
|
||||
/* clear voltage reference enable bits */
|
||||
ctl &= ~IVREF_CTL_DECAP;
|
||||
ctl |= vrefmode;
|
||||
IVREF_CTL = ctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set VREF voltage precision trim.
|
||||
\param[in] precisiontrim
|
||||
\arg VREF_VOLT_PRECISION_TRIM_X(x=0..31): (-6.4+ 0.4*x)%
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void vref_precision_trim_value_set(uint32_t precisiontrim)
|
||||
{
|
||||
uint32_t ctl = 0U;
|
||||
ctl = IVREF_CTL;
|
||||
ctl &= ~IVREF_CTL_VPT;
|
||||
ctl |= precisiontrim;
|
||||
IVREF_CTL = ctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable IREF
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void iref_enable(void)
|
||||
{
|
||||
IVREF_CTL |= IVREF_CTL_CREN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable IREF
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void iref_disable(void)
|
||||
{
|
||||
IVREF_CTL &= ~IVREF_CTL_CREN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set IREF mode
|
||||
\param[in] irefmode
|
||||
\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 irefmode)
|
||||
{
|
||||
uint32_t ctl = 0U;
|
||||
ctl = IVREF_CTL;
|
||||
ctl &= ~IVREF_CTL_SSEL;
|
||||
ctl |= irefmode;
|
||||
IVREF_CTL = ctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\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)
|
||||
{
|
||||
uint32_t ctl = 0U;
|
||||
ctl = IVREF_CTL;
|
||||
ctl &= ~IVREF_CTL_CPT;
|
||||
ctl |= precisiontrim;
|
||||
IVREF_CTL = ctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set IREF sink mode
|
||||
\param[in] irefsinkmode
|
||||
\arg IREF_SOURCE_CURRENT : source current.
|
||||
\arg IREF_SINK_CURRENT: sink current
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void iref_sink_set(uint32_t irefsinkmode)
|
||||
{
|
||||
uint32_t ctl = 0U;
|
||||
ctl = IVREF_CTL;
|
||||
/* clear sink current mode bits */
|
||||
ctl &= ~IVREF_CTL_SCMOD;
|
||||
/* set sink current mode bits */
|
||||
ctl |= irefsinkmode;
|
||||
IVREF_CTL = ctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set IREF step data
|
||||
\param[in] irefstepdata
|
||||
\arg IREF_CUR_STEP_DATA_X:(x=0..63): step*x
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void iref_step_data_config(uint32_t irefstepdata)
|
||||
{
|
||||
uint32_t ctl = 0U;
|
||||
/* get ctl value */
|
||||
ctl = IVREF_CTL;
|
||||
/* clear current step data bits */
|
||||
ctl &= ~IVREF_CTL_CSDT;
|
||||
/* set current step data bits */
|
||||
ctl |= irefstepdata;
|
||||
IVREF_CTL = ctl;
|
||||
}
|
||||
|
||||
#endif /* GD32F170_190 */
|
149
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_misc.c
Normal file
149
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_misc.c
Normal file
@@ -0,0 +1,149 @@
|
||||
/*!
|
||||
\file gd32f1x0_misc.c
|
||||
\brief MISC driver
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2017 GigaDevice
|
||||
|
||||
2014-12-26, V1.0.0, platform GD32F1x0(x=3,5)
|
||||
2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9)
|
||||
2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
*/
|
||||
|
||||
#include "gd32f1x0_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(uint8_t 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)0x700)==NVIC_PRIGROUP_PRE0_SUB4){
|
||||
temp_pre = 0U;
|
||||
temp_sub = 0x4U;
|
||||
}else if(((SCB->AIRCR) & (uint32_t)0x700)==NVIC_PRIGROUP_PRE1_SUB3){
|
||||
temp_pre = 1U;
|
||||
temp_sub = 0x3U;
|
||||
}else if(((SCB->AIRCR) & (uint32_t)0x700)==NVIC_PRIGROUP_PRE2_SUB2){
|
||||
temp_pre = 2U;
|
||||
temp_sub = 0x2U;
|
||||
}else if(((SCB->AIRCR) & (uint32_t)0x700)==NVIC_PRIGROUP_PRE3_SUB1){
|
||||
temp_pre = 3U;
|
||||
temp_sub = 0x1U;
|
||||
}else if(((SCB->AIRCR) & (uint32_t)0x700)==NVIC_PRIGROUP_PRE4_SUB0){
|
||||
temp_pre = 4U;
|
||||
temp_sub = 0x0U;
|
||||
}else{
|
||||
}
|
||||
/* 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 >> 0x05] = (uint32_t)0x01 << (nvic_irq & (uint8_t)0x1F);
|
||||
}
|
||||
|
||||
/*!
|
||||
\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(uint8_t 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);
|
||||
}
|
||||
|
||||
/*!
|
||||
\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;
|
||||
}
|
||||
}
|
341
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_opa.c
Normal file
341
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_opa.c
Normal file
@@ -0,0 +1,341 @@
|
||||
/*!
|
||||
\file gd32f1x0_opa.c
|
||||
\brief OPA driver
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2017 GigaDevice
|
||||
|
||||
2014-12-26, V1.0.0, platform GD32F1x0(x=3,5)
|
||||
2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9)
|
||||
2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
*/
|
||||
|
||||
#ifdef GD32F170_190
|
||||
|
||||
#include "gd32f1x0_opa.h"
|
||||
|
||||
/*!
|
||||
\brief deinit the OPA register to its default reset value
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void opa_deinit(void)
|
||||
{
|
||||
rcu_periph_reset_enable(RCU_OPAIVREFRST);
|
||||
rcu_periph_reset_disable(RCU_OPAIVREFRST);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable OPA switch
|
||||
\param[in] opax_swy
|
||||
\arg OPA_T3OPA0: T3 switch enable for OPA0
|
||||
\arg OPA_S1OPA0: S1 switch enable for OPA0
|
||||
\arg OPA_S2OPA0: S2 switch enable for OPA0
|
||||
\arg OPA_S3OPA0: S3 switch enable for OPA0
|
||||
\arg OPA_T3OPA1: T3 switch enable for OPA1
|
||||
\arg OPA_S1OPA1: S1 switch enable for OPA1
|
||||
\arg OPA_S2OPA1: S2 switch enable for OPA1
|
||||
\arg OPA_S3OPA1: S3 switch enable for OPA1
|
||||
\arg OPA_S4OPA1: S4 switch enable for OPA1
|
||||
\arg OPA_T3OPA2: T3 switch enable for OPA2
|
||||
\arg OPA_S1OPA2: S3 switch enable for OPA2
|
||||
\arg OPA_S2OPA2: S3 switch enable for OPA2
|
||||
\arg OPA_S3OPA2: S3 switch enable for OPA2
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void opa_switch_enable(uint32_t opax_swy)
|
||||
{
|
||||
OPA_CTL |= (uint32_t)(opax_swy);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable OPA
|
||||
\param[in] opa_periph
|
||||
\arg OPAx(x =0,1,2)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void opa_enable(uint32_t opa_periph)
|
||||
{
|
||||
if(OPA0 == opa_periph){
|
||||
OPA_CTL &= ~OPA_CTL_OPA0PD;
|
||||
}else if(OPA1 == opa_periph){
|
||||
OPA_CTL &= ~OPA_CTL_OPA1PD;
|
||||
}else{
|
||||
OPA_CTL &= ~OPA_CTL_OPA2PD;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable OPA
|
||||
\param[in] opa_periph
|
||||
\arg OPAx(x =0,1,2)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void opa_disable(uint32_t opa_periph)
|
||||
{
|
||||
if(OPA0 == opa_periph){
|
||||
OPA_CTL |= OPA_CTL_OPA0PD;
|
||||
}else if(OPA1 == opa_periph){
|
||||
OPA_CTL |= OPA_CTL_OPA1PD;
|
||||
}else{
|
||||
OPA_CTL |= OPA_CTL_OPA2PD;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable OPA switch
|
||||
\param[in] opax_swy
|
||||
\arg OPA_T3OPA0: T3 switch enable for OPA0
|
||||
\arg OPA_S1OPA0: S1 switch enable for OPA0
|
||||
\arg OPA_S2OPA0: S2 switch enable for OPA0
|
||||
\arg OPA_S3OPA0: S3 switch enable for OPA0
|
||||
\arg OPA_T3OPA1: T3 switch enable for OPA1
|
||||
\arg OPA_S1OPA1: S1 switch enable for OPA1
|
||||
\arg OPA_S2OPA1: S2 switch enable for OPA1
|
||||
\arg OPA_S3OPA1: S3 switch enable for OPA1
|
||||
\arg OPA_S4OPA1: S4 switch enable for OPA1
|
||||
\arg OPA_T3OPA2: T3 switch enable for OPA2
|
||||
\arg OPA_S1OPA2: S3 switch enable for OPA2
|
||||
\arg OPA_S2OPA2: S3 switch enable for OPA2
|
||||
\arg OPA_S3OPA2: S3 switch enable for OPA2
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void opa_switch_disable(uint32_t opax_swy)
|
||||
{
|
||||
OPA_CTL &= ~opax_swy;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable OPA in low power mode
|
||||
\param[in] opa_periph
|
||||
\arg OPAx(x =0,1,2)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void opa_low_power_enable(uint32_t opa_periph)
|
||||
{
|
||||
if(OPA0 == opa_periph){
|
||||
OPA_CTL &= ~OPA_CTL_OPA0LPM;
|
||||
}else if(OPA1 == opa_periph){
|
||||
OPA_CTL &= ~OPA_CTL_OPA1LPM;
|
||||
}else{
|
||||
OPA_CTL &= ~OPA_CTL_OPA2LPM;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable OPA in low power mode
|
||||
\param[in] opa_periph
|
||||
\arg OPAx(x =0,1,2)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void opa_low_power_disable(uint32_t opa_periph)
|
||||
{
|
||||
if(OPA0 == opa_periph){
|
||||
OPA_CTL |= OPA_CTL_OPA0LPM;
|
||||
}else if(OPA1 == opa_periph){
|
||||
OPA_CTL |= OPA_CTL_OPA1LPM;
|
||||
}else{
|
||||
OPA_CTL |= OPA_CTL_OPA2LPM;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set OPA power range
|
||||
\param[in] powerrange
|
||||
\arg OPA_POWRANGE_LOW: Low power range is selected (VDDA is lower than 3.3V)
|
||||
\arg OPA_POWRANGE_HIGH: High power range is selected (VDDA is higher than 3.3V)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void opa_power_range_config(uint32_t powerrange)
|
||||
{
|
||||
OPA_CTL &= ~OPA_CTL_OPA_RANGE;
|
||||
OPA_CTL |= powerrange;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set OPA bias trimming mode
|
||||
\param[in] opa_trimmode
|
||||
\arg OPA_BT_TRIM_FACTORY: factory trimming values are used for offset calibration
|
||||
\arg OPA_BT_TRIM_USER: user trimming values are used for offset calibration
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void opa_trim_mode_set(uint32_t opa_trimmode)
|
||||
{
|
||||
OPA_BT &= ~OPA_BT_OT_USER;
|
||||
OPA_BT |= opa_trimmode;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set OPA bias trimming value
|
||||
\param[in] opa_periph
|
||||
\arg OPAx(x =0,1,2)
|
||||
\param[in] opa_input
|
||||
\arg OPA_INPUT_P: PMOS input is selected to configure the trimming value
|
||||
\arg OPA_INPUT_N: NMOS input is selected to configure the trimming value
|
||||
\param[in] opa_trimmode
|
||||
\arg this parameter can be any value lower or equal to 0x0000001F.
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void opa_trim_value_config(uint32_t opa_periph,uint32_t opa_input,uint32_t opa_trimvalue)
|
||||
{
|
||||
uint32_t bt = 0U, ctl = 0U;
|
||||
ctl = OPA_CTL;
|
||||
bt = OPA_BT;
|
||||
|
||||
if(OPA0 == opa_periph){
|
||||
/* clear the specified opa calibration for N diff and P diff */
|
||||
ctl &= (uint32_t)~(OPA_CTL_OPA0CAL_L | OPA_CTL_OPA0CAL_H);
|
||||
/* set the specified opa calibration for N diff or P diff */
|
||||
ctl |= opa_input;
|
||||
if(OPA_INPUT_P == opa_input){
|
||||
/* clear the specified PMOS pairs normal mode 5-bit offset trim value */
|
||||
bt &= (~OPA_BT_OA0_TRIM_LOW);
|
||||
bt |= (opa_trimvalue);
|
||||
}else{
|
||||
/* clear the specified NMOS pairs normal mode 5-bit offset trim value */
|
||||
bt &= (~OPA_BT_OA0_TRIM_HIGH);
|
||||
bt |= (opa_trimvalue << 5U);
|
||||
}
|
||||
|
||||
}else if(OPA1 == opa_periph){
|
||||
ctl &= (uint32_t)~(OPA_CTL_OPA1CAL_L | OPA_CTL_OPA1CAL_H);
|
||||
ctl |= (uint32_t)(opa_input << 8U);
|
||||
if(OPA_INPUT_P == opa_input){
|
||||
/* clear the specified PMOS pairs normal mode 5-bit offset trim value */
|
||||
bt &= (~OPA_BT_OA1_TRIM_LOW);
|
||||
bt |= (opa_trimvalue << 10U);
|
||||
}else{
|
||||
/* clear the specified NMOS pairs normal mode 5-bit offset trim value */
|
||||
bt &= (~OPA_BT_OA1_TRIM_HIGH);
|
||||
bt |= (opa_trimvalue << 15U);
|
||||
}
|
||||
}else{
|
||||
ctl &= (uint32_t)~(OPA_CTL_OPA2CAL_L | OPA_CTL_OPA2CAL_H);
|
||||
ctl |= (uint32_t)(opa_input << 16U);
|
||||
if(OPA_INPUT_P == opa_input){
|
||||
/* clear the specified PMOS pairs normal mode 5-bit offset trim value */
|
||||
bt &= (~OPA_BT_OA2_TRIM_LOW);
|
||||
bt |= (opa_trimvalue << 20U);
|
||||
}else{
|
||||
/* clear the specified NMOS pairs normal mode 5-bit offset trim value */
|
||||
bt &= (~OPA_BT_OA2_TRIM_HIGH);
|
||||
bt |= (opa_trimvalue << 25U);
|
||||
}
|
||||
}
|
||||
|
||||
OPA_CTL = ctl;
|
||||
OPA_BT = bt;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set OPA bias trimming value low power
|
||||
\param[in] opa_periph
|
||||
\arg OPAx(x =0,1,2)
|
||||
\param[in] opa_input
|
||||
\arg OPA_INPUT_P: PMOS input is selected to configure the trimming value
|
||||
\arg OPA_INPUT_N: NMOS input is selected to configure the trimming value
|
||||
\param[in] opa_trimmode
|
||||
\arg this parameter can be any value lower or equal to 0x0000001F.
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void opa_trim_value_lp_config(uint32_t opa_periph,uint32_t opa_input,uint32_t opa_trimvalue)
|
||||
{
|
||||
uint32_t lpbt = 0U, ctl = 0U;
|
||||
ctl = OPA_CTL;
|
||||
lpbt = OPA_LPBT;
|
||||
|
||||
if(OPA0 == opa_periph){
|
||||
ctl &= (uint32_t)~(OPA_CTL_OPA0CAL_L | OPA_CTL_OPA0CAL_H);
|
||||
ctl |= opa_input;
|
||||
if(OPA_INPUT_P == opa_input){
|
||||
/* clear the specified PMOS pairs low power mode 5-bit offset trim value */
|
||||
lpbt &= (~OPA_LPBT_OA0_TRIM_LOW);
|
||||
lpbt |= (opa_trimvalue);
|
||||
}else{
|
||||
/* clear the specified NMOS pairs low power mode 5-bit offset trim value */
|
||||
lpbt &= (~OPA_LPBT_OA0_TRIM_HIGH);
|
||||
lpbt |= (opa_trimvalue << 5U);
|
||||
}
|
||||
}else if (OPA1 == opa_periph){
|
||||
ctl &= (uint32_t)~(OPA_CTL_OPA0CAL_L | OPA_CTL_OPA0CAL_H);
|
||||
ctl |= (uint32_t)(opa_input << 8U);
|
||||
if(OPA_INPUT_P == opa_input){
|
||||
/* clear the specified PMOS pairs low power mode 5-bit offset trim value */
|
||||
lpbt &= (~OPA_LPBT_OA1_TRIM_LOW);
|
||||
lpbt |= (opa_trimvalue << 10U);
|
||||
}else{
|
||||
/* clear the specified NMOS pairs low power mode 5-bit offset trim value */
|
||||
lpbt &= (~OPA_LPBT_OA1_TRIM_HIGH);
|
||||
lpbt |= (opa_trimvalue << 15U);
|
||||
}
|
||||
|
||||
}else{
|
||||
ctl &= (uint32_t)~(OPA_CTL_OPA2CAL_L | OPA_CTL_OPA2CAL_H);
|
||||
ctl |= (uint32_t)(opa_input << 16U);
|
||||
if(OPA_INPUT_P == opa_input){
|
||||
/* clear the specified PMOS pairs low power mode 5-bit offset trim value */
|
||||
lpbt &= (~OPA_LPBT_OA2_TRIM_LOW);
|
||||
lpbt |= (opa_trimvalue << 20U);
|
||||
}else{
|
||||
/* clear the specified NMOS pairs low power mode 5-bit offset trim value */
|
||||
lpbt &= (~OPA_LPBT_OA2_TRIM_HIGH);
|
||||
lpbt |= (opa_trimvalue << 25U);
|
||||
}
|
||||
}
|
||||
|
||||
OPA_CTL = ctl;
|
||||
OPA_LPBT = lpbt;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get OPA calibration flag
|
||||
\param[in] opa_periph
|
||||
\arg OPAx(x =0,1,2)
|
||||
\param[out] none
|
||||
\retval The state of the OPA calibration flag (SET or RESET)
|
||||
*/
|
||||
FlagStatus opa_cal_out_get(uint32_t opa_periph)
|
||||
{
|
||||
uint32_t data = 0U;
|
||||
FlagStatus bitstatus = RESET;
|
||||
data = OPA_CTL;
|
||||
|
||||
if(OPA0 == opa_periph){
|
||||
/* get opa0 calibration output bit status */
|
||||
if ((uint32_t)RESET != (data & OPA_CTL_OPA1CALOUT)){
|
||||
bitstatus = SET;
|
||||
}else{
|
||||
bitstatus = RESET;
|
||||
}
|
||||
}else if(OPA1 == opa_periph){
|
||||
/* get opa1 calibration output bit status */
|
||||
if ((uint32_t)RESET != (data & OPA_CTL_OPA1CALOUT)){
|
||||
bitstatus = SET;
|
||||
}else{
|
||||
bitstatus = RESET;
|
||||
}
|
||||
}else{
|
||||
/* get opa2 calibration output bit status */
|
||||
if((uint32_t)RESET != (data & OPA_CTL_OPA1CALOUT)){
|
||||
bitstatus = SET;
|
||||
}else{
|
||||
bitstatus = RESET;
|
||||
}
|
||||
}
|
||||
return bitstatus;
|
||||
}
|
||||
|
||||
#endif /* GD32F170_190 */
|
257
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_pmu.c
Normal file
257
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_pmu.c
Normal file
@@ -0,0 +1,257 @@
|
||||
/*!
|
||||
\file gd32f1x0_pmu.c
|
||||
\brief PMU driver
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2017 GigaDevice
|
||||
|
||||
2014-12-26, V1.0.0, platform GD32F1x0(x=3,5)
|
||||
2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9)
|
||||
2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
*/
|
||||
|
||||
#include "gd32f1x0_pmu.h"
|
||||
|
||||
/*!
|
||||
\brief reset PMU register
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_deinit(void)
|
||||
{
|
||||
/* reset PMU */
|
||||
rcu_periph_reset_enable(RCU_PMURST);
|
||||
rcu_periph_reset_disable(RCU_PMURST);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief select low voltage detector threshold
|
||||
\param[in] lvdt_n:
|
||||
\arg PMU_LVDT_0: voltage threshold is 2.2V (GD32F130_150) or 2.4V (GD32F170_190)
|
||||
\arg PMU_LVDT_1: voltage threshold is 2.3V (GD32F130_150) or 2.7V (GD32F170_190)
|
||||
\arg PMU_LVDT_2: voltage threshold is 2.4V (GD32F130_150) or 3.0V (GD32F170_190)
|
||||
\arg PMU_LVDT_3: voltage threshold is 2.5V (GD32F130_150) or 3.3V (GD32F170_190)
|
||||
\arg PMU_LVDT_4: voltage threshold is 2.6V (GD32F130_150) or 3.6V (GD32F170_190)
|
||||
\arg PMU_LVDT_5: voltage threshold is 2.7V (GD32F130_150) or 3.9V (GD32F170_190)
|
||||
\arg PMU_LVDT_6: voltage threshold is 2.8V (GD32F130_150) or 4.2V (GD32F170_190)
|
||||
\arg PMU_LVDT_7: voltage threshold is 2.9V (GD32F130_150) or 4.5V (GD32F170_190)
|
||||
\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 lvdt_n */
|
||||
PMU_CTL |= lvdt_n;
|
||||
/* enable LVD */
|
||||
PMU_CTL |= PMU_CTL_LVDEN;
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief PMU lvd disable
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_lvd_disable(void)
|
||||
{
|
||||
/* disable LVD */
|
||||
PMU_CTL &= ~PMU_CTL_LVDEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief PMU work at 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-M3 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 at deepsleep mode
|
||||
\param[in] ldo
|
||||
\arg PMU_LDO_NORMAL: LDO normal work when pmu enter deepsleep mode
|
||||
\arg PMU_LDO_LOWPOWER: LDO work at low power mode when pmu enter deepsleep 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,uint8_t deepsleepmodecmd)
|
||||
{
|
||||
static uint32_t reg_snap[ 4 ];
|
||||
/* clear stbmod and ldolp bits */
|
||||
PMU_CTL &= ~((uint32_t)(PMU_CTL_STBMOD | PMU_CTL_LDOLP));
|
||||
|
||||
/* set ldolp bit according to pmu_ldo */
|
||||
PMU_CTL |= ldo;
|
||||
|
||||
/* set sleepdeep bit of Cortex-M3 system control register */
|
||||
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
|
||||
|
||||
reg_snap[ 0 ] = REG32( 0xE000E010 );
|
||||
reg_snap[ 1 ] = REG32( 0xE000E100 );
|
||||
reg_snap[ 2 ] = REG32( 0xE000E104 );
|
||||
reg_snap[ 3 ] = REG32( 0xE000E108 );
|
||||
|
||||
REG32( 0xE000E010 ) &= 0x00010004;
|
||||
REG32( 0xE000E180 ) = 0XB7FFEF19;
|
||||
REG32( 0xE000E184 ) = 0XFFFFFBFF;
|
||||
REG32( 0xE000E188 ) = 0xFFFFFFFF;
|
||||
|
||||
/* select WFI or WFE command to enter deepsleep mode */
|
||||
if(WFI_CMD == deepsleepmodecmd){
|
||||
__WFI();
|
||||
}else{
|
||||
__SEV();
|
||||
__WFE();
|
||||
__WFE();
|
||||
}
|
||||
|
||||
REG32( 0xE000E010 ) = reg_snap[ 0 ] ;
|
||||
REG32( 0xE000E100 ) = reg_snap[ 1 ] ;
|
||||
REG32( 0xE000E104 ) = reg_snap[ 2 ] ;
|
||||
REG32( 0xE000E108 ) = reg_snap[ 3 ] ;
|
||||
|
||||
/* reset sleepdeep bit of Cortex-M3 system control register */
|
||||
SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief pmu work at standby mode
|
||||
\param[in] standbymodecmd:
|
||||
\arg WFI_CMD: use WFI command
|
||||
\arg WFE_CMD: use WFE command
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_to_standbymode(uint8_t standbymodecmd)
|
||||
{
|
||||
/* set sleepdeep bit of Cortex-M3 system control register */
|
||||
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
|
||||
|
||||
/* set stbmod bit */
|
||||
PMU_CTL |= PMU_CTL_STBMOD;
|
||||
|
||||
/* reset wakeup flag */
|
||||
PMU_CTL |= PMU_CTL_WURST;
|
||||
|
||||
/* select WFI or WFE command to enter standby mode */
|
||||
if(WFI_CMD == standbymodecmd){
|
||||
__WFI();
|
||||
}else{
|
||||
__WFE();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear flag bit
|
||||
\param[in] flag_reset:
|
||||
\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_reset)
|
||||
{
|
||||
switch(flag_reset){
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\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
|
||||
\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 backup domain write enable
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_backup_write_enable(void)
|
||||
{
|
||||
PMU_CTL |= PMU_CTL_BKPWEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief backup domain write disable
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_backup_write_disable(void)
|
||||
{
|
||||
PMU_CTL &= ~PMU_CTL_BKPWEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief wakeup pin enable
|
||||
\param[in] wakeup_pin:
|
||||
\arg PMU_WAKEUP_PIN0: wakeup pin 0
|
||||
\arg PMU_WAKEUP_PIN1: wakeup pin 1
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_wakeup_pin_enable(uint32_t wakeup_pin )
|
||||
{
|
||||
PMU_CS |= wakeup_pin;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief wakeup pin disable
|
||||
\param[in] wakeup_pin:
|
||||
\arg PMU_WAKEUP_PIN0: wakeup pin 0
|
||||
\arg PMU_WAKEUP_PIN1: wakeup pin 1
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void pmu_wakeup_pin_disable(uint32_t wakeup_pin )
|
||||
{
|
||||
PMU_CS &= ~wakeup_pin;
|
||||
|
||||
}
|
1214
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_rcu.c
Normal file
1214
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_rcu.c
Normal file
File diff suppressed because it is too large
Load Diff
930
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_rtc.c
Normal file
930
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_rtc.c
Normal file
@@ -0,0 +1,930 @@
|
||||
/*!
|
||||
\file gd32f1x0_rtc.c
|
||||
\brief RTC driver
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2017 GigaDevice
|
||||
|
||||
2014-12-26, V1.0.0, platform GD32F1x0(x=3,5)
|
||||
2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9)
|
||||
2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
*/
|
||||
|
||||
#include "gd32f1x0_rtc.h"
|
||||
|
||||
/*!
|
||||
\brief reset most of the RTC registers
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval ErrStatus: ERROR or SUCCESS
|
||||
*/
|
||||
ErrStatus rtc_deinit(void)
|
||||
{
|
||||
ErrStatus error_status = ERROR;
|
||||
|
||||
/* RTC_TAMP register is not under write protection */
|
||||
RTC_TAMP = RTC_REGISTER_RESET;
|
||||
|
||||
/* disable the write protection */
|
||||
RTC_WPK = RTC_UNLOCK_KEY1;
|
||||
RTC_WPK = RTC_UNLOCK_KEY2;
|
||||
|
||||
/* reset RTC_CTL register, this can be done without the init mode */
|
||||
RTC_CTL &= RTC_REGISTER_RESET;
|
||||
|
||||
/* enter init mode */
|
||||
error_status = rtc_init_mode_enter();
|
||||
|
||||
if(ERROR != error_status){
|
||||
/* before reset RTC_TIME and RTC_DATE, BPSHAD bit in RTC_CTL should be reset as the condition.
|
||||
in order to read calendar from shadow register, not the real registers being reset */
|
||||
RTC_TIME = RTC_REGISTER_RESET;
|
||||
RTC_DATE = RTC_DATE_RESET;
|
||||
|
||||
RTC_PSC = RTC_PSC_RESET;
|
||||
|
||||
/* reset RTC_STAT register, also exit init mode.
|
||||
at the same time, RTC_STAT_SOPF bit is reset, as the condition to reset RTC_SHIFTCTL register later */
|
||||
RTC_STAT = RTC_STAT_RESET;
|
||||
|
||||
/* to write RTC_ALRM0SS register, ALRM0EN bit in RTC_CTL register should be reset as the condition */
|
||||
RTC_ALRM0TD = RTC_REGISTER_RESET;
|
||||
RTC_ALRM0SS = RTC_REGISTER_RESET;
|
||||
|
||||
/* reset RTC_SHIFTCTL and RTC_HRFC register, this can be done without the init mode */
|
||||
RTC_SHIFTCTL = RTC_REGISTER_RESET;
|
||||
RTC_HRFC = RTC_REGISTER_RESET;
|
||||
|
||||
error_status = rtc_register_sync_wait();
|
||||
}
|
||||
|
||||
/* enable the write protection */
|
||||
RTC_WPK = RTC_LOCK_KEY;
|
||||
|
||||
return error_status;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize RTC registers
|
||||
\param[in] rtc_initpara_struct: pointer to a rtc_parameter_struct structure which contains
|
||||
parameters for initialization of the rtc peripheral
|
||||
members of the structure and the member values are shown as below:
|
||||
rtc_year: 0x0 - 0x99(BCD format)
|
||||
rtc_month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN,
|
||||
RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC
|
||||
rtc_date: 0x1 - 0x31(BCD format)
|
||||
rtc_day_of_week: RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY
|
||||
RTC_FRIDAY, RTC_SATURDAY, RTC_SUNDAY
|
||||
rtc_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format chose
|
||||
rtc_minute: 0x0 - 0x59(BCD format)
|
||||
rtc_second: 0x0 - 0x59(BCD format)
|
||||
rtc_factor_asyn: 0x0 - 0x7F
|
||||
rtc_factor_syn: 0x0 - 0x7FFF
|
||||
rtc_am_pm: RTC_AM, RTC_PM
|
||||
rtc_display_format: RTC_24HOUR, RTC_12HOUR
|
||||
\param[out] none
|
||||
\retval ErrStatus: ERROR or SUCCESS
|
||||
*/
|
||||
ErrStatus rtc_init(rtc_parameter_struct* rtc_initpara_struct)
|
||||
{
|
||||
ErrStatus error_status = ERROR;
|
||||
uint32_t reg_time = 0U, reg_date = 0U;
|
||||
|
||||
reg_date = (DATE_YR(rtc_initpara_struct->rtc_year) | \
|
||||
DATE_DOW(rtc_initpara_struct->rtc_day_of_week) | \
|
||||
DATE_MON(rtc_initpara_struct->rtc_month) | \
|
||||
DATE_DAY(rtc_initpara_struct->rtc_date));
|
||||
|
||||
reg_time = (rtc_initpara_struct->rtc_am_pm| \
|
||||
TIME_HR(rtc_initpara_struct->rtc_hour) | \
|
||||
TIME_MN(rtc_initpara_struct->rtc_minute) | \
|
||||
TIME_SC(rtc_initpara_struct->rtc_second));
|
||||
|
||||
/* 1st: disable the write protection */
|
||||
RTC_WPK = RTC_UNLOCK_KEY1;
|
||||
RTC_WPK = RTC_UNLOCK_KEY2;
|
||||
|
||||
/* 2nd: enter init mode */
|
||||
error_status = rtc_init_mode_enter();
|
||||
|
||||
if(ERROR != error_status){
|
||||
RTC_PSC = (uint32_t)(PSC_FACTOR_A(rtc_initpara_struct->rtc_factor_asyn)| \
|
||||
PSC_FACTOR_S(rtc_initpara_struct->rtc_factor_syn));
|
||||
|
||||
RTC_TIME = (uint32_t)reg_time;
|
||||
RTC_DATE = (uint32_t)reg_date;
|
||||
|
||||
RTC_CTL &= (uint32_t)(~RTC_CTL_CS);
|
||||
RTC_CTL |= rtc_initpara_struct->rtc_display_format;
|
||||
|
||||
/* 3rd: exit init mode */
|
||||
rtc_init_mode_exit();
|
||||
|
||||
/* 4th: wait the RSYNF flag to set */
|
||||
error_status = rtc_register_sync_wait();
|
||||
}
|
||||
|
||||
/* 5th: enable the write protection */
|
||||
RTC_WPK = RTC_LOCK_KEY;
|
||||
|
||||
return error_status;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enter RTC init mode
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval ErrStatus: ERROR or SUCCESS
|
||||
*/
|
||||
ErrStatus rtc_init_mode_enter(void)
|
||||
{
|
||||
uint32_t time_index = RTC_INITM_TIMEOUT;
|
||||
uint32_t flag_status = RESET;
|
||||
ErrStatus error_status = ERROR;
|
||||
|
||||
/* check whether it has been in init mode */
|
||||
if ((uint32_t)RESET == (RTC_STAT & RTC_STAT_INITF)){
|
||||
RTC_STAT |= RTC_STAT_INITM;
|
||||
|
||||
/* wait until the INITF flag to be set */
|
||||
do{
|
||||
flag_status = RTC_STAT & RTC_STAT_INITF;
|
||||
}while((--time_index > 0U) && ((uint32_t)RESET == flag_status));
|
||||
|
||||
if ((uint32_t)RESET != flag_status){
|
||||
error_status = SUCCESS;
|
||||
}
|
||||
}else{
|
||||
error_status = SUCCESS;
|
||||
}
|
||||
return error_status;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief exit RTC init mode
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rtc_init_mode_exit(void)
|
||||
{
|
||||
RTC_STAT &= (uint32_t)(~RTC_STAT_INITM);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief wait until RTC_TIME and RTC_DATE registers are synchronized with APB clock, and the shadow
|
||||
registers are updated
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval ErrStatus: ERROR or SUCCESS
|
||||
*/
|
||||
ErrStatus rtc_register_sync_wait(void)
|
||||
{
|
||||
volatile uint32_t time_index = RTC_RSYNF_TIMEOUT;
|
||||
uint32_t flag_status = RESET;
|
||||
ErrStatus error_status = ERROR;
|
||||
|
||||
if ((uint32_t)RESET == (RTC_CTL & RTC_CTL_BPSHAD)){
|
||||
/* disable the write protection */
|
||||
RTC_WPK = RTC_UNLOCK_KEY1;
|
||||
RTC_WPK = RTC_UNLOCK_KEY2;
|
||||
|
||||
/* firstly clear RSYNF flag */
|
||||
RTC_STAT &= (uint32_t)(~RTC_STAT_RSYNF);
|
||||
|
||||
/* wait until RSYNF flag to be set */
|
||||
do{
|
||||
flag_status = RTC_STAT & RTC_STAT_RSYNF;
|
||||
}while((--time_index > 0U) && ((uint32_t)RESET == flag_status));
|
||||
|
||||
if ((uint32_t)RESET != flag_status){
|
||||
error_status = SUCCESS;
|
||||
}
|
||||
|
||||
/* enable the write protection */
|
||||
RTC_WPK = RTC_LOCK_KEY;
|
||||
}else{
|
||||
error_status = SUCCESS;
|
||||
}
|
||||
|
||||
return error_status;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get current time and date
|
||||
\param[in] none
|
||||
\param[out] rtc_initpara_struct: pointer to a rtc_parameter_struct structure which contains
|
||||
parameters for initialization of the rtc peripheral
|
||||
members of the structure and the member values are shown as below:
|
||||
rtc_year: 0x0 - 0x99(BCD format)
|
||||
rtc_month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN,
|
||||
RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC
|
||||
rtc_date: 0x1 - 0x31(BCD format)
|
||||
rtc_day_of_week: RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY
|
||||
RTC_FRIDAY, RTC_SATURDAY, RTC_SUNDAY
|
||||
rtc_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format chose
|
||||
rtc_minute: 0x0 - 0x59(BCD format)
|
||||
rtc_second: 0x0 - 0x59(BCD format)
|
||||
rtc_factor_asyn: 0x0 - 0x7F
|
||||
rtc_factor_syn: 0x0 - 0x7FFF
|
||||
rtc_am_pm: RTC_AM, RTC_PM
|
||||
rtc_display_format: RTC_24HOUR, RTC_12HOUR
|
||||
\retval none
|
||||
*/
|
||||
void rtc_current_time_get(rtc_parameter_struct* rtc_initpara_struct)
|
||||
{
|
||||
uint32_t temp_tr = 0U, temp_dr = 0U, temp_pscr = 0U, temp_ctlr = 0U;
|
||||
|
||||
temp_tr = (uint32_t)RTC_TIME;
|
||||
temp_dr = (uint32_t)RTC_DATE;
|
||||
temp_pscr = (uint32_t)RTC_PSC;
|
||||
temp_ctlr = (uint32_t)RTC_CTL;
|
||||
|
||||
/* get current time and construct rtc_parameter_struct structure */
|
||||
rtc_initpara_struct->rtc_year = (uint8_t)GET_DATE_YR(temp_dr);
|
||||
rtc_initpara_struct->rtc_month = (uint8_t)GET_DATE_MON(temp_dr);
|
||||
rtc_initpara_struct->rtc_date = (uint8_t)GET_DATE_DAY(temp_dr);
|
||||
rtc_initpara_struct->rtc_day_of_week = (uint8_t)GET_DATE_DOW(temp_dr);
|
||||
rtc_initpara_struct->rtc_hour = (uint8_t)GET_TIME_HR(temp_tr);
|
||||
rtc_initpara_struct->rtc_minute = (uint8_t)GET_TIME_MN(temp_tr);
|
||||
rtc_initpara_struct->rtc_second = (uint8_t)GET_TIME_SC(temp_tr);
|
||||
rtc_initpara_struct->rtc_factor_asyn = (uint16_t)GET_PSC_FACTOR_A(temp_pscr);
|
||||
rtc_initpara_struct->rtc_factor_syn = (uint16_t)GET_PSC_FACTOR_S(temp_pscr);
|
||||
rtc_initpara_struct->rtc_am_pm = (uint32_t)(temp_pscr & RTC_TIME_PM);
|
||||
rtc_initpara_struct->rtc_display_format = (uint32_t)(temp_ctlr & RTC_CTL_CS);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get current subsecond value
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval current subsecond value
|
||||
*/
|
||||
uint32_t rtc_subsecond_get(void)
|
||||
{
|
||||
uint32_t reg = 0U;
|
||||
/* if BPSHAD bit is reset, reading RTC_SS will lock RTC_TIME and RTC_DATE automatically */
|
||||
reg = (uint32_t)RTC_SS;
|
||||
/* read RTC_DATE to unlock the 3 shadow registers */
|
||||
(void) (RTC_DATE);
|
||||
|
||||
return reg;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure RTC alarm
|
||||
\param[in] rtc_alarm_time: pointer to a rtc_alarm_struct structure which contains
|
||||
parameters for RTC alarm configuration
|
||||
members of the structure and the member values are shown as below:
|
||||
rtc_alarm_mask: RTC_ALARM_NONE_MASK, RTC_ALARM_DATE_MASK, RTC_ALARM_HOUR_MASK
|
||||
RTC_ALARM_MINUTE_MASK, RTC_ALARM_SECOND_MASK, RTC_ALARM_ALL_MASK
|
||||
rtc_weekday_or_date: RTC_ALARM_DATE_SELECTED, RTC_ALARM_WEEKDAY_SELECTED
|
||||
rtc_alarm_day: 1) 0x1 - 0x31(BCD format) if RTC_ALARM_DATE_SELECTED is set
|
||||
2) RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY, RTC_FRIDAY,
|
||||
RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set
|
||||
rtc_alarm_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format
|
||||
rtc_alarm_minute: 0x0 - 0x59(BCD format)
|
||||
rtc_alarm_second: 0x0 - 0x59(BCD format)
|
||||
rtc_am_pm: RTC_AM, RTC_PM
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rtc_alarm_config(rtc_alarm_struct* rtc_alarm_time)
|
||||
{
|
||||
uint32_t reg_alrm0td = 0U;
|
||||
|
||||
reg_alrm0td = (rtc_alarm_time->rtc_alarm_mask | \
|
||||
rtc_alarm_time->rtc_weekday_or_date | \
|
||||
rtc_alarm_time->rtc_am_pm | \
|
||||
ALRM0TD_DAY(rtc_alarm_time->rtc_alarm_day) | \
|
||||
ALRM0TD_HR(rtc_alarm_time->rtc_alarm_hour) | \
|
||||
ALRM0TD_MN(rtc_alarm_time->rtc_alarm_minute) | \
|
||||
ALRM0TD_SC(rtc_alarm_time->rtc_alarm_second));
|
||||
|
||||
/* disable the write protection */
|
||||
RTC_WPK = RTC_UNLOCK_KEY1;
|
||||
RTC_WPK = RTC_UNLOCK_KEY2;
|
||||
|
||||
RTC_ALRM0TD = (uint32_t)reg_alrm0td;
|
||||
|
||||
/* enable the write protection */
|
||||
RTC_WPK = RTC_LOCK_KEY;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure subsecond of RTC alarm
|
||||
\param[in] mask_subsecond: alarm subsecond mask
|
||||
\arg RTC_MASKSSC_0_14: mask alarm subsecond configuration
|
||||
\arg RTC_MASKSSC_1_14: mask RTC_ALRM0SS_SSC[14:1], and RTC_ALRM0SS_SSC[0] is to be compared
|
||||
\arg RTC_MASKSSC_2_14: mask RTC_ALRM0SS_SSC[14:2], and RTC_ALRM0SS_SSC[1:0] is to be compared
|
||||
\arg RTC_MASKSSC_3_14: mask RTC_ALRM0SS_SSC[14:3], and RTC_ALRM0SS_SSC[2:0] is to be compared
|
||||
\arg RTC_MASKSSC_4_14: mask RTC_ALRM0SS_SSC[14:4]], and RTC_ALRM0SS_SSC[3:0] is to be compared
|
||||
\arg RTC_MASKSSC_5_14: mask RTC_ALRM0SS_SSC[14:5], and RTC_ALRM0SS_SSC[4:0] is to be compared
|
||||
\arg RTC_MASKSSC_6_14: mask RTC_ALRM0SS_SSC[14:6], and RTC_ALRM0SS_SSC[5:0] is to be compared
|
||||
\arg RTC_MASKSSC_7_14: mask RTC_ALRM0SS_SSC[14:7], and RTC_ALRM0SS_SSC[6:0] is to be compared
|
||||
\arg RTC_MASKSSC_8_14: mask RTC_ALRM0SS_SSC[14:8], and RTC_ALRM0SS_SSC[7:0] is to be compared
|
||||
\arg RTC_MASKSSC_9_14: mask RTC_ALRM0SS_SSC[14:9], and RTC_ALRM0SS_SSC[8:0] is to be compared
|
||||
\arg RTC_MASKSSC_10_14: mask RTC_ALRM0SS_SSC[14:10], and RTC_ALRM0SS_SSC[9:0] is to be compared
|
||||
\arg RTC_MASKSSC_11_14: mask RTC_ALRM0SS_SSC[14:11], and RTC_ALRM0SS_SSC[10:0] is to be compared
|
||||
\arg RTC_MASKSSC_12_14: mask RTC_ALRM0SS_SSC[14:12], and RTC_ALRM0SS_SSC[11:0] is to be compared
|
||||
\arg RTC_MASKSSC_13_14: mask RTC_ALRM0SS_SSC[14:13], and RTC_ALRM0SS_SSC[12:0] is to be compared
|
||||
\arg RTC_MASKSSC_14: mask RTC_ALRM0SS_SSC[14], and RTC_ALRM0SS_SSC[13:0] is to be compared
|
||||
\arg RTC_MASKSSC_NONE: mask none, and RTC_ALRM0SS_SSC[14:0] is to be compared
|
||||
\param[in] subsecond: alarm subsecond value(0x000 - 0x7FFF)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rtc_alarm_subsecond_config(uint32_t mask_subsecond, uint32_t subsecond)
|
||||
{
|
||||
/* disable the write protection */
|
||||
RTC_WPK = RTC_UNLOCK_KEY1;
|
||||
RTC_WPK = RTC_UNLOCK_KEY2;
|
||||
|
||||
RTC_ALRM0SS = mask_subsecond | subsecond;
|
||||
|
||||
/* enable the write protection */
|
||||
RTC_WPK = RTC_LOCK_KEY;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable RTC alarm
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rtc_alarm_enable(void)
|
||||
{
|
||||
/* disable the write protection */
|
||||
RTC_WPK = RTC_UNLOCK_KEY1;
|
||||
RTC_WPK = RTC_UNLOCK_KEY2;
|
||||
|
||||
RTC_CTL |= RTC_CTL_ALRM0EN;
|
||||
|
||||
/* enable the write protection */
|
||||
RTC_WPK = RTC_LOCK_KEY;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable RTC alarm
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval ErrStatus: ERROR or SUCCESS
|
||||
*/
|
||||
ErrStatus rtc_alarm_disable(void)
|
||||
{
|
||||
volatile uint32_t time_index = RTC_ALRM0WF_TIMEOUT;
|
||||
ErrStatus error_status = ERROR;
|
||||
uint32_t flag_status = RESET;
|
||||
|
||||
/* disable the write protection */
|
||||
RTC_WPK = RTC_UNLOCK_KEY1;
|
||||
RTC_WPK = RTC_UNLOCK_KEY2;
|
||||
|
||||
/* clear the state of alarm */
|
||||
RTC_CTL &= (uint32_t)(~RTC_CTL_ALRM0EN);
|
||||
|
||||
/* wait until ALRM0WF flag to be set after the alarm is disabled */
|
||||
do{
|
||||
flag_status = RTC_STAT & RTC_STAT_ALRM0WF;
|
||||
}while((--time_index > 0U) && ((uint32_t)RESET == flag_status));
|
||||
|
||||
if ((uint32_t)RESET != flag_status){
|
||||
error_status = SUCCESS;
|
||||
}
|
||||
|
||||
/* enable the write protection */
|
||||
RTC_WPK = RTC_LOCK_KEY;
|
||||
|
||||
return error_status;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get RTC alarm
|
||||
\param[in] none
|
||||
\param[out] rtc_alarm_time: pointer to a rtc_alarm_struct structure which contains
|
||||
parameters for RTC alarm configuration
|
||||
members of the structure and the member values are shown as below:
|
||||
rtc_alarm_mask: RTC_ALARM_NONE_MASK, RTC_ALARM_DATE_MASK, RTC_ALARM_HOUR_MASK
|
||||
RTC_ALARM_MINUTE_MASK, RTC_ALARM_SECOND_MASK, RTC_ALARM_ALL_MASK
|
||||
rtc_weekday_or_date: RTC_ALARM_DATE_SELECTED, RTC_ALARM_WEEKDAY_SELECTED
|
||||
rtc_alarm_day: 1) 0x1 - 0x31(BCD format) if RTC_ALARM_DATE_SELECTED is set
|
||||
2) RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY, RTC_FRIDAY,
|
||||
RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set
|
||||
rtc_alarm_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format
|
||||
rtc_alarm_minute: 0x0 - 0x59(BCD format)
|
||||
rtc_alarm_second: 0x0 - 0x59(BCD format)
|
||||
rtc_am_pm: RTC_AM, RTC_PM
|
||||
\retval none
|
||||
*/
|
||||
void rtc_alarm_get(rtc_alarm_struct* rtc_alarm_time)
|
||||
{
|
||||
uint32_t reg_alrm0td = 0U;
|
||||
|
||||
/* get the value of RTC_ALRM0TD register */
|
||||
reg_alrm0td = RTC_ALRM0TD;
|
||||
|
||||
/* get alarm parameters and construct the rtc_alarm_struct structure */
|
||||
rtc_alarm_time->rtc_alarm_mask = reg_alrm0td & RTC_ALARM_ALL_MASK;
|
||||
rtc_alarm_time->rtc_am_pm = (uint32_t)(reg_alrm0td & RTC_ALRM0TD_PM);
|
||||
rtc_alarm_time->rtc_weekday_or_date = (uint32_t)(reg_alrm0td & RTC_ALRM0TD_DOWS);
|
||||
rtc_alarm_time->rtc_alarm_day = (uint8_t)GET_ALRM0TD_DAY(reg_alrm0td);
|
||||
rtc_alarm_time->rtc_alarm_hour = (uint8_t)GET_ALRM0TD_HR(reg_alrm0td);
|
||||
rtc_alarm_time->rtc_alarm_minute = (uint8_t)GET_ALRM0TD_MN(reg_alrm0td);
|
||||
rtc_alarm_time->rtc_alarm_second = (uint8_t)GET_ALRM0TD_SC(reg_alrm0td);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get RTC alarm subsecond
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval RTC alarm subsecond value
|
||||
*/
|
||||
uint32_t rtc_alarm_subsecond_get(void)
|
||||
{
|
||||
return ((uint32_t)(RTC_ALRM0SS & RTC_ALRM0SS_SSC));
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable RTC time-stamp
|
||||
\param[in] edge: specify which edge to detect of time-stamp
|
||||
\arg RTC_TIMESTAMP_RISING_EDGE: rising edge is valid event edge for timestamp event
|
||||
\arg RTC_TIMESTAMP_FALLING_EDGE: falling edge is valid event edge for timestamp event
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rtc_timestamp_enable(uint32_t edge)
|
||||
{
|
||||
uint32_t reg_ctl = 0U;
|
||||
|
||||
/* clear the bits to be configured in RTC_CTL */
|
||||
reg_ctl = (uint32_t)(RTC_CTL & (uint32_t)(~(RTC_CTL_TSEG | RTC_CTL_TSEN)));
|
||||
|
||||
/* new configuration */
|
||||
reg_ctl |= (uint32_t)(edge | RTC_CTL_TSEN);
|
||||
|
||||
/* disable the write protection */
|
||||
RTC_WPK = RTC_UNLOCK_KEY1;
|
||||
RTC_WPK = RTC_UNLOCK_KEY2;
|
||||
|
||||
RTC_CTL = (uint32_t)reg_ctl;
|
||||
|
||||
/* enable the write protection */
|
||||
RTC_WPK = RTC_LOCK_KEY;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable RTC time-stamp
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rtc_timestamp_disable(void)
|
||||
{
|
||||
/* disable the write protection */
|
||||
RTC_WPK = RTC_UNLOCK_KEY1;
|
||||
RTC_WPK = RTC_UNLOCK_KEY2;
|
||||
|
||||
/* clear the TSEN bit */
|
||||
RTC_CTL &= (uint32_t)(~ RTC_CTL_TSEN);
|
||||
|
||||
/* enable the write protection */
|
||||
RTC_WPK = RTC_LOCK_KEY;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get RTC timestamp time and date
|
||||
\param[in] none
|
||||
\param[out] rtc_timestamp: pointer to a rtc_timestamp_struct structure which contains
|
||||
parameters for RTC time-stamp configuration
|
||||
members of the structure and the member values are shown as below:
|
||||
rtc_timestamp_month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN,
|
||||
RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC
|
||||
rtc_timestamp_date: 0x1 - 0x31(BCD format)
|
||||
rtc_timestamp_day: RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY, RTC_FRIDAY,
|
||||
RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set
|
||||
rtc_timestamp_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format
|
||||
rtc_timestamp_minute: 0x0 - 0x59(BCD format)
|
||||
rtc_timestamp_second: 0x0 - 0x59(BCD format)
|
||||
rtc_am_pm: RTC_AM, RTC_PM
|
||||
\retval none
|
||||
*/
|
||||
void rtc_timestamp_get(rtc_timestamp_struct* rtc_timestamp)
|
||||
{
|
||||
uint32_t temp_tts = 0U, temp_dts = 0U;
|
||||
|
||||
/* get the value of time_stamp registers */
|
||||
temp_tts = (uint32_t)RTC_TTS;
|
||||
temp_dts = (uint32_t)RTC_DTS;
|
||||
|
||||
/* get timestamp time and construct the rtc_timestamp_struct structure */
|
||||
rtc_timestamp->rtc_am_pm = (uint32_t)(temp_tts & RTC_TTS_PM);
|
||||
rtc_timestamp->rtc_timestamp_month = (uint8_t)GET_DTS_MON(temp_dts);
|
||||
rtc_timestamp->rtc_timestamp_date = (uint8_t)GET_DTS_DAY(temp_dts);
|
||||
rtc_timestamp->rtc_timestamp_day = (uint8_t)GET_DTS_DOW(temp_dts);
|
||||
rtc_timestamp->rtc_timestamp_hour = (uint8_t)GET_TTS_HR(temp_tts);
|
||||
rtc_timestamp->rtc_timestamp_minute = (uint8_t)GET_TTS_MN(temp_tts);
|
||||
rtc_timestamp->rtc_timestamp_second = (uint8_t)GET_TTS_SC(temp_tts);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get RTC time-stamp subsecond
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval RTC time-stamp subsecond value
|
||||
*/
|
||||
uint32_t rtc_timestamp_subsecond_get(void)
|
||||
{
|
||||
return ((uint32_t)RTC_SSTS);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable RTC tamper
|
||||
\param[in] rtc_tamper: pointer to a rtc_tamper_struct structure which contains
|
||||
parameters for RTC tamper configuration
|
||||
members of the structure and the member values are shown as below:
|
||||
rtc_tamper_source: RTC_TAMPER0, RTC_TAMPER1
|
||||
rtc_tamper_trigger: RTC_TAMPER_TRIGGER_EDGE_RISING, RTC_TAMPER_TRIGGER_EDGE_FALLING
|
||||
RTC_TAMPER_TRIGGER_LEVEL_LOW, RTC_TAMPER_TRIGGER_LEVEL_HIGH
|
||||
rtc_tamper_filter: RTC_FLT_EDGE, RTC_FLT_2S, RTC_FLT_4S, RTC_FLT_8S
|
||||
rtc_tamper_sample_frequency: RTC_FREQ_DIV32768, RTC_FREQ_DIV16384, RTC_FREQ_DIV8192,
|
||||
RTC_FREQ_DIV4096, RTC_FREQ_DIV2048, RTC_FREQ_DIV1024,
|
||||
RTC_FREQ_DIV512, RTC_FREQ_DIV256
|
||||
rtc_tamper_precharge_enable: DISABLE, ENABLE
|
||||
rtc_tamper_precharge_time: RTC_PRCH_1C, RTC_PRCH_2C, RTC_PRCH_4C, RTC_PRCH_8C
|
||||
rtc_tamper_with_timestamp: DISABLE, ENABLE
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rtc_tamper_enable(rtc_tamper_struct* rtc_tamper)
|
||||
{
|
||||
/* disable tamper */
|
||||
RTC_TAMP &= (uint32_t)~(rtc_tamper->rtc_tamper_source);
|
||||
|
||||
/* tamper filter must be used when the tamper source is voltage level detection */
|
||||
RTC_TAMP &= (uint32_t)~RTC_TAMP_FLT;
|
||||
|
||||
/* the tamper source is voltage level detection */
|
||||
if(rtc_tamper->rtc_tamper_filter != RTC_FLT_EDGE ){
|
||||
RTC_TAMP &= (uint32_t)~(RTC_TAMP_DISPU | RTC_TAMP_PRCH | RTC_TAMP_FREQ | RTC_TAMP_FLT);
|
||||
|
||||
/* check if the tamper pin need precharge, if need, then configure the precharge time */
|
||||
if(DISABLE == rtc_tamper->rtc_tamper_precharge_enable){
|
||||
RTC_TAMP |= (uint32_t)RTC_TAMP_DISPU;
|
||||
}else{
|
||||
RTC_TAMP |= (uint32_t)(rtc_tamper->rtc_tamper_precharge_time);
|
||||
}
|
||||
|
||||
RTC_TAMP |= (uint32_t)(rtc_tamper->rtc_tamper_sample_frequency);
|
||||
RTC_TAMP |= (uint32_t)(rtc_tamper->rtc_tamper_filter);
|
||||
}
|
||||
|
||||
RTC_TAMP &= (uint32_t)~RTC_TAMP_TPTS;
|
||||
|
||||
if(DISABLE != rtc_tamper->rtc_tamper_with_timestamp){
|
||||
/* the tamper event also cause a time-stamp event */
|
||||
RTC_TAMP |= (uint32_t)RTC_TAMP_TPTS;
|
||||
}
|
||||
|
||||
/* configure the tamper trigger */
|
||||
RTC_TAMP &= ((uint32_t)~((rtc_tamper->rtc_tamper_source) << RTC_TAMPER_TRIGGER_POS));
|
||||
if(RTC_TAMPER_TRIGGER_EDGE_RISING != rtc_tamper->rtc_tamper_trigger){
|
||||
RTC_TAMP |= (uint32_t)((rtc_tamper->rtc_tamper_source)<< RTC_TAMPER_TRIGGER_POS);
|
||||
}
|
||||
/* enable tamper */
|
||||
RTC_TAMP |= (uint32_t)(rtc_tamper->rtc_tamper_source);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable RTC tamper
|
||||
\param[in] source: specify which tamper source to be disabled
|
||||
\arg RTC_TAMPER0
|
||||
\arg RTC_TAMPER1
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rtc_tamper_disable(uint32_t source)
|
||||
{
|
||||
/* disable tamper */
|
||||
RTC_TAMP &= (uint32_t)~source;
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable specified RTC interrupt
|
||||
\param[in] interrupt: specify which interrupt source to be enabled
|
||||
\arg RTC_INT_TIMESTAMP: timestamp interrupt
|
||||
\arg RTC_INT_ALARM: alarm interrupt
|
||||
\arg RTC_INT_TAMP: tamp interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rtc_interrupt_enable(uint32_t interrupt)
|
||||
{
|
||||
/* disable the write protection */
|
||||
RTC_WPK = RTC_UNLOCK_KEY1;
|
||||
RTC_WPK = RTC_UNLOCK_KEY2;
|
||||
|
||||
/* enable the interrupts in RTC_CTL register */
|
||||
RTC_CTL |= (uint32_t)(interrupt & (uint32_t)~RTC_TAMP_TPIE);
|
||||
/* enable the interrupts in RTC_TAMP register */
|
||||
RTC_TAMP |= (uint32_t)(interrupt & RTC_TAMP_TPIE);
|
||||
|
||||
/* enable the write protection */
|
||||
RTC_WPK = RTC_LOCK_KEY;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disble specified RTC interrupt
|
||||
\param[in] interrupt: specify which interrupt source to be disabled
|
||||
\arg RTC_INT_TIMESTAMP: timestamp interrupt
|
||||
\arg RTC_INT_ALARM: alarm interrupt
|
||||
\arg RTC_INT_TAMP: tamp interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rtc_interrupt_disable(uint32_t interrupt)
|
||||
{
|
||||
/* disable the write protection */
|
||||
RTC_WPK = RTC_UNLOCK_KEY1;
|
||||
RTC_WPK = RTC_UNLOCK_KEY2;
|
||||
|
||||
/* disable the interrupts in RTC_CTL register */
|
||||
RTC_CTL &= (uint32_t)~(interrupt & (uint32_t)~RTC_TAMP_TPIE);
|
||||
/* disable the interrupts in RTC_TAMP register */
|
||||
RTC_TAMP &= (uint32_t)~(interrupt & RTC_TAMP_TPIE);
|
||||
|
||||
/* enable the write protection */
|
||||
RTC_WPK = RTC_LOCK_KEY;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief check specified flag
|
||||
\param[in] flag: specify which flag to check
|
||||
\arg RTC_FLAG_RECALIBRATION: recalibration pending flag
|
||||
\arg RTC_FLAG_TAMP1: tamper 1 event flag
|
||||
\arg RTC_FLAG_TAMP0: tamper 0 event flag
|
||||
\arg RTC_FLAG_TIMESTAMP_OVERFLOW: time-stamp overflow event flag
|
||||
\arg RTC_FLAG_TIMESTAMP: time-stamp event flag
|
||||
\arg RTC_FLAG_ALARM0: alarm event flag
|
||||
\arg RTC_FLAG_INIT: init mode event flag
|
||||
\arg RTC_FLAG_RSYN: time and date registers synchronized event flag
|
||||
\arg RTC_FLAG_YCM: year parameter configured event flag
|
||||
\arg RTC_FLAG_SHIFT: shift operation pending flag
|
||||
\arg RTC_FLAG_ALARM0_WRITTEN: alarm writen available flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus rtc_flag_get(uint32_t flag)
|
||||
{
|
||||
FlagStatus flag_state = RESET;
|
||||
|
||||
if ((uint32_t)RESET != (RTC_STAT & flag)){
|
||||
flag_state = SET;
|
||||
}
|
||||
return flag_state;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear specified flag
|
||||
\param[in] flag: specify which flag to clear
|
||||
\arg RTC_FLAG_TAMP1: tamper 1 event flag
|
||||
\arg RTC_FLAG_TAMP0: tamper 0 event flag
|
||||
\arg RTC_FLAG_TIMESTAMP_OVERFLOW: time-stamp overflow event flag
|
||||
\arg RTC_FLAG_TIMESTAMP: time-stamp event flag
|
||||
\arg RTC_FLAG_ALARM0: alarm event flag
|
||||
\arg RTC_FLAG_RSYN: time and date registers synchronized event flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rtc_flag_clear(uint32_t flag)
|
||||
{
|
||||
RTC_STAT &= (uint32_t)(~flag);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure rtc alternate output source
|
||||
\param[in] source: specify signal to output
|
||||
\arg RTC_CALIBRATION_512HZ: when the LXTAL freqency is 32768Hz and the RTC_PSC
|
||||
is the default value, output 512Hz signal
|
||||
\arg RTC_CALIBRATION_1HZ: when the LXTAL freqency is 32768Hz and the RTC_PSC
|
||||
is the default value, output 512Hz signal
|
||||
\arg RTC_ALARM_HIGH: when the alarm flag is set, the output pin is high
|
||||
\arg RTC_ALARM_LOW: when the Alarm flag is set, the output pin is low
|
||||
\param[in] mode: specify the output pin (PC13) mode when output alarm signal
|
||||
\arg RTC_ALARM_OUTPUT_OD: open drain mode
|
||||
\arg RTC_ALARM_OUTPUT_PP: push pull mode
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rtc_alter_output_config(uint32_t source, uint32_t mode)
|
||||
{
|
||||
/* disable the write protection */
|
||||
RTC_WPK = RTC_UNLOCK_KEY1;
|
||||
RTC_WPK = RTC_UNLOCK_KEY2;
|
||||
|
||||
RTC_CTL &= (uint32_t)~(RTC_CTL_COEN | RTC_CTL_OS | RTC_CTL_OPOL | RTC_CTL_COS);
|
||||
|
||||
RTC_CTL |= (uint32_t)(source);
|
||||
|
||||
/* alarm output */
|
||||
if((uint32_t)RESET != (source & RTC_OS_ENABLE)){
|
||||
RTC_TAMP &= (uint32_t)~(RTC_TAMP_PC13VAL);
|
||||
RTC_TAMP |= (uint32_t)(mode);
|
||||
}
|
||||
|
||||
/* enable the write protection */
|
||||
RTC_WPK = RTC_LOCK_KEY;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief ajust the daylight saving time by adding or substracting one hour from the current time
|
||||
\param[in] operation: hour ajustment operation
|
||||
\arg RTC_CTL_A1H: add one hour
|
||||
\arg RTC_CTL_S1H: substract one hour
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rtc_hour_adjust(uint32_t operation)
|
||||
{
|
||||
/* disable the write protection */
|
||||
RTC_WPK = RTC_UNLOCK_KEY1;
|
||||
RTC_WPK = RTC_UNLOCK_KEY2;
|
||||
|
||||
RTC_CTL |= (uint32_t)(operation);
|
||||
|
||||
/* enable the write protection */
|
||||
RTC_WPK = RTC_LOCK_KEY;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable RTC bypass shadow registers function
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rtc_bypass_shadow_enable(void)
|
||||
{
|
||||
/* disable the write protection */
|
||||
RTC_WPK = RTC_UNLOCK_KEY1;
|
||||
RTC_WPK = RTC_UNLOCK_KEY2;
|
||||
|
||||
RTC_CTL |= (uint8_t)RTC_CTL_BPSHAD;
|
||||
|
||||
/* enable the write protection */
|
||||
RTC_WPK = RTC_LOCK_KEY;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable RTC bypass shadow registers function
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void rtc_bypass_shadow_disable(void)
|
||||
{
|
||||
/* disable the write protection */
|
||||
RTC_WPK = RTC_UNLOCK_KEY1;
|
||||
RTC_WPK = RTC_UNLOCK_KEY2;
|
||||
|
||||
RTC_CTL &= (uint8_t)~RTC_CTL_BPSHAD;
|
||||
|
||||
/* enable the write protection */
|
||||
RTC_WPK = RTC_LOCK_KEY;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable RTC reference clock detection function
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval ErrStatus: ERROR or SUCCESS
|
||||
*/
|
||||
ErrStatus rtc_refclock_detection_enable(void)
|
||||
{
|
||||
ErrStatus error_status = ERROR;
|
||||
|
||||
/* disable the write protection */
|
||||
RTC_WPK = RTC_UNLOCK_KEY1;
|
||||
RTC_WPK = RTC_UNLOCK_KEY2;
|
||||
|
||||
/* enter init mode */
|
||||
error_status = rtc_init_mode_enter();
|
||||
|
||||
if(ERROR != error_status){
|
||||
RTC_CTL |= (uint32_t)RTC_CTL_REFEN;
|
||||
/* exit init mode */
|
||||
rtc_init_mode_exit();
|
||||
}
|
||||
|
||||
/* enable the write protection */
|
||||
RTC_WPK = RTC_LOCK_KEY;
|
||||
|
||||
return error_status;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable RTC reference clock detection function
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval ErrStatus: ERROR or SUCCESS
|
||||
*/
|
||||
ErrStatus rtc_refclock_detection_disable(void)
|
||||
{
|
||||
ErrStatus error_status = ERROR;
|
||||
|
||||
/* disable the write protection */
|
||||
RTC_WPK = RTC_UNLOCK_KEY1;
|
||||
RTC_WPK = RTC_UNLOCK_KEY2;
|
||||
|
||||
/* enter init mode */
|
||||
error_status = rtc_init_mode_enter();
|
||||
|
||||
if(ERROR != error_status){
|
||||
RTC_CTL &= (uint32_t)~RTC_CTL_REFEN;
|
||||
/* exit init mode */
|
||||
rtc_init_mode_exit();
|
||||
}
|
||||
|
||||
/* enable the write protection */
|
||||
RTC_WPK = RTC_LOCK_KEY;
|
||||
|
||||
return error_status;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief ajust RTC second or subsecond value of current time
|
||||
\param[in] add: add 1s to current time or not
|
||||
\arg RTC_SHIFT_ADD1S_RESET: no effect
|
||||
\arg RTC_SHIFT_ADD1S_SET: add 1s to current time
|
||||
\param[in] minus: number of subsecond to minus from current time(0x0 - 0x7FFF)
|
||||
\param[out] none
|
||||
\retval ErrStatus: ERROR or SUCCESS
|
||||
*/
|
||||
ErrStatus rtc_second_ajust(uint32_t add, uint32_t minus)
|
||||
{
|
||||
uint32_t time_index = RTC_SHIFTCTL_TIMEOUT;
|
||||
ErrStatus error_status = ERROR;
|
||||
uint32_t flag_status = RESET;
|
||||
uint32_t temp=0U;
|
||||
|
||||
/* disable the write protection */
|
||||
RTC_WPK = RTC_UNLOCK_KEY1;
|
||||
RTC_WPK = RTC_UNLOCK_KEY2;
|
||||
|
||||
/* check if a shift operation is ongoing */
|
||||
do{
|
||||
flag_status = RTC_STAT & RTC_STAT_SOPF;
|
||||
}while((--time_index > 0U) && ((uint32_t)RESET != flag_status));
|
||||
|
||||
temp = RTC_CTL & RTC_CTL_REFEN;
|
||||
/* check if the function of reference clock detection is disabled */
|
||||
if(((uint32_t)RESET == flag_status) && (RESET == temp)){
|
||||
RTC_SHIFTCTL = (uint32_t)(add | SHIFTCTL_SFS(minus));
|
||||
error_status = rtc_register_sync_wait();
|
||||
}
|
||||
|
||||
/* enable the write protection */
|
||||
RTC_WPK = RTC_LOCK_KEY;
|
||||
|
||||
return error_status;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure RTC calibration register
|
||||
\param[in] window: select calibration window
|
||||
\arg RTC_CALIBRATION_WINDOW_32S: 2exp20 RTCCLK cycles, 32s if RTCCLK = 32768 Hz
|
||||
\arg RTC_CALIBRATION_WINDOW_16S: 2exp19 RTCCLK cycles, 16s if RTCCLK = 32768 Hz
|
||||
\arg RTC_CALIBRATION_WINDOW_8S: 2exp18 RTCCLK cycles, 8s if RTCCLK = 32768 Hz
|
||||
\param[in] plus: add RTC clock or not
|
||||
\arg RTC_CALIBRATION_PLUS_SET: add one RTC clock every 2048 rtc clock
|
||||
\arg RTC_CALIBRATION_PLUS_RESET: no effect
|
||||
\param[in] minus: the RTC clock to minus during the calibration window(0x0 - 0x1FF)
|
||||
\param[out] none
|
||||
\retval ErrStatus: ERROR or SUCCESS
|
||||
*/
|
||||
ErrStatus rtc_calibration_config(uint32_t window, uint32_t plus, uint32_t minus)
|
||||
{
|
||||
uint32_t time_index = RTC_HRFC_TIMEOUT;
|
||||
ErrStatus error_status = ERROR;
|
||||
uint32_t flag_status = RESET;
|
||||
|
||||
/* disable the write protection */
|
||||
RTC_WPK = RTC_UNLOCK_KEY1;
|
||||
RTC_WPK = RTC_UNLOCK_KEY2;
|
||||
|
||||
/* check if a calibration operation is ongoing */
|
||||
do{
|
||||
flag_status = RTC_STAT & RTC_STAT_SCPF;
|
||||
}while((--time_index > 0U) && ((uint32_t)RESET != flag_status));
|
||||
|
||||
if((uint32_t)RESET == flag_status){
|
||||
RTC_HRFC = (uint32_t)(window | plus | HRFC_CMSK(minus));
|
||||
error_status = SUCCESS;
|
||||
}
|
||||
|
||||
/* enable the write protection */
|
||||
RTC_WPK = RTC_LOCK_KEY;
|
||||
|
||||
return error_status;
|
||||
}
|
445
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_slcd.c
Normal file
445
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_slcd.c
Normal file
@@ -0,0 +1,445 @@
|
||||
/*!
|
||||
\file gd32f1x0_slcd.c
|
||||
\brief SLCD driver
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2017 GigaDevice
|
||||
|
||||
2014-12-26, V1.0.0, platform GD32F1x0(x=3,5)
|
||||
2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9)
|
||||
2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
*/
|
||||
|
||||
#ifdef GD32F170_190
|
||||
#include "gd32f1x0_slcd.h"
|
||||
#include "gd32f1x0_rcu.h"
|
||||
|
||||
/*!
|
||||
\brief SLCD reset
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void slcd_deinit(void)
|
||||
{
|
||||
rcu_periph_reset_enable(RCU_SLCDRST);
|
||||
rcu_periph_reset_disable(RCU_SLCDRST);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the SLCD status flag
|
||||
\param[in] slcd_flag: the adc status flag bits
|
||||
\arg SLCD_FLAG_ON: SLCD controller on flag
|
||||
\arg SLCD_FLAG_SOF: start of frame flag
|
||||
\arg SLCD_FLAG_UPR: SLCD data update request flag
|
||||
\arg SLCD_FLAG_UPD: update LCDS data done flag
|
||||
\arg SLCD_FLAG_VRDY: SLCD voltage ready flag
|
||||
\arg SLCD_FLAG_SYN: SLCD CFG register synchronization flag
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus slcd_flag_get(uint8_t slcd_flag)
|
||||
{
|
||||
if(SLCD_STAT & slcd_flag){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the SLCD interrupt flag
|
||||
\param[in] slcd_interrupt: the adc interrupt flag bits
|
||||
\arg SLCD_INT_FLAG_SOF: start of frame interrupt
|
||||
\arg SLCD_INT_FLAG_UPD: SLCD update done interrupt
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus slcd_interrupt_flag_get(uint8_t slcd_interrupt)
|
||||
{
|
||||
FlagStatus interrupt_flag = RESET;
|
||||
uint32_t state;
|
||||
/* check the interrupt bits */
|
||||
switch(slcd_interrupt){
|
||||
case SLCD_INT_FLAG_SOF:
|
||||
state = SLCD_STAT & SLCD_FLAG_SOF;
|
||||
if((SLCD_CFG & SLCD_CFG_SOFIE) && state){
|
||||
interrupt_flag = SET;
|
||||
}
|
||||
break;
|
||||
case SLCD_INT_FLAG_UPD:
|
||||
state = SLCD_STAT & SLCD_FLAG_UPD;
|
||||
if((SLCD_CFG & SLCD_CFG_UPDIE) && state){
|
||||
interrupt_flag = SET;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return interrupt_flag;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear the SLCD flag
|
||||
\param[in] slcd_flag: the adc status flag bits
|
||||
\arg SLCD_FLAG_SOF: start of frame flag
|
||||
\arg SLCD_FLAG_UPD: update LCDS data done flag
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void slcd_flag_clear(uint8_t slcd_flag)
|
||||
{
|
||||
/* check the interrupt bits */
|
||||
switch(slcd_flag){
|
||||
case SLCD_FLAG_SOF:
|
||||
SLCD_STATC |= SLCD_STATC_SOFC;
|
||||
break;
|
||||
case SLCD_FLAG_UPD:
|
||||
SLCD_STATC |= SLCD_STATC_UPDC;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear the SLCD interrupt flag
|
||||
\param[in] slcd_interrupt: the adc interrupt bits
|
||||
\arg SLCD_INT_FLAG_SOF: start of frame interrupt
|
||||
\arg SLCD_INT_FLAG_UPD: SLCD update done interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void slcd_interrupt_flag_clear(uint8_t slcd_interrupt)
|
||||
{
|
||||
/* check the interrupt bits */
|
||||
switch(slcd_interrupt){
|
||||
case SLCD_INT_FLAG_SOF:
|
||||
SLCD_STATC |= SLCD_STATC_SOFC;
|
||||
break;
|
||||
case SLCD_INT_FLAG_UPD:
|
||||
SLCD_STATC |= SLCD_STATC_UPDC;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief the SLCD interrupt config
|
||||
\param[in] slcd_interrupt: the adc interrupt bits
|
||||
\arg SLCD_INT_SOF: start of frame interrupt
|
||||
\arg SLCD_INT_UPD: SLCD update done interrupt
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void slcd_interrupt_config(uint8_t slcd_interrupt,ControlStatus newvalue)
|
||||
{
|
||||
/* ENABLE or DISABLE the interrupt */
|
||||
if(newvalue){
|
||||
/* select the interrupt source */
|
||||
switch(slcd_interrupt){
|
||||
case SLCD_INT_SOF:
|
||||
SLCD_CFG |= (uint32_t) SLCD_CFG_SOFIE;
|
||||
break;
|
||||
case SLCD_INT_UPD:
|
||||
SLCD_CFG |= (uint32_t) SLCD_CFG_UPDIE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
switch(slcd_interrupt){
|
||||
/* select the interrupt source */
|
||||
case SLCD_INT_SOF:
|
||||
SLCD_CFG &= (uint32_t)~(SLCD_CFG_SOFIE);
|
||||
break;
|
||||
case SLCD_INT_UPD:
|
||||
SLCD_CFG &= (uint32_t)~(SLCD_CFG_UPDIE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief SLCD bias voltage select
|
||||
\param[in] bias_voltage: the SLCD voltage bias
|
||||
\arg SLCD_BIAS_1_4: 1/4 voltage bias
|
||||
\arg SLCD_BIAS_1_2: 1/2 voltage bias
|
||||
\arg SLCD_BIAS_1_3: 1/3 voltage bias
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void slcd_bias_voltage_select(uint32_t bias_voltage)
|
||||
{
|
||||
SLCD_CTL &= (uint32_t)~(SLCD_CTL_BIAS);
|
||||
SLCD_CTL |= (uint32_t)bias_voltage;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief SLCD duty cycle select
|
||||
\param[in] duty: the adc flag bits
|
||||
\arg SLCD_DUTY_STATIC: static dutycycle
|
||||
\arg SLCD_DUTY_1_2: 1/2 dutycycle
|
||||
\arg SLCD_DUTY_1_3: 1/3 dutycycle
|
||||
\arg SLCD_DUTY_1_4: 1/4 dutycycle
|
||||
\arg SLCD_DUTY_1_6: 1/6 dutycycle
|
||||
\arg SLCD_DUTY_1_8: 1/8 dutycycle
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void slcd_duty_select(uint32_t duty)
|
||||
{
|
||||
SLCD_CTL &= (uint32_t)~(SLCD_CTL_DUTY);
|
||||
SLCD_CTL |= (uint32_t)duty;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief config the prescaler and the divider of SLCD clock
|
||||
fSLCD = finclk/( pow( 2 , PRE )* DIV )
|
||||
\param[in] prescaler: the prescaler factor
|
||||
\arg SLCD_PRESCALER_1: PRE = 0
|
||||
\arg SLCD_PRESCALER_2: PRE = 1
|
||||
\arg SLCD_PRESCALER_4: PRE = 2
|
||||
\arg SLCD_PRESCALER_8: PRE = 3
|
||||
\arg SLCD_PRESCALER_16: PRE = 4
|
||||
\arg SLCD_PRESCALER_32: PRE = 5
|
||||
\arg SLCD_PRESCALER_64: PRE = 6
|
||||
\arg SLCD_PRESCALER_128: PRE = 7
|
||||
\arg SLCD_PRESCALER_256: PRE = 8
|
||||
\arg SLCD_PRESCALER_512: PRE = 9
|
||||
\arg SLCD_PRESCALER_1024: PRE = 10
|
||||
\arg SLCD_PRESCALER_2048: PRE = 11
|
||||
\arg SLCD_PRESCALER_4096: PRE = 12
|
||||
\arg SLCD_PRESCALER_8192: PRE = 13
|
||||
\arg SLCD_PRESCALER_16384: PRE = 14
|
||||
\arg SLCD_PRESCALER_32768: PRE = 15
|
||||
\param[in] divider: the divider factor
|
||||
\arg SLCD_DIVIDER_x: x= 16..31 ,DIV = 16..31
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void slcd_clock_config(uint32_t prescaler,uint32_t divider)
|
||||
{
|
||||
uint32_t cfg;
|
||||
|
||||
/* config the prescaler and the divider */
|
||||
cfg = SLCD_CFG;
|
||||
cfg &= (uint32_t)~(SLCD_CFG_PSC | SLCD_CFG_DIV);
|
||||
cfg |= (uint32_t)(prescaler | divider);
|
||||
SLCD_CFG = cfg;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief SLCD blink mode config
|
||||
\param[in] mode: the prescaler factor
|
||||
\arg SLCD_BLINKMODE_OFF: blink disabled
|
||||
\arg SLCD_BLINKMODE_SEG0_COM0: blink enabled on SEG[0], COM[0]
|
||||
\arg SLCD_BLINKMODE_SEG0_ALLCOM: blink enabled on SEG[0], all COM
|
||||
\arg SLCD_BLINKMODE_ALLSEG_ALLCOM: blink enabled on all SEG and all COM
|
||||
\param[in] blink_divider: the divider factor
|
||||
\arg SLCD_BLINK_FREQUENCY_DIV8: blink frequency = fSLCD/8
|
||||
\arg SLCD_BLINK_FREQUENCY_DIV16: blink frequency = fSLCD/16
|
||||
\arg SLCD_BLINK_FREQUENCY_DIV32: blink frequency = fSLCD/32
|
||||
\arg SLCD_BLINK_FREQUENCY_DIV64: blink frequency = fSLCD/64
|
||||
\arg SLCD_BLINK_FREQUENCY_DIV128: blink frequency = fSLCD/128
|
||||
\arg SLCD_BLINK_FREQUENCY_DIV256: blink frequency = fSLCD/256
|
||||
\arg SLCD_BLINK_FREQUENCY_DIV512: blink frequency = fSLCD/512
|
||||
\arg SLCD_BLINK_FREQUENCY_DIV1024: blink frequency = fSLCD/1024
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void slcd_blink_mode_config(uint32_t mode,uint32_t blink_divider)
|
||||
{
|
||||
SLCD_CFG &= (uint32_t)~(SLCD_CFG_BLKMOD | SLCD_CFG_BLKDIV);
|
||||
SLCD_CFG |= (uint32_t)(mode | blink_divider);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief SLCD contrast ratio config
|
||||
\param[in] contrast_ratio: specify the VSLCD voltage ,when chosing the internal voltage source
|
||||
\arg SLCD_CONTRAST_LEVEL_0: maximum SLCD Voltage = 2.60V
|
||||
\arg SLCD_CONTRAST_LEVEL_1: maximum SLCD Voltage = 2.73V
|
||||
\arg SLCD_CONTRAST_LEVEL_2: maximum SLCD Voltage = 2.86V
|
||||
\arg SLCD_CONTRAST_LEVEL_3: maximum SLCD Voltage = 2.99V
|
||||
\arg SLCD_CONTRAST_LEVEL_4: maximum SLCD Voltage = 3.12V
|
||||
\arg SLCD_CONTRAST_LEVEL_5: maximum SLCD Voltage = 3.25V
|
||||
\arg SLCD_CONTRAST_LEVEL_6: maximum SLCD Voltage = 3.38V
|
||||
\arg SLCD_CONTRAST_LEVEL_7: maximum SLCD Voltage = 3.51V
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void slcd_contrast_ratio_config(uint32_t contrast_ratio)
|
||||
{
|
||||
uint32_t cfg;
|
||||
|
||||
/* config the contrast ratio */
|
||||
cfg = SLCD_CFG;
|
||||
cfg &= (uint32_t)~(SLCD_CFG_CONR);
|
||||
cfg |= (uint32_t)contrast_ratio;
|
||||
SLCD_CFG = cfg;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief SLCD dead time duration config
|
||||
\param[in] dead_time: configure the length of the dead time between frames
|
||||
\arg SLCD_DEADTIME_PERIOD_0: no dead time
|
||||
\arg SLCD_DEADTIME_PERIOD_1: 1 phase inserted between couple of frame
|
||||
\arg SLCD_DEADTIME_PERIOD_2: 2 phase inserted between couple of frame
|
||||
\arg SLCD_DEADTIME_PERIOD_3: 3 phase inserted between couple of frame
|
||||
\arg SLCD_DEADTIME_PERIOD_4: 4 phase inserted between couple of frame
|
||||
\arg SLCD_DEADTIME_PERIOD_5: 5 phase inserted between couple of frame
|
||||
\arg SLCD_DEADTIME_PERIOD_6: 6 phase inserted between couple of frame
|
||||
\arg SLCD_DEADTIME_PERIOD_7: 7 phase inserted between couple of frame
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void slcd_dead_time_config(uint32_t dead_time)
|
||||
{
|
||||
uint32_t cfg;
|
||||
|
||||
/* config dead time duration */
|
||||
cfg = SLCD_CFG;
|
||||
cfg &= (uint32_t)~(SLCD_CFG_DTD);
|
||||
cfg |= (uint32_t)dead_time;
|
||||
SLCD_CFG = cfg;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief SLCD pulse on duration config
|
||||
\param[in] duration: configure the length of the dead time between frames
|
||||
\arg SLCD_PULSEON_DURATION_0: pulse on duration = 0
|
||||
\arg SLCD_PULSEON_DURATION_1: pulse on duration = 1*1/fPRE
|
||||
\arg SLCD_PULSEON_DURATION_2: pulse on duration = 2*1/fPRE
|
||||
\arg SLCD_PULSEON_DURATION_3: pulse on duration = 3*1/fPRE
|
||||
\arg SLCD_PULSEON_DURATION_4: pulse on duration = 4*1/fPRE
|
||||
\arg SLCD_PULSEON_DURATION_5: pulse on duration = 5*1/fPRE
|
||||
\arg SLCD_PULSEON_DURATION_6: pulse on duration = 6*1/fPRE
|
||||
\arg SLCD_PULSEON_DURATION_7: pulse on duration = 7*1/fPRE
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void slcd_pulse_on_duration_config(uint32_t duration)
|
||||
{
|
||||
uint32_t cfg;
|
||||
|
||||
/* config pulse on duration */
|
||||
cfg = SLCD_CFG;
|
||||
cfg &= (uint32_t)~(SLCD_CFG_PULSE);
|
||||
cfg |= (uint32_t)duration;
|
||||
SLCD_CFG = cfg;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief SLCD common/segment pad select
|
||||
\param[in] NewValue: ENABLE or DISABLE
|
||||
\arg ENABLE: LCD_COM[7:4] pad select LCD_SEG[31:28]
|
||||
\arg DISABLE: LCD_COM[7:4] pad select LCD_COM[7:4]
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void slcd_com_seg_remap(ControlStatus newvalue)
|
||||
{
|
||||
if( ENABLE == newvalue ){
|
||||
SLCD_CTL |= SLCD_CTL_COMS;
|
||||
}else{
|
||||
SLCD_CTL &= ~(SLCD_CTL_COMS);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief SLCD voltage source select
|
||||
\param[in] voltage_source: the SLCD voltage source
|
||||
\arg SLCD_VOLTAGE_INTERNAL: internal source
|
||||
\arg SLCD_VOLTAGE_EXTERNAL: external source (VSLCD pin)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void slcd_voltage_source_select(uint8_t voltage_source)
|
||||
{
|
||||
if( SLCD_VOLTAGE_EXTERNAL == voltage_source ){
|
||||
SLCD_CTL |= SLCD_CTL_VSRC;
|
||||
}else{
|
||||
SLCD_CTL &= ~(SLCD_CTL_VSRC);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable or disable permanent high drive
|
||||
\param[in] NewValue: ENABLE or DISABLE
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void slcd_high_drive_config(ControlStatus newvalue)
|
||||
{
|
||||
if( ENABLE == newvalue ){
|
||||
SLCD_CFG |= SLCD_CFG_HDEN;
|
||||
}else{
|
||||
SLCD_CFG &= ~(SLCD_CFG_HDEN);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief SLCD voltage source select
|
||||
\param[in] data_reg: the SLCD data register
|
||||
\arg SLCD_DATA_REG0: SLCD_DATA register 0
|
||||
\arg SLCD_DATA_REG1: SLCD_DATA Register 1
|
||||
\arg SLCD_DATA_REG2: SLCD_DATA register 2
|
||||
\arg SLCD_DATA_REG3: SLCD_DATA Register 3
|
||||
\arg SLCD_DATA_REG4: SLCD_DATA register 4
|
||||
\arg SLCD_DATA_REG5: SLCD_DATA Register 5
|
||||
\arg SLCD_DATA_REG6: SLCD_DATA register 6
|
||||
\arg SLCD_DATA_REG7: SLCD_DATA Register 7
|
||||
\param[in] data: the data write to the register
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void slcd_data_register_write(uint32_t data_reg,uint32_t data)
|
||||
{
|
||||
volatile uint32_t *pdata;
|
||||
|
||||
/* point to DATA register */
|
||||
pdata = &SLCD_DATA0;
|
||||
|
||||
/* wtite data word to DATA register */
|
||||
*(pdata + data_reg) = (uint32_t)data;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief SLCD data update request
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void slcd_data_update_request(void)
|
||||
{
|
||||
SLCD_STAT |= SLCD_STAT_UPRF;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable SLCD interface
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void slcd_enable(void)
|
||||
{
|
||||
SLCD_CTL |= SLCD_CTL_LCDON;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable SLCD interface
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void slcd_disable(void)
|
||||
{
|
||||
SLCD_CTL &= ~(SLCD_CTL_LCDON);
|
||||
}
|
||||
|
||||
#endif /* GD32F170_190 */
|
679
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_spi.c
Normal file
679
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_spi.c
Normal file
@@ -0,0 +1,679 @@
|
||||
/*!
|
||||
\file gd32f1x0_spi.c
|
||||
\brief SPI driver
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2017 GigaDevice
|
||||
|
||||
2014-12-26, V1.0.0, platform GD32F1x0(x=3,5)
|
||||
2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9)
|
||||
2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
*/
|
||||
|
||||
#include "gd32f1x0_spi.h"
|
||||
|
||||
#define SPI_INIT_MASK ((uint32_t)0x00003040U)
|
||||
#define I2S_INIT_MASK ((uint32_t)0x0000F047U)
|
||||
#define SPI_I2SPSC_RESET ((uint32_t)0x00000002U) /*!< I2S clock prescaler register reset value */
|
||||
|
||||
/*!
|
||||
\brief reset SPI and I2S
|
||||
\param[in] spi_periph: SPIx(x=0,1,2)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void spi_i2s_deinit(uint32_t spi_periph)
|
||||
{
|
||||
switch(spi_periph){
|
||||
case SPI0:
|
||||
/* reset SPI0 and I2S0 */
|
||||
rcu_periph_reset_enable(RCU_SPI0RST);
|
||||
rcu_periph_reset_disable(RCU_SPI0RST);
|
||||
break;
|
||||
case SPI1:
|
||||
/* reset SPI1 */
|
||||
rcu_periph_reset_enable(RCU_SPI1RST);
|
||||
rcu_periph_reset_disable(RCU_SPI1RST);
|
||||
break;
|
||||
case SPI2:
|
||||
/* reset SPI2 and I2S2 */
|
||||
rcu_periph_reset_enable(RCU_SPI2RST);
|
||||
rcu_periph_reset_disable(RCU_SPI2RST);
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize SPI parameter
|
||||
\param[in] spi_periph: SPIx(x=0,1,2)
|
||||
\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;
|
||||
|
||||
/* select SPI mode */
|
||||
SPI_I2SCTL(spi_periph) &= (uint32_t)(~SPI_I2SCTL_I2SSEL);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable SPI
|
||||
\param[in] spi_periph: SPIx(x=0,1,2)
|
||||
\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)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void spi_disable(uint32_t spi_periph)
|
||||
{
|
||||
SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_SPIEN);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure I2S prescaler
|
||||
\param[in] spi_periph: SPIx(only x=0,2)
|
||||
\param[in] audiosample: I2S audio sample rate
|
||||
\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] frameformat: I2S data length and channel length
|
||||
\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] mckout: I2S master clock output
|
||||
\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 audiosample,uint32_t frameformat,uint32_t mckout)
|
||||
{
|
||||
uint32_t i2sdiv = 2U, i2sof = 0U;
|
||||
uint32_t clks = 0U;
|
||||
uint32_t i2sclock = 0U;
|
||||
|
||||
/* deinit SPI_I2SPSC register */
|
||||
SPI_I2SPSC(spi_periph) = SPI_I2SPSC_RESET;
|
||||
|
||||
/* get system clock */
|
||||
i2sclock =rcu_clock_freq_get(CK_SYS);
|
||||
/* config the prescaler depending on the mclk output state, the frame format and audio sample rate */
|
||||
if(I2S_MCKOUT_ENABLE == mckout){
|
||||
clks = (uint32_t)(((i2sclock / 256U) * 10U) / audiosample);
|
||||
}else{
|
||||
if(I2S_FRAMEFORMAT_DT16B_CH16B == frameformat){
|
||||
clks = (uint32_t)(((i2sclock / 32U) *10U ) / audiosample);
|
||||
}else{
|
||||
clks = (uint32_t)(((i2sclock / 64U) *10U ) / audiosample);
|
||||
}
|
||||
}
|
||||
/* remove the flaoting 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 | 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)frameformat;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize I2S parameter
|
||||
\param[in] spi_periph: SPIx(only x=0,2)
|
||||
\param[in] mode: I2S operation 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] standard: 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] ckpl: I2S idle state clock polarity
|
||||
\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 mode,uint32_t standard,uint32_t ckpl)
|
||||
{
|
||||
uint32_t reg= 0U;
|
||||
reg= SPI_I2SCTL(spi_periph);
|
||||
reg &= I2S_INIT_MASK;
|
||||
|
||||
/* enable I2S */
|
||||
reg |= (uint32_t)SPI_I2SCTL_I2SSEL;
|
||||
/* select I2S mode */
|
||||
reg |= (uint32_t)mode;
|
||||
/* select I2S standard */
|
||||
reg |= (uint32_t)standard;
|
||||
/* select I2S polarity */
|
||||
reg |= (uint32_t)ckpl;
|
||||
/* write to SPI_I2SCTL register */
|
||||
SPI_I2SCTL(spi_periph) = (uint32_t)reg;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief I2S enable
|
||||
\param[in] spi_periph: SPIx(x=0,2)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2s_enable(uint32_t spi_periph)
|
||||
{
|
||||
SPI_I2SCTL(spi_periph) |= (uint32_t)SPI_I2SCTL_I2SEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief I2S disable
|
||||
\param[in] spi_periph: SPIx(x=0,2)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void i2s_disable(uint32_t spi_periph)
|
||||
{
|
||||
SPI_I2SCTL(spi_periph) &= (uint32_t)(~SPI_I2SCTL_I2SEN);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief SPI NSS output enable
|
||||
\param[in] spi_periph: SPIx(x=0,1,2)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void spi_nss_output_enable(uint32_t spi_periph)
|
||||
{
|
||||
SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_NSSDRV;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief SPI NSS output disable
|
||||
\param[in] spi_periph: SPIx(x=0,1,2)
|
||||
\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)
|
||||
\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)
|
||||
\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)
|
||||
\param[in] dma: SPI DMA mode
|
||||
\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 dma)
|
||||
{
|
||||
if(SPI_DMA_TRANSMIT == dma){
|
||||
SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_DMATEN;
|
||||
}else{
|
||||
SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_DMAREN;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable SPI DMA send or receive
|
||||
\param[in] spi_periph: SPIx(x=0,1,2)
|
||||
\param[in] dma: SPI DMA mode
|
||||
\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 dma)
|
||||
{
|
||||
if(SPI_DMA_TRANSMIT == 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)
|
||||
\param[in] frame_format: SPI frame size
|
||||
\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)
|
||||
\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)
|
||||
\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)
|
||||
\param[in] transfer_direction: SPI transfer direction
|
||||
\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 enable SPI and I2S interrupt
|
||||
\param[in] spi_periph: SPIx(x=0,1,2)
|
||||
\param[in] interrupt:
|
||||
\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
|
||||
\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)
|
||||
\param[in] interrupt:
|
||||
\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
|
||||
\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)
|
||||
\param[in] interrupt: SPI/I2S interrupt flag status
|
||||
\arg SPI_I2S_INT_FLAG_TBE: transmit buffer empty interrupt.
|
||||
\arg SPI_I2S_INT_FLAG_RBNE: receive buffer not empty interrupt.
|
||||
\arg SPI_I2S_INT_FLAG_RXORERR: overrun interrupt.
|
||||
\arg SPI_INT_FLAG_CONFERR: config error interrupt.
|
||||
\arg SPI_INT_FLAG_CRCERR: CRC error interrupt.
|
||||
\arg I2S_INT_FLAG_TXURERR: underrun error interrupt.
|
||||
\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;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
/*get SPI/I2S interrupt flag status */
|
||||
if(reg1 && reg2){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get SPI and I2S flag status
|
||||
\param[in] spi_periph: SPIx(x=0,1,2)
|
||||
\param[in] flag: SPI/I2S flag status
|
||||
\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 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.
|
||||
\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 clear SPI CRC error flag status
|
||||
\param[in] spi_periph: SPIx(x=0,1,2)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void spi_crc_error_clear(uint32_t spi_periph)
|
||||
{
|
||||
SPI_STAT(spi_periph) &= (uint32_t)(~SPI_FLAG_CRCERR);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief turn on CRC function
|
||||
\param[in] spi_periph: SPIx(x=0,1,2)
|
||||
\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 CRC function
|
||||
\param[in] spi_periph: SPIx(x=0,1,2)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void spi_crc_off(uint32_t spi_periph)
|
||||
{
|
||||
SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_CRCEN);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief set CRC polynomial
|
||||
\param[in] spi_periph: SPIx(x=0,1,2)
|
||||
\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)
|
||||
\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 SPI next data is CRC value
|
||||
\param[in] spi_periph: SPIx(x=0,1,2)
|
||||
\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)
|
||||
\param[in] crc: SPI CRC value
|
||||
\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 crc)
|
||||
{
|
||||
if(SPI_CRC_TX == crc){
|
||||
return ((uint16_t)(SPI_TCRC(spi_periph)));
|
||||
}else{
|
||||
return ((uint16_t)(SPI_RCRC(spi_periph)));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef GD32F170_190
|
||||
/*!
|
||||
\brief enable quad wire SPI
|
||||
\param[in] spi_periph: SPIx(only x=1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void qspi_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=1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void qspi_disable(uint32_t spi_periph)
|
||||
{
|
||||
SPI_QCTL(spi_periph) &= ~SPI_QCTL_QMOD ;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable quad wire SPI write
|
||||
\param[in] spi_periph: SPIx(only x=1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void qspi_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=1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void qspi_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=1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void qspi_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=1)
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void qspi_io23_output_disable(uint32_t spi_periph)
|
||||
{
|
||||
SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_IO23_DRV);
|
||||
}
|
||||
#endif /* GD32F170_190 */
|
214
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_syscfg.c
Normal file
214
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_syscfg.c
Normal file
@@ -0,0 +1,214 @@
|
||||
/*!
|
||||
\file gd32f1x0_syscfg.c
|
||||
\brief SYSCFG driver
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2017 GigaDevice
|
||||
|
||||
2014-12-26, V1.0.0, platform GD32F1x0(x=3,5)
|
||||
2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9)
|
||||
2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
*/
|
||||
|
||||
#include "gd32f1x0_syscfg.h"
|
||||
|
||||
/*!
|
||||
\brief reset the SYSCFG registers
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void syscfg_deinit(void)
|
||||
{
|
||||
rcu_periph_reset_enable(RCU_CFGCMPRST);
|
||||
rcu_periph_reset_disable(RCU_CFGCMPRST);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable the DMA channels remapping
|
||||
\param[in] syscfg_dma_remap: specify the DMA channels to remap
|
||||
\arg SYSCFG_DMA_REMAP_TIMER16: remap TIMER16 channel0 and UP DMA requests to channel1(defaut channel0)
|
||||
\arg SYSCFG_DMA_REMAP_TIMER15: remap TIMER15 channel2 and UP DMA requests to channel3(defaut channel2)
|
||||
\arg SYSCFG_DMA_REMAP_USART0RX: remap USART0 Rx DMA request to channel4(default channel2)
|
||||
\arg SYSCFG_DMA_REMAP_USART0TX: remap USART0 Tx DMA request to channel3(default channel1)
|
||||
\arg SYSCFG_DMA_REMAP_ADC: remap ADC DMA requests from channel0 to channel1
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void syscfg_dma_remap_enable(uint32_t syscfg_dma_remap)
|
||||
{
|
||||
SYSCFG_CFG0 |= syscfg_dma_remap;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable the DMA channels remapping
|
||||
\param[in] syscfg_dma_remap: specify the DMA channels to remap
|
||||
\arg SYSCFG_DMA_REMAP_TIMER16: remap TIMER16 channel0 and UP DMA requests to channel1(defaut channel0)
|
||||
\arg SYSCFG_DMA_REMAP_TIMER15: remap TIMER15 channel2 and UP DMA requests to channel3(defaut channel2)
|
||||
\arg SYSCFG_DMA_REMAP_USART0RX: remap USART0 Rx DMA request to channel4(default channel2)
|
||||
\arg SYSCFG_DMA_REMAP_USART0TX: remap USART0 Tx DMA request to channel3(default channel1)
|
||||
\arg SYSCFG_DMA_REMAP_ADC: remap ADC DMA requests from channel0 to channel1
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void syscfg_dma_remap_disable(uint32_t syscfg_dma_remap)
|
||||
{
|
||||
SYSCFG_CFG0 &= ~syscfg_dma_remap;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable PB9 high current capability
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void syscfg_high_current_enable(void)
|
||||
{
|
||||
SYSCFG_CFG0 |= SYSCFG_HIGH_CURRENT_ENABLE;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable PB9 high current capability
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void syscfg_high_current_disable(void)
|
||||
{
|
||||
SYSCFG_CFG0 &= SYSCFG_HIGH_CURRENT_DISABLE;
|
||||
}
|
||||
|
||||
#ifdef GD32F170_190
|
||||
/*!
|
||||
\brief configure the VLCD intermediate voltage rail
|
||||
\param[in] vlcd_bias: specify VLCD bias
|
||||
\arg VLCD_BIAS1_2_RAIL1: VLCD bias is 1/2, using rail1
|
||||
\arg VLCD_BIAS1_2_RAIL2: VLCD bias is 1/2, using rail2
|
||||
\arg VLCD_BIAS1_2_RAIL3: VLCD bias is 1/2, using rail3
|
||||
\arg VLCD_BIAS1_3_RAIL1_2: VLCD bias is 1/3, using rail1 and rail2
|
||||
\arg VLCD_BIAS1_3_RAIL1_3: VLCD bias is 1/3, using rail1 and rail3
|
||||
\arg VLCD_BIAS1_4_RAILALL: VLCD bias is 1/4, using all rails
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void syscfg_vlcd_rail_config(uint8_t vlcd_bias)
|
||||
{
|
||||
uint32_t cfg1 = SYSCFG_CFG1;
|
||||
|
||||
/* Clear system configuration register 1 */
|
||||
SYSCFG_CFG1 = 0U;
|
||||
|
||||
switch(vlcd_bias){
|
||||
/* according to VLCD bias, configure rails combination */
|
||||
case VLCD_BIAS1_2_RAIL1:
|
||||
SYSCFG_CFG1 |= SYSCFG_VLCD_RAIL1;
|
||||
break;
|
||||
case VLCD_BIAS1_2_RAIL2:
|
||||
SYSCFG_CFG1 |= SYSCFG_VLCD_RAIL2;
|
||||
break;
|
||||
case VLCD_BIAS1_2_RAIL3:
|
||||
SYSCFG_CFG1 |= SYSCFG_VLCD_RAIL3;
|
||||
break;
|
||||
case VLCD_BIAS1_3_RAIL1_2:
|
||||
SYSCFG_CFG1 |= SYSCFG_VLCD_RAIL2 | SYSCFG_VLCD_RAIL1;
|
||||
break;
|
||||
case VLCD_BIAS1_3_RAIL1_3:
|
||||
SYSCFG_CFG1 |= SYSCFG_VLCD_RAIL3 | SYSCFG_VLCD_RAIL1;
|
||||
break;
|
||||
case VLCD_BIAS1_4_RAILALL:
|
||||
SYSCFG_CFG1 |= SYSCFG_VLCD_RAIL3 | SYSCFG_VLCD_RAIL2 | SYSCFG_VLCD_RAIL1;
|
||||
break;
|
||||
default:
|
||||
SYSCFG_CFG1 = cfg1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* GD32F170_190 */
|
||||
|
||||
/*!
|
||||
\brief configure the GPIO pin as EXTI Line
|
||||
\param[in] exti_port: specify the GPIO port used in EXTI
|
||||
\arg EXTI_SOURCE_GPIOx(x = A,B,C,D,F): EXTI GPIO port
|
||||
\param[in] exti_pin: specify the EXTI line
|
||||
\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 connect TIMER0/14/15/16 break input to the selected parameter
|
||||
\param[in] syscfg_lock: Specify the parameter to be connected
|
||||
\arg SYSCFG_LOCK_LOCKUP: Cortex-M3 lockup output connected to the break input
|
||||
\arg SYSCFG_LOCK_SRAM_PARITY_ERROR: SRAM_PARITY check error connected to the break input
|
||||
\arg SYSCFG_LOCK_LVD: LVD interrupt connected to the break input
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void syscfg_lock_config(uint32_t syscfg_lock)
|
||||
{
|
||||
SYSCFG_CFG2 |= syscfg_lock;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief check if the specified flag in SYSCFG_CFG2 is set or not.
|
||||
\param[in] syscfg_flag: specify the flag in SYSCFG_CFG2 to check.
|
||||
\arg SYSCFG_SRAM_PCEF: SRAM parity check error flag.
|
||||
\param[out] none
|
||||
\retval the syscfg_flag state returned (SET or RESET).
|
||||
*/
|
||||
FlagStatus syscfg_flag_get(uint32_t syscfg_flag)
|
||||
{
|
||||
if((SYSCFG_CFG2 & syscfg_flag) != (uint32_t)RESET){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear the flag in SYSCFG_CFG2 by writing 1.
|
||||
\param[in] syscfg_flag: Specify the flag in SYSCFG_CFG2 to clear.
|
||||
\arg SYSCFG_SRAM_PCEF: SRAM parity check error flag.
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void syscfg_flag_clear(uint32_t syscfg_flag)
|
||||
{
|
||||
SYSCFG_CFG2 |= (uint32_t) syscfg_flag;
|
||||
}
|
1887
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_timer.c
Normal file
1887
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_timer.c
Normal file
File diff suppressed because it is too large
Load Diff
518
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_tsi.c
Normal file
518
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_tsi.c
Normal file
@@ -0,0 +1,518 @@
|
||||
/*!
|
||||
\file gd32f1x0_tsi.c
|
||||
\brief TSI driver
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2017 GigaDevice
|
||||
|
||||
2014-12-26, V1.0.0, platform GD32F1x0(x=3,5)
|
||||
2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9)
|
||||
2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
*/
|
||||
|
||||
#include "gd32f1x0_tsi.h"
|
||||
#include "gd32f1x0_rcu.h"
|
||||
|
||||
/*!
|
||||
\brief reset TSI peripheral
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tsi_deinit(void)
|
||||
{
|
||||
rcu_periph_reset_enable(RCU_TSIRST);
|
||||
rcu_periph_reset_disable(RCU_TSIRST);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize TSI plus prescaler,charge plus,transfer plus,max cycle number
|
||||
\param[in] prescaler: CTCLK clock division factor
|
||||
\arg TSI_CTCDIV_DIV1: fCTCLK = fHCLK
|
||||
\arg TSI_CTCDIV_DIV2: fCTCLK = fHCLK/2
|
||||
\arg TSI_CTCDIV_DIV4: fCTCLK = fHCLK/4
|
||||
\arg TSI_CTCDIV_DIV8: fCTCLK = fHCLK/8
|
||||
\arg TSI_CTCDIV_DIV16: fCTCLK = fHCLK/16
|
||||
\arg TSI_CTCDIV_DIV32: fCTCLK = fHCLK/32
|
||||
\arg TSI_CTCDIV_DIV64: fCTCLK = fHCLK/64
|
||||
\arg TSI_CTCDIV_DIV128: fCTCLK = fHCLK/128
|
||||
\param[in] charge_duration: charge state duration time
|
||||
\arg TSI_CHARGE_1CTCLK(x=1..16): the duration time of charge state is x CTCLK
|
||||
\param[in] transfer_duration: charge transfer state duration time
|
||||
\arg TSI_TRANSFER_xCTCLK(x=1..16): the duration time of transfer state is x CTCLK
|
||||
\param[in] max_number: max cycle number
|
||||
\arg TSI_MAXNUM255: the max cycle number of a sequence is 255
|
||||
\arg TSI_MAXNUM511: the max cycle number of a sequence is 511
|
||||
\arg TSI_MAXNUM1023: the max cycle number of a sequence is 1023
|
||||
\arg TSI_MAXNUM2047: the max cycle number of a sequence is 2047
|
||||
\arg TSI_MAXNUM4095: the max cycle number of a sequence is 4095
|
||||
\arg TSI_MAXNUM8191: the max cycle number of a sequence is 8191
|
||||
\arg TSI_MAXNUM16383: the max cycle number of a sequence is 16383
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tsi_init(uint32_t prescaler,uint32_t charge_duration,uint32_t transfer_duration,uint32_t max_number)
|
||||
{
|
||||
if(RESET == (TSI_CTL & TSI_CTL_TSIS)){
|
||||
uint32_t ctl;
|
||||
ctl = TSI_CTL;
|
||||
/*configure TSI clock division factor,charge state duration time,charge transfer state duration time */
|
||||
ctl &= ~(TSI_CTL_CTCDIV|TSI_CTL_CTDT|TSI_CTL_CDT|TSI_CTL_MCN);
|
||||
ctl |= (prescaler|charge_duration|transfer_duration|max_number);
|
||||
TSI_CTL = ctl;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable sample pin
|
||||
\param[in] sample: sample pin
|
||||
\arg TSI_SAMPCFG_GxPy( x=0..5,y=0..3):pin y of group x is sample pin
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tsi_sample_pin_enable(uint32_t sample)
|
||||
{
|
||||
if(RESET == (TSI_CTL & TSI_CTL_TSIS)){
|
||||
TSI_SAMPCFG |= sample;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable sample pin
|
||||
\param[in] sample: sample pin
|
||||
\arg TSI_SAMPCFG_GxPy( x=0..5,y=0..3): pin y of group x is sample pin
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tsi_sample_pin_disable(uint32_t sample)
|
||||
{
|
||||
if(RESET == (TSI_CTL & TSI_CTL_TSIS)){
|
||||
TSI_SAMPCFG &= ~sample;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable channel pin
|
||||
\param[in] channel: channel pin
|
||||
\arg TSI_CHCFG_GxPy( x=0..5,y=0..3): pin y of group x
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tsi_channel_pin_enable(uint32_t channel)
|
||||
{
|
||||
TSI_CHCFG |= channel;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable channel pin
|
||||
\param[in] channel: channel pin
|
||||
\arg TSI_CHCFG_GxPy( x=0..5,y=0..3): pin y of group x
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tsi_channel_pin_disable(uint32_t channel)
|
||||
{
|
||||
TSI_CHCFG &= ~channel;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure charge plus and transfer plus
|
||||
\param[in] prescaler: CTCLK clock division factor
|
||||
\arg TSI_CTCDIV_DIV1: fCTCLK = fHCLK
|
||||
\arg TSI_CTCDIV_DIV2: fCTCLK = fHCLK/2
|
||||
\arg TSI_CTCDIV_DIV4: fCTCLK = fHCLK/4
|
||||
\arg TSI_CTCDIV_DIV8: fCTCLK = fHCLK/6
|
||||
\arg TSI_CTCDIV_DIV16: fCTCLK = fHCLK/8
|
||||
\arg TSI_CTCDIV_DIV32: fCTCLK = fHCLK/32
|
||||
\arg TSI_CTCDIV_DIV64: fCTCLK = fHCLK/64
|
||||
\arg TSI_CTCDIV_DIV128: fCTCLK = fHCLK/128
|
||||
\param[in] charge_duration: charge state duration time
|
||||
\arg TSI_CHARGE_xCTCLK(x=1..16): the duration time of charge state is x CTCLK
|
||||
\param[in] transfer_duration: charge transfer state duration time
|
||||
\arg TSI_TRANSFER_xCTCLK(x=1..16): the duration time of transfer state is x CTCLK
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tsi_plus_config(uint32_t prescaler,uint32_t charge_duration,uint32_t transfer_duration)
|
||||
{
|
||||
if(RESET == (TSI_CTL & TSI_CTL_TSIS)){
|
||||
uint32_t ctl;
|
||||
ctl = TSI_CTL;
|
||||
/*configure TSI clock division factor,charge state duration time,charge transfer state duration time */
|
||||
ctl &= ~(TSI_CTL_CTCDIV|TSI_CTL_CTDT|TSI_CTL_CDT);
|
||||
ctl |= (prescaler|charge_duration|transfer_duration);
|
||||
TSI_CTL = ctl;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure TSI triggering by software
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tsi_sofeware_mode_config(void)
|
||||
{
|
||||
if(RESET == (TSI_CTL & TSI_CTL_TSIS)){
|
||||
TSI_CTL &= ~TSI_CTL_TRGMOD;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure TSI triggering by hardware
|
||||
\param[in] trigger_edge: the edge type in hardware trigger mode
|
||||
\arg TSI_FALLING_TRIGGER: falling edge trigger TSI charge transfer sequence
|
||||
\arg TSI_RISING_TRIGGER: rising edge trigger TSI charge transfer sequence
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tsi_hardware_mode_config(uint8_t trigger_edge)
|
||||
{
|
||||
if(RESET == (TSI_CTL & TSI_CTL_TSIS)){
|
||||
/*enable hardware mode*/
|
||||
TSI_CTL |= TSI_CTL_TRGMOD;
|
||||
/*configure the edge type in hardware trigger mode*/
|
||||
if(TSI_FALLING_TRIGGER == (uint32_t)trigger_edge){
|
||||
TSI_CTL &= ~TSI_CTL_EGSEL;
|
||||
}else{
|
||||
TSI_CTL |= TSI_CTL_EGSEL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure TSI pin mode when charge-transfer sequence is IDLE
|
||||
\param[in] pin_mode: pin mode when charge-transfer sequence is IDLE
|
||||
\arg TSI_OUTPUT_LOW: TSI pin will output low when IDLE
|
||||
\arg TSI_INPUT_FLOATING: TSI pin will keep input_floating when IDLE
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tsi_pin_mode_config(uint8_t pin_mode)
|
||||
{
|
||||
if(RESET == (TSI_CTL & TSI_CTL_TSIS)){
|
||||
if(TSI_OUTPUT_LOW == pin_mode){
|
||||
TSI_CTL &= ~TSI_CTL_PINMOD;
|
||||
}else{
|
||||
TSI_CTL |= TSI_CTL_PINMOD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure the max cycle number of a charge-transfer sequence
|
||||
\param[in] max_number: max cycle number
|
||||
\arg TSI_MAXNUM255: the max cycle number of a sequence is 255
|
||||
\arg TSI_MAXNUM511: the max cycle number of a sequence is 511
|
||||
\arg TSI_MAXNUM1023: the max cycle number of a sequence is 1023
|
||||
\arg TSI_MAXNUM2047: the max cycle number of a sequence is 2047
|
||||
\arg TSI_MAXNUM4095: the max cycle number of a sequence is 4095
|
||||
\arg TSI_MAXNUM8191: the max cycle number of a sequence is 8191
|
||||
\arg TSI_MAXNUM16383: the max cycle number of a sequence is 16383
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tsi_max_number_config(uint32_t max_number)
|
||||
{
|
||||
if(RESET == (TSI_CTL & TSI_CTL_TSIS)){
|
||||
uint32_t maxnum;
|
||||
maxnum = TSI_CTL;
|
||||
/*configure the max cycle number of a charge-transfer sequence*/
|
||||
maxnum &= ~TSI_CTL_MCN;
|
||||
maxnum |= max_number;
|
||||
TSI_CTL = maxnum;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief start a charge-transfer sequence when TSI is in software trigger mode
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tsi_software_start(void)
|
||||
{
|
||||
TSI_CTL |= TSI_CTL_TSIS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief stop a charge-transfer sequence when TSI is in software trigger mode
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tsi_software_stop(void)
|
||||
{
|
||||
TSI_CTL &= ~TSI_CTL_TSIS;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable TSI module
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tsi_enable(void)
|
||||
{
|
||||
TSI_CTL |= TSI_CTL_TSIEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable TSI module
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tsi_disable(void)
|
||||
{
|
||||
TSI_CTL &= ~TSI_CTL_TSIEN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief configure extend charge state
|
||||
\param[in] extend: enable or disable extend charge state
|
||||
\arg ENABLE: enable extend charge state
|
||||
\arg DISABLE: disable extend charge state
|
||||
\param[in] prescaler: ECCLK clock division factor
|
||||
\arg TSI_EXTEND_DIV1: fECCLK = fHCLK
|
||||
\arg TSI_EXTEND_DIV2: fECCLK = fHCLK/2
|
||||
\param[in] max_duration: value range 1...128,extend charge state maximum duration time is 1*tECCLK~128*tECCLK
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tsi_extend_charge_config(ControlStatus extend,uint8_t prescaler,uint32_t max_duration)
|
||||
{
|
||||
if(RESET == (TSI_CTL & TSI_CTL_TSIS)){
|
||||
uint32_t ctl;
|
||||
if(DISABLE == extend){
|
||||
/*disable extend charge state*/
|
||||
TSI_CTL &= ~TSI_CTL_ECEN;
|
||||
}else{
|
||||
/*configure extend charge state maximum duration time*/
|
||||
ctl = TSI_CTL;
|
||||
ctl &= ~TSI_CTL_ECDT;
|
||||
ctl |= TSI_EXTENDMAX((uint32_t)(max_duration-1U));
|
||||
TSI_CTL = ctl;
|
||||
/*configure ECCLK clock division factor*/
|
||||
if(TSI_EXTEND_DIV1 == prescaler){
|
||||
TSI_CTL &= ~TSI_CTL_ECDIV;
|
||||
}else{
|
||||
TSI_CTL |= TSI_CTL_ECDIV;
|
||||
}
|
||||
/*enable extend charge state*/
|
||||
TSI_CTL |= TSI_CTL_ECEN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable TSI interrupt
|
||||
\param[in] source: select interrupt which will be enabled
|
||||
\arg TSI_INT_CTCF: charge-transfer complete flag interrupt enable
|
||||
\arg TSI_INTEN_MNERR: max cycle number error interrupt enable
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tsi_interrupt_enable(uint32_t source)
|
||||
{
|
||||
TSI_INTEN |= source;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disable TSI interrupt
|
||||
\param[in] source: select interrupt which will be disabled
|
||||
\arg TSI_INT_CTCF: charge-transfer complete flag interrupt disable
|
||||
\arg TSI_INTEN_MNERR: max cycle number error interrupt disable
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tsi_interrupt_disable(uint32_t source)
|
||||
{
|
||||
TSI_INTEN &= ~source;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief clear flag
|
||||
\param[in] source: select flag which will be cleared
|
||||
\arg TSI_INT_FLAG_CTC: clear charge-transfer complete flag
|
||||
\arg TSI_INT_FLAG_MNERR: clear max cycle number error
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tsi_interrupt_flag_clear(uint32_t flag)
|
||||
{
|
||||
TSI_INTC |= flag;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get TSI module current status
|
||||
\param[in] status:
|
||||
\arg TSI_INT_FLAG_CTC: charge-transfer complete flag
|
||||
\arg TSI_INT_FLAG_MNERR: max Cycle Number Error
|
||||
\param[out] none
|
||||
\retval FlagStatus:SET or RESET
|
||||
*/
|
||||
FlagStatus tsi_interrupt_flag_get(uint32_t status)
|
||||
{
|
||||
if(TSI_INTF & status){
|
||||
return SET;
|
||||
} else {
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief switch on hysteresis pin
|
||||
\param[in] group_pin: select pin which will be switched on hysteresis
|
||||
\arg TSI_PHM_GxPy(x=0..5,y=0..3): pin y of group x switch on hysteresis
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tsi_hysteresis_on(uint32_t group_pin)
|
||||
{
|
||||
TSI_PHM |= group_pin;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief switch off hysteresis pin
|
||||
\param[in] group_pin: select pin which will be switched off hysteresis
|
||||
\arg TSI_PHM_GxPy(x=0..5,y=0..3): pin y of group x switch off hysteresis
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tsi_hysteresis_off(uint32_t group_pin)
|
||||
{
|
||||
TSI_PHM &= ~group_pin;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief switch on analog pin
|
||||
\param[in] group_pin: select pin which will be switched on analog
|
||||
\arg TSI_ASW_GxPy(x=0..5,y=0..3):pin y of group x switch on analog
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tsi_analog_on(uint32_t group_pin)
|
||||
{
|
||||
TSI_ASW |= group_pin;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief switch off analog pin
|
||||
\param[in] group_pin: select pin which will be switched off analog
|
||||
\arg TSI_ASW_GxPy(x=0..5,y=0..3):pin y of group x switch off analog
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tsi_analog_off(uint32_t group_pin)
|
||||
{
|
||||
TSI_ASW &= ~group_pin;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enbale group
|
||||
\param[in] group: select group to be enabled
|
||||
\arg TSI_GCTL_GEx(x=0..5): the x group will be enabled
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tsi_group_enable(uint32_t group)
|
||||
{
|
||||
TSI_GCTL |= group;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief disbale group
|
||||
\param[in] group: select group to be disabled
|
||||
\arg TSI_GCTL_GEx(x=0..5):the x group will be disabled
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void tsi_group_disable(uint32_t group)
|
||||
{
|
||||
TSI_GCTL &= ~group;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get group complete status
|
||||
\param[in] group: select group
|
||||
\arg TSI_GCTL_GCx(x=0..5): get the complete status of group x
|
||||
\param[out] none
|
||||
\retval FlagStatus: group complete status,SET or RESET
|
||||
*/
|
||||
FlagStatus tsi_group_status_get(uint32_t group)
|
||||
{
|
||||
if(TSI_GCTL & group){
|
||||
return SET;
|
||||
}else{
|
||||
return RESET;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the cycle number for group0 as soon as a charge-transfer sequence completes
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval group0 cycle number
|
||||
*/
|
||||
uint16_t tsi_group0_cycle_get(void)
|
||||
{
|
||||
return (uint16_t)TSI_G0CYCN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the cycle number for group1 as soon as a charge-transfer sequence completes
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval group1 cycle number
|
||||
*/
|
||||
uint16_t tsi_group1_cycle_get(void)
|
||||
{
|
||||
return (uint16_t)TSI_G1CYCN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the cycle number for group2 as soon as a charge-transfer sequence completes
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval group2 cycle number
|
||||
*/
|
||||
uint16_t tsi_group2_cycle_get(void)
|
||||
{
|
||||
return (uint16_t)TSI_G2CYCN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the cycle number for group3 as soon as a charge-transfer sequence completes
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval group3 cycle number
|
||||
*/
|
||||
uint16_t tsi_group3_cycle_get(void)
|
||||
{
|
||||
return (uint16_t)TSI_G3CYCN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the cycle number for group4 as soon as a charge-transfer sequence completes
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval group4 cycle number
|
||||
*/
|
||||
uint16_t tsi_group4_cycle_get(void)
|
||||
{
|
||||
return (uint16_t)TSI_G4CYCN;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief get the cycle number for group5 as soon as a charge-transfer sequence completes
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval group5 cycle number
|
||||
*/
|
||||
uint16_t tsi_group5_cycle_get(void)
|
||||
{
|
||||
return (uint16_t)TSI_G5CYCN;
|
||||
}
|
1162
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_usart.c
Normal file
1162
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_usart.c
Normal file
File diff suppressed because it is too large
Load Diff
121
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_wwdgt.c
Normal file
121
Drivers/GD32F1x0_standard_peripheral/Source/gd32f1x0_wwdgt.c
Normal file
@@ -0,0 +1,121 @@
|
||||
/*!
|
||||
\file gd32f1x0_wwdgt.c
|
||||
\brief WWDGT driver
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (C) 2017 GigaDevice
|
||||
|
||||
2014-12-26, V1.0.0, platform GD32F1x0(x=3,5)
|
||||
2016-01-15, V2.0.0, platform GD32F1x0(x=3,5,7,9)
|
||||
2016-04-30, V3.0.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
2017-06-19, V3.1.0, firmware update for GD32F1x0(x=3,5,7,9)
|
||||
*/
|
||||
|
||||
#include "gd32f1x0_wwdgt.h"
|
||||
#include "gd32f1x0_rcu.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 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)
|
||||
{
|
||||
uint32_t reg = 0U;
|
||||
|
||||
reg = WWDGT_CTL & (~WWDGT_CTL_CNT);
|
||||
reg |= (uint32_t)(CTL_CNT((uint32_t)counter_value));
|
||||
|
||||
WWDGT_CTL = (uint32_t)reg;
|
||||
}
|
||||
|
||||
/*!
|
||||
\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 counter value, window value, and prescaler divider value
|
||||
\param[in] counter: 0x00 - 0x7F
|
||||
\param[in] window: 0x00 - 0x7F
|
||||
\param[in] prescaler: wwdgt prescaler value
|
||||
\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)
|
||||
{
|
||||
uint32_t reg_cfg = 0U, reg_ctl = 0U;
|
||||
|
||||
/* clear WIN and PSC bits, clear CNT bit */
|
||||
reg_cfg = WWDGT_CFG &(~(WWDGT_CFG_WIN | WWDGT_CFG_PSC));
|
||||
reg_ctl = WWDGT_CTL &(~(uint32_t)WWDGT_CTL_CNT);
|
||||
|
||||
/* configure WIN and PSC bits, configure CNT bit */
|
||||
reg_cfg |= (uint32_t)(CFG_WIN(window));
|
||||
reg_cfg |= (uint32_t)(prescaler);
|
||||
reg_ctl |= (uint32_t)(CTL_CNT(counter));
|
||||
|
||||
WWDGT_CFG = (uint32_t)reg_cfg;
|
||||
WWDGT_CTL = (uint32_t)reg_ctl;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief enable early wakeup interrupt of WWDGT
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void wwdgt_interrupt_enable(void)
|
||||
{
|
||||
WWDGT_CFG |= WWDGT_CFG_EWIE;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief check early wakeup interrupt state of WWDGT
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval FlagStatus: SET or RESET
|
||||
*/
|
||||
FlagStatus wwdgt_flag_get(void)
|
||||
{
|
||||
if(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)(~(uint32_t)WWDGT_STAT_EWIF);
|
||||
}
|
Reference in New Issue
Block a user