initial commit

This commit is contained in:
2024-04-12 00:32:45 +08:00
commit f618a56836
86 changed files with 44937 additions and 0 deletions

View File

@@ -0,0 +1,870 @@
/**
**************************************************************************
* @file at32f403a_407_adc.c
* @brief contains all the functions for the adc firmware library
**************************************************************************
* Copyright notice & Disclaimer
*
* The software Board Support Package (BSP) that is made available to
* download from Artery official website is the copyrighted work of Artery.
* Artery authorizes customers to use, copy, and distribute the BSP
* software and its related documentation for the purpose of design and
* development in conjunction with Artery microcontrollers. Use of the
* software is governed by this copyright notice and the following disclaimer.
*
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
*
**************************************************************************
*/
#include "at32f403a_407_conf.h"
/** @addtogroup AT32F403A_407_periph_driver
* @{
*/
/** @defgroup ADC
* @brief ADC driver modules
* @{
*/
#ifdef ADC_MODULE_ENABLED
/** @defgroup ADC_private_functions
* @{
*/
/**
* @brief deinitialize the adc peripheral registers to their default reset values.
* @param adc_x: select the adc peripheral.
* this parameter can be one of the following values:
* ADC1, ADC2, ADC3.
* @retval none
*/
void adc_reset(adc_type *adc_x)
{
if(adc_x == ADC1)
{
crm_periph_reset(CRM_ADC1_PERIPH_RESET, TRUE);
crm_periph_reset(CRM_ADC1_PERIPH_RESET, FALSE);
}
else if(adc_x == ADC2)
{
crm_periph_reset(CRM_ADC2_PERIPH_RESET, TRUE);
crm_periph_reset(CRM_ADC2_PERIPH_RESET, FALSE);
}
else if(adc_x == ADC3)
{
crm_periph_reset(CRM_ADC3_PERIPH_RESET, TRUE);
crm_periph_reset(CRM_ADC3_PERIPH_RESET, FALSE);
}
}
/**
* @brief enable or disable the specified adc peripheral.
* @param adc_x: select the adc peripheral.
* this parameter can be one of the following values:
* ADC1, ADC2, ADC3.
* @param new_state: new state of a/d converter.
* this parameter can be: TRUE or FALSE.
* note:after adc ready,user set adcen bit will cause ordinary conversion
* @retval none
*/
void adc_enable(adc_type *adc_x, confirm_state new_state)
{
adc_x->ctrl2_bit.adcen = new_state;
}
/**
* @brief select combine mode of the specified adc peripheral.
* @param combine_mode: select the adc combine mode.
* this parameter can be one of the following values:
* - ADC_INDEPENDENT_MODE
* - ADC_ORDINARY_SMLT_PREEMPT_SMLT_MODE
* - ADC_ORDINARY_SMLT_PREEMPT_INTERLTRIG_MODE
* - ADC_ORDINARY_SHORTSHIFT_PREEMPT_SMLT_MODE
* - ADC_ORDINARY_LONGSHIFT_PREEMPT_SMLT_MODE
* - ADC_PREEMPT_SMLT_ONLY_MODE
* - ADC_ORDINARY_SMLT_ONLY_MODE
* - ADC_ORDINARY_SHORTSHIFT_ONLY_MODE
* - ADC_ORDINARY_LONGSHIFT_ONLY_MODE
* - ADC_PREEMPT_INTERLTRIG_ONLY_MODE
* note:these bits are reserved in adc2 and adc3
* @retval none
*/
void adc_combine_mode_select(adc_combine_mode_type combine_mode)
{
ADC1->ctrl1_bit.mssel = combine_mode;
}
/**
* @brief adc base default para init.
* @param sequence_mode: set the state of adc sequence mode.
* this parameter can be:TRUE or FALSE
* @param repeat_mode: set the state of adc repeat conversion mode.
* this parameter can be:TRUE or FALSE
* @param data_align: set the state of adc data alignment.
* this parameter can be one of the following values:
* - ADC_RIGHT_ALIGNMENT
* - ADC_LEFT_ALIGNMENT
* @param ordinary_channel_length: configure the adc ordinary channel sequence length.
* this parameter can be:
* - (0x1~0x10)
* @retval none
*/
void adc_base_default_para_init(adc_base_config_type *adc_base_struct)
{
adc_base_struct->sequence_mode = FALSE;
adc_base_struct->repeat_mode = FALSE;
adc_base_struct->data_align = ADC_RIGHT_ALIGNMENT;
adc_base_struct->ordinary_channel_length = 1;
}
/**
* @brief initialize the adc peripheral according to the specified parameters.
* @param adc_x: select the adc peripheral.
* this parameter can be one of the following values:
* ADC1, ADC2, ADC3.
* @param sequence_mode: set the state of adc sequence mode.
* this parameter can be:TRUE or FALSE
* @param repeat_mode: set the state of adc repeat conversion mode.
* this parameter can be:TRUE or FALSE
* @param data_align: set the state of adc data alignment.
* this parameter can be one of the following values:
* - ADC_RIGHT_ALIGNMENT
* - ADC_LEFT_ALIGNMENT
* @param ordinary_channel_length: configure the adc ordinary channel sequence length.
* this parameter can be:
* - (0x1~0x10)
* @retval none
*/
void adc_base_config(adc_type *adc_x, adc_base_config_type *adc_base_struct)
{
adc_x->ctrl1_bit.sqen = adc_base_struct->sequence_mode;
adc_x->ctrl2_bit.rpen = adc_base_struct->repeat_mode;
adc_x->ctrl2_bit.dtalign = adc_base_struct->data_align;
adc_x->osq1_bit.oclen = adc_base_struct->ordinary_channel_length - 1;
}
/**
* @brief enable or disable the adc dma transfer.
* @param adc_x: select the adc peripheral.
* this parameter can be one of the following values:
* ADC1, ADC3.
* note:this bit is reserved in adc2
* @param new_state: new state of the adc dma transfer.
* this parameter can be: TRUE or FALSE.
* @retval none
*/
void adc_dma_mode_enable(adc_type *adc_x, confirm_state new_state)
{
adc_x->ctrl2_bit.ocdmaen = new_state;
}
/**
* @brief enable or disable the specified adc interrupts.
* @param adc_x: select the adc peripheral.
* this parameter can be one of the following values:
* ADC1, ADC2, ADC3.
* @param adc_int: specifies the adc interrupt sources to be enabled or disabled.
* this parameter can be one of the following values:
* - ADC_VMOR_INT
* - ADC_CCE_INT
* - ADC_PCCE_INT
* @param new_state: new state of the specified adc interrupts.
* this parameter can be: TRUE or FALSE.
* @retval none
*/
void adc_interrupt_enable(adc_type *adc_x, uint32_t adc_int, confirm_state new_state)
{
if(new_state == TRUE)
{
adc_x->ctrl1 |= adc_int;
}
else if(new_state == FALSE)
{
adc_x->ctrl1 &= ~adc_int;
}
}
/**
* @brief initialize calibration register of the specified adc peripheral.
* @param adc_x: select the adc peripheral.
* this parameter can be one of the following values:
* ADC1, ADC2, ADC3.
* @retval none
*/
void adc_calibration_init(adc_type *adc_x)
{
adc_x->ctrl2_bit.adcalinit = TRUE;
}
/**
* @brief get calibration register's initialize status of the specified adc peripheral.
* @param adc_x: select the adc peripheral.
* this parameter can be one of the following values:
* ADC1, ADC2, ADC3.
* @retval the new state of reset calibration register status(SET or RESET).
*/
flag_status adc_calibration_init_status_get(adc_type *adc_x)
{
if(adc_x->ctrl2_bit.adcalinit)
{
return SET;
}
else
{
return RESET;
}
}
/**
* @brief start calibration process of the specified adc peripheral.
* @param adc_x: select the adc peripheral.
* this parameter can be one of the following values:
* ADC1, ADC2, ADC3.
* @retval none
*/
void adc_calibration_start(adc_type *adc_x)
{
adc_x->ctrl2_bit.adcal = TRUE;
}
/**
* @brief get calibration status of the specified adc peripheral.
* @param adc_x: select the adc peripheral.
* this parameter can be one of the following values:
* ADC1, ADC2, ADC3.
* @retval the new state of calibration status(SET or RESET).
*/
flag_status adc_calibration_status_get(adc_type *adc_x)
{
if(adc_x->ctrl2_bit.adcal)
{
return SET;
}
else
{
return RESET;
}
}
/**
* @brief enable or disable the voltage monitoring on single/all ordinary or preempt channels of the specified adc peripheral.
* @param adc_x: select the adc peripheral.
* this parameter can be one of the following values:
* ADC1, ADC2, ADC3.
* @param adc_voltage_monitoring: choose the adc_voltage_monitoring config.
* this parameter can be one of the following values:
* - ADC_VMONITOR_SINGLE_ORDINARY
* - ADC_VMONITOR_SINGLE_PREEMPT
* - ADC_VMONITOR_SINGLE_ORDINARY_PREEMPT
* - ADC_VMONITOR_ALL_ORDINARY
* - ADC_VMONITOR_ALL_PREEMPT
* - ADC_VMONITOR_ALL_ORDINARY_PREEMPT
* - ADC_VMONITOR_NONE
* @retval none
*/
void adc_voltage_monitor_enable(adc_type *adc_x, adc_voltage_monitoring_type adc_voltage_monitoring)
{
adc_x->ctrl1_bit.ocvmen = FALSE;
adc_x->ctrl1_bit.pcvmen = FALSE;
adc_x->ctrl1_bit.vmsgen = FALSE;
adc_x->ctrl1 |= adc_voltage_monitoring;
}
/**
* @brief set voltage monitoring's high and low thresholds value of the specified adc peripheral.
* @param adc_x: select the adc peripheral.
* this parameter can be one of the following values:
* ADC1, ADC2, ADC3.
* @param adc_high_threshold: voltage monitoring's high thresholds value.
* this parameter can be:
* - (0x000~0xFFF)
* @param adc_low_threshold: voltage monitoring's low thresholds value.
* this parameter can be:
* - (0x000~0xFFF)
* @retval none
*/
void adc_voltage_monitor_threshold_value_set(adc_type *adc_x, uint16_t adc_high_threshold, uint16_t adc_low_threshold)
{
adc_x->vmhb_bit.vmhb = adc_high_threshold;
adc_x->vmlb_bit.vmlb = adc_low_threshold;
}
/**
* @brief select the voltage monitoring's channel of the specified adc peripheral.
* @param adc_x: select the adc peripheral.
* this parameter can be one of the following values:
* ADC1, ADC2, ADC3.
* @param adc_channel: select the channel.
* this parameter can be one of the following values:
* - ADC_CHANNEL_0 - ADC_CHANNEL_1 - ADC_CHANNEL_2 - ADC_CHANNEL_3
* - ADC_CHANNEL_4 - ADC_CHANNEL_5 - ADC_CHANNEL_6 - ADC_CHANNEL_7
* - ADC_CHANNEL_8 - ADC_CHANNEL_9 - ADC_CHANNEL_10 - ADC_CHANNEL_11
* - ADC_CHANNEL_12 - ADC_CHANNEL_13 - ADC_CHANNEL_14 - ADC_CHANNEL_15
* - ADC_CHANNEL_16 - ADC_CHANNEL_17
* @retval none
*/
void adc_voltage_monitor_single_channel_select(adc_type *adc_x, adc_channel_select_type adc_channel)
{
adc_x->ctrl1_bit.vmcsel = adc_channel;
}
/**
* @brief set ordinary channel's corresponding rank in the sequencer and sample time of the specified adc peripheral.
* @param adc_x: select the adc peripheral.
* this parameter can be one of the following values:
* ADC1, ADC2, ADC3.
* @param adc_channel: select the channel.
* this parameter can be one of the following values:
* - ADC_CHANNEL_0 - ADC_CHANNEL_1 - ADC_CHANNEL_2 - ADC_CHANNEL_3
* - ADC_CHANNEL_4 - ADC_CHANNEL_5 - ADC_CHANNEL_6 - ADC_CHANNEL_7
* - ADC_CHANNEL_8 - ADC_CHANNEL_9 - ADC_CHANNEL_10 - ADC_CHANNEL_11
* - ADC_CHANNEL_12 - ADC_CHANNEL_13 - ADC_CHANNEL_14 - ADC_CHANNEL_15
* - ADC_CHANNEL_16 - ADC_CHANNEL_17
* @param adc_sequence: set rank in the ordinary group sequencer.
* this parameter must be:
* - between 1 to 16
* @param adc_sampletime: set the sampletime of adc channel.
* this parameter can be one of the following values:
* - ADC_SAMPLETIME_1_5
* - ADC_SAMPLETIME_7_5
* - ADC_SAMPLETIME_13_5
* - ADC_SAMPLETIME_28_5
* - ADC_SAMPLETIME_41_5
* - ADC_SAMPLETIME_55_5
* - ADC_SAMPLETIME_71_5
* - ADC_SAMPLETIME_239_5
* @retval none
*/
void adc_ordinary_channel_set(adc_type *adc_x, adc_channel_select_type adc_channel, uint8_t adc_sequence, adc_sampletime_select_type adc_sampletime)
{
uint32_t tmp_reg;
if(adc_channel < ADC_CHANNEL_10)
{
tmp_reg = adc_x->spt2;
tmp_reg &= ~(0x07 << 3 * adc_channel);
tmp_reg |= adc_sampletime << 3 * adc_channel;
adc_x->spt2 = tmp_reg;
}
else
{
tmp_reg = adc_x->spt1;
tmp_reg &= ~(0x07 << 3 * (adc_channel - ADC_CHANNEL_10));
tmp_reg |= adc_sampletime << 3 * (adc_channel - ADC_CHANNEL_10);
adc_x->spt1 = tmp_reg;
}
if(adc_sequence >= 13)
{
tmp_reg = adc_x->osq1;
tmp_reg &= ~(0x01F << 5 * (adc_sequence - 13));
tmp_reg |= adc_channel << 5 * (adc_sequence - 13);
adc_x->osq1 = tmp_reg;
}
else if(adc_sequence >= 7)
{
tmp_reg = adc_x->osq2;
tmp_reg &= ~(0x01F << 5 * (adc_sequence - 7));
tmp_reg |= adc_channel << 5 * (adc_sequence - 7);
adc_x->osq2 = tmp_reg;
}
else
{
tmp_reg = adc_x->osq3;
tmp_reg &= ~(0x01F << 5 * (adc_sequence - 1));
tmp_reg |= adc_channel << 5 * (adc_sequence - 1);
adc_x->osq3 = tmp_reg;
}
}
/**
* @brief set preempt channel lenghth of the specified adc peripheral.
* @param adc_x: select the adc peripheral.
* this parameter can be one of the following values:
* ADC1, ADC2, ADC3.
* @param adc_channel_lenght: set the adc preempt channel lenghth.
* this parameter can be:
* - (0x1~0x4)
* @retval none
*/
void adc_preempt_channel_length_set(adc_type *adc_x, uint8_t adc_channel_lenght)
{
adc_x->psq_bit.pclen = adc_channel_lenght - 1;
}
/**
* @brief configure preempt channel's corresponding rank in the sequencer and sample time of the specified adc peripheral.
* @param adc_x: select the adc peripheral.
* this parameter can be one of the following values:
* ADC1, ADC2, ADC3.
* @param adc_channel: select the channel.
* this parameter can be one of the following values:
* - ADC_CHANNEL_0 - ADC_CHANNEL_1 - ADC_CHANNEL_2 - ADC_CHANNEL_3
* - ADC_CHANNEL_4 - ADC_CHANNEL_5 - ADC_CHANNEL_6 - ADC_CHANNEL_7
* - ADC_CHANNEL_8 - ADC_CHANNEL_9 - ADC_CHANNEL_10 - ADC_CHANNEL_11
* - ADC_CHANNEL_12 - ADC_CHANNEL_13 - ADC_CHANNEL_14 - ADC_CHANNEL_15
* - ADC_CHANNEL_16 - ADC_CHANNEL_17
* @param adc_sequence: set rank in the preempt group sequencer.
* this parameter must be:
* - between 1 to 4
* @param adc_sampletime: config the sampletime of adc channel.
* this parameter can be one of the following values:
* - ADC_SAMPLETIME_1_5
* - ADC_SAMPLETIME_7_5
* - ADC_SAMPLETIME_13_5
* - ADC_SAMPLETIME_28_5
* - ADC_SAMPLETIME_41_5
* - ADC_SAMPLETIME_55_5
* - ADC_SAMPLETIME_71_5
* - ADC_SAMPLETIME_239_5
* @retval none
*/
void adc_preempt_channel_set(adc_type *adc_x, adc_channel_select_type adc_channel, uint8_t adc_sequence, adc_sampletime_select_type adc_sampletime)
{
uint32_t tmp_reg;
uint8_t sequence_index;
if(adc_channel < ADC_CHANNEL_10)
{
tmp_reg = adc_x->spt2;
tmp_reg &= ~(0x07 << 3 * adc_channel);
tmp_reg |= adc_sampletime << 3 * adc_channel;
adc_x->spt2 = tmp_reg;
}
else
{
tmp_reg = adc_x->spt1;
tmp_reg &= ~(0x07 << 3 * (adc_channel - ADC_CHANNEL_10));
tmp_reg |= adc_sampletime << 3 * (adc_channel - ADC_CHANNEL_10);
adc_x->spt1 = tmp_reg;
}
sequence_index = adc_sequence + 3 - adc_x->psq_bit.pclen;
switch(sequence_index)
{
case 1:
adc_x->psq_bit.psn1 = adc_channel;
break;
case 2:
adc_x->psq_bit.psn2 = adc_channel;
break;
case 3:
adc_x->psq_bit.psn3 = adc_channel;
break;
case 4:
adc_x->psq_bit.psn4 = adc_channel;
break;
default:
break;
}
}
/**
* @brief enable or disable the ordinary channel's external trigger and
* set external trigger event of the specified adc peripheral.
* @param adc_x: select the adc peripheral.
* this parameter can be one of the following values:
* ADC1, ADC2, ADC3.
* @param adc_ordinary_trig: select the external trigger event.
* this parameter can be one of the following values:
* adc1 & adc2
* - ADC12_ORDINARY_TRIG_TMR1CH1 - ADC12_ORDINARY_TRIG_TMR1CH2 - ADC12_ORDINARY_TRIG_TMR1CH3 - ADC12_ORDINARY_TRIG_TMR2CH2
* - ADC12_ORDINARY_TRIG_TMR3TRGOUT - ADC12_ORDINARY_TRIG_TMR4CH4 - ADC12_ORDINARY_TRIG_EXINT11_TMR8TRGOUT - ADC12_ORDINARY_TRIG_SOFTWARE
* - ADC12_ORDINARY_TRIG_TMR1TRGOUT - ADC12_ORDINARY_TRIG_TMR8CH1 - ADC12_ORDINARY_TRIG_TMR8CH2
* adc3
* - ADC3_ORDINARY_TRIG_TMR3CH1 - ADC3_ORDINARY_TRIG_TMR2CH3 - ADC3_ORDINARY_TRIG_TMR1CH3 - ADC3_ORDINARY_TRIG_TMR8CH1
* - ADC3_ORDINARY_TRIG_TMR8TRGOUT - ADC3_ORDINARY_TRIG_TMR5CH1 - ADC3_ORDINARY_TRIG_TMR5CH3 - ADC3_ORDINARY_TRIG_SOFTWARE
* - ADC3_ORDINARY_TRIG_TMR1TRGOUT - ADC3_ORDINARY_TRIG_TMR1CH1 - ADC3_ORDINARY_TRIG_TMR8CH3
* @param new_state: new state of ordinary channel's external trigger.
* this parameter can be: TRUE or FALSE.
* @retval none
*/
void adc_ordinary_conversion_trigger_set(adc_type *adc_x, adc_ordinary_trig_select_type adc_ordinary_trig, confirm_state new_state)
{
if(adc_ordinary_trig > 7)
{
adc_x->ctrl2_bit.octesel_h = 1;
adc_x->ctrl2_bit.octesel_l = adc_ordinary_trig & 0x7;
}
else
{
adc_x->ctrl2_bit.octesel_h = 0;
adc_x->ctrl2_bit.octesel_l = adc_ordinary_trig & 0x7;
}
adc_x->ctrl2_bit.octen = new_state;
}
/**
* @brief enable or disable the preempt channel's external trigger and
* set external trigger event of the specified adc peripheral.
* @param adc_x: select the adc peripheral.
* this parameter can be one of the following values:
* ADC1, ADC2, ADC3.
* @param adc_preempt_trig: select the external trigger event.
* this parameter can be one of the following values:
* adc1 & adc2
* - ADC12_PREEMPT_TRIG_TMR1TRGOUT - ADC12_PREEMPT_TRIG_TMR1CH4 - ADC12_PREEMPT_TRIG_TMR2TRGOUT - ADC12_PREEMPT_TRIG_TMR2CH1
* - ADC12_PREEMPT_TRIG_TMR3CH4 - ADC12_PREEMPT_TRIG_TMR4TRGOUT - ADC12_PREEMPT_TRIG_EXINT15_TMR8CH4 - ADC12_PREEMPT_TRIG_SOFTWARE
* - ADC12_PREEMPT_TRIG_TMR1CH1 - ADC12_PREEMPT_TRIG_TMR8CH1 - ADC12_PREEMPT_TRIG_TMR8TRGOUT
* adc3
* - ADC3_PREEMPT_TRIG_TMR1TRGOUT - ADC3_PREEMPT_TRIG_TMR1CH4 - ADC3_PREEMPT_TRIG_TMR4CH3 - ADC3_PREEMPT_TRIG_TMR8CH2
* - ADC3_PREEMPT_TRIG_TMR8CH4 - ADC3_PREEMPT_TRIG_TMR5TRGOUT - ADC3_PREEMPT_TRIG_TMR5CH4 - ADC3_PREEMPT_TRIG_SOFTWARE
* - ADC3_PREEMPT_TRIG_TMR1CH1 - ADC3_PREEMPT_TRIG_TMR1CH2 - ADC3_PREEMPT_TRIG_TMR8TRGOUT
* @param new_state: new state of preempt channel's external trigger.
* this parameter can be: TRUE or FALSE.
* @retval none
*/
void adc_preempt_conversion_trigger_set(adc_type *adc_x, adc_preempt_trig_select_type adc_preempt_trig, confirm_state new_state)
{
if(adc_preempt_trig > 7)
{
adc_x->ctrl2_bit.pctesel_h = 1;
adc_x->ctrl2_bit.pctesel_l = adc_preempt_trig & 0x7;
}
else
{
adc_x->ctrl2_bit.pctesel_h = 0;
adc_x->ctrl2_bit.pctesel_l = adc_preempt_trig & 0x7;
}
adc_x->ctrl2_bit.pcten = new_state;
}
/**
* @brief set preempt channel's conversion value offset of the specified adc peripheral.
* @param adc_x: select the adc peripheral.
* this parameter can be one of the following values:
* ADC1, ADC2, ADC3.
* @param adc_preempt_channel: select the preempt channel.
* this parameter can be one of the following values:
* - ADC_PREEMPT_CHANNEL_1
* - ADC_PREEMPT_CHANNEL_2
* - ADC_PREEMPT_CHANNEL_3
* - ADC_PREEMPT_CHANNEL_4
* @param adc_offset_value: set the adc preempt channel's conversion value offset.
* this parameter can be:
* - (0x000~0xFFF)
* @retval none
*/
void adc_preempt_offset_value_set(adc_type *adc_x, adc_preempt_channel_type adc_preempt_channel, uint16_t adc_offset_value)
{
switch(adc_preempt_channel)
{
case ADC_PREEMPT_CHANNEL_1:
adc_x->pcdto1_bit.pcdto1 = adc_offset_value;
break;
case ADC_PREEMPT_CHANNEL_2:
adc_x->pcdto2_bit.pcdto2 = adc_offset_value;
break;
case ADC_PREEMPT_CHANNEL_3:
adc_x->pcdto3_bit.pcdto3 = adc_offset_value;
break;
case ADC_PREEMPT_CHANNEL_4:
adc_x->pcdto4_bit.pcdto4 = adc_offset_value;
break;
default:
break;
}
}
/**
* @brief set partitioned mode channel count of the specified adc peripheral.
* @param adc_x: select the adc peripheral.
* this parameter can be one of the following values:
* ADC1, ADC2, ADC3.
* @param adc_channel_count: configure the adc partitioned mode channel count.
* this parameter can be:
* - (0x1~0x8)
* @retval none
*/
void adc_ordinary_part_count_set(adc_type *adc_x, uint8_t adc_channel_count)
{
adc_x->ctrl1_bit.ocpcnt = adc_channel_count - 1;
}
/**
* @brief enable or disable the partitioned mode on ordinary channel of the specified adc peripheral.
* @param adc_x: select the adc peripheral.
* this parameter can be one of the following values:
* ADC1, ADC2, ADC3.
* @param new_state: new state of ordinary channel's partitioned mode.
* this parameter can be: TRUE or FALSE.
* @retval none
*/
void adc_ordinary_part_mode_enable(adc_type *adc_x, confirm_state new_state)
{
adc_x->ctrl1_bit.ocpen = new_state;
}
/**
* @brief enable or disable the partitioned mode on preempt channel of the specified adc peripheral.
* @param adc_x: select the adc peripheral.
* this parameter can be one of the following values:
* ADC1, ADC2, ADC3.
* @param new_state: new state of preempt channel's partitioned mode.
* this parameter can be: TRUE or FALSE.
* @retval none
*/
void adc_preempt_part_mode_enable(adc_type *adc_x, confirm_state new_state)
{
adc_x->ctrl1_bit.pcpen = new_state;
}
/**
* @brief enable or disable automatic preempt group conversion of the specified adc peripheral.
* @param adc_x: select the adc peripheral.
* this parameter can be one of the following values:
* ADC1, ADC2, ADC3.
* @param new_state: new state of automatic preempt group conversion.
* this parameter can be: TRUE or FALSE.
* @retval none
*/
void adc_preempt_auto_mode_enable(adc_type *adc_x, confirm_state new_state)
{
adc_x->ctrl1_bit.pcautoen = new_state;
}
/**
* @brief enable or disable the temperature sensor and vintrv channel.
* @param new_state: new state of Internal temperature sensor and vintrv.
* this parameter can be: TRUE or FALSE.
* note:this bit is present only in adc1
* @retval none
*/
void adc_tempersensor_vintrv_enable(confirm_state new_state)
{
ADC1->ctrl2_bit.itsrven = new_state;
}
/**
* @brief enable or disable ordinary software start conversion of the specified adc peripheral.
* @param adc_x: select the adc peripheral.
* this parameter can be one of the following values:
* ADC1, ADC2, ADC3.
* @param new_state: new state of ordinary software start conversion.
* this parameter can be: TRUE or FALSE.
* @retval none
*/
void adc_ordinary_software_trigger_enable(adc_type *adc_x, confirm_state new_state)
{
adc_x->ctrl2_bit.ocswtrg = new_state;
}
/**
* @brief get ordinary software start conversion status of the specified adc peripheral.
* @param adc_x: select the adc peripheral.
* this parameter can be one of the following values:
* ADC1, ADC2, ADC3.
* @retval the new state of ordinary software start conversion status(SET or RESET).
*/
flag_status adc_ordinary_software_trigger_status_get(adc_type *adc_x)
{
if(adc_x->ctrl2_bit.ocswtrg)
{
return SET;
}
else
{
return RESET;
}
}
/**
* @brief enable or disable preempt software start conversion of the specified adc peripheral.
* @param adc_x: select the adc peripheral.
* this parameter can be one of the following values:
* ADC1, ADC2, ADC3.
* @param new_state: new state of preempt software start conversion.
* this parameter can be: TRUE or FALSE.
* @retval none
*/
void adc_preempt_software_trigger_enable(adc_type *adc_x, confirm_state new_state)
{
adc_x->ctrl2_bit.pcswtrg = new_state;
}
/**
* @brief get preempt software start conversion status of the specified adc peripheral.
* @param adc_x: select the adc peripheral.
* this parameter can be one of the following values:
* ADC1, ADC2, ADC3.
* @retval the new state of preempt software start conversion status(SET or RESET).
*/
flag_status adc_preempt_software_trigger_status_get(adc_type *adc_x)
{
if(adc_x->ctrl2_bit.pcswtrg)
{
return SET;
}
else
{
return RESET;
}
}
/**
* @brief return the last conversion data for ordinary channel of the specified adc peripheral.
* @param adc_x: select the adc peripheral.
* this parameter can be one of the following values:
* ADC1, ADC2, ADC3.
* @retval the last conversion data for ordinary channel.
*/
uint16_t adc_ordinary_conversion_data_get(adc_type *adc_x)
{
return (uint16_t)(adc_x->odt_bit.odt);
}
/**
* @brief return the last conversion data for ordinary channel of combine adc(adc1 and adc2).
* @retval the last conversion data for ordinary channel.
*/
uint32_t adc_combine_ordinary_conversion_data_get(void)
{
return (uint32_t)(ADC1->odt);
}
/**
* @brief return the conversion data for selection preempt channel of the specified adc peripheral.
* @param adc_x: select the adc peripheral.
* this parameter can be one of the following values:
* ADC1, ADC2, ADC3.
* @param adc_preempt_channel: select the preempt channel.
* this parameter can be one of the following values:
* - ADC_PREEMPT_CHANNEL_1
* - ADC_PREEMPT_CHANNEL_2
* - ADC_PREEMPT_CHANNEL_3
* - ADC_PREEMPT_CHANNEL_4
* @retval the conversion data for selection preempt channel.
*/
uint16_t adc_preempt_conversion_data_get(adc_type *adc_x, adc_preempt_channel_type adc_preempt_channel)
{
uint16_t preempt_conv_data_index = 0;
switch(adc_preempt_channel)
{
case ADC_PREEMPT_CHANNEL_1:
preempt_conv_data_index = (uint16_t)(adc_x->pdt1_bit.pdt1);
break;
case ADC_PREEMPT_CHANNEL_2:
preempt_conv_data_index = (uint16_t)(adc_x->pdt2_bit.pdt2);
break;
case ADC_PREEMPT_CHANNEL_3:
preempt_conv_data_index = (uint16_t)(adc_x->pdt3_bit.pdt3);
break;
case ADC_PREEMPT_CHANNEL_4:
preempt_conv_data_index = (uint16_t)(adc_x->pdt4_bit.pdt4);
break;
default:
break;
}
return preempt_conv_data_index;
}
/**
* @brief get flag of the specified adc peripheral.
* @param adc_x: select the adc peripheral.
* this parameter can be one of the following values:
* ADC1, ADC2, ADC3.
* @param adc_flag: select the adc flag.
* this parameter can be one of the following values:
* - ADC_VMOR_FLAG
* - ADC_CCE_FLAG
* - ADC_PCCE_FLAG
* - ADC_PCCS_FLAG(no interrupt associated)
* - ADC_OCCS_FLAG(no interrupt associated)
* @retval the new state of adc flag status(SET or RESET).
*/
flag_status adc_flag_get(adc_type *adc_x, uint8_t adc_flag)
{
flag_status status = RESET;
if((adc_x->sts & adc_flag) == RESET)
{
status = RESET;
}
else
{
status = SET;
}
return status;
}
/**
* @brief get interrupt flag of the specified adc peripheral.
* @param adc_x: select the adc peripheral.
* this parameter can be one of the following values:
* ADC1, ADC2, ADC3.
* @param adc_flag: select the adc flag.
* this parameter can be one of the following values:
* - ADC_VMOR_FLAG
* - ADC_CCE_FLAG
* - ADC_PCCE_FLAG
* @retval the new state of adc flag status(SET or RESET).
*/
flag_status adc_interrupt_flag_get(adc_type *adc_x, uint8_t adc_flag)
{
flag_status status = RESET;
switch(adc_flag)
{
case ADC_VMOR_FLAG:
if(adc_x->sts_bit.vmor && adc_x->ctrl1_bit.vmorien)
{
status = SET;
}
break;
case ADC_CCE_FLAG:
if(adc_x->sts_bit.cce && adc_x->ctrl1_bit.cceien)
{
status = SET;
}
break;
case ADC_PCCE_FLAG:
if(adc_x->sts_bit.pcce && adc_x->ctrl1_bit.pcceien)
{
status = SET;
}
break;
default:
break;
}
return status;
}
/**
* @brief clear flag of the specified adc peripheral.
* @param adc_x: select the adc peripheral.
* this parameter can be one of the following values:
* ADC1, ADC2, ADC3.
* @param adc_flag: select the adc flag.
* this parameter can be any combination of the following values:
* - ADC_VMOR_FLAG
* - ADC_CCE_FLAG(also can clear by reading the adc_x->odt)
* - ADC_PCCE_FLAG
* - ADC_PCCS_FLAG
* - ADC_OCCS_FLAG
* @retval none
*/
void adc_flag_clear(adc_type *adc_x, uint32_t adc_flag)
{
adc_x->sts = ~adc_flag;
}
/**
* @}
*/
#endif
/**
* @}
*/
/**
* @}
*/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,921 @@
/**
**************************************************************************
* @file at32f403a_407_crm.c
* @brief contains all the functions for the crm firmware library
**************************************************************************
* Copyright notice & Disclaimer
*
* The software Board Support Package (BSP) that is made available to
* download from Artery official website is the copyrighted work of Artery.
* Artery authorizes customers to use, copy, and distribute the BSP
* software and its related documentation for the purpose of design and
* development in conjunction with Artery microcontrollers. Use of the
* software is governed by this copyright notice and the following disclaimer.
*
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
*
**************************************************************************
*/
#include "at32f403a_407_conf.h"
/** @addtogroup AT32F403A_407_periph_driver
* @{
*/
/** @defgroup CRM
* @brief CRM driver modules
* @{
*/
#ifdef CRM_MODULE_ENABLED
/** @defgroup CRM_private_functions
* @{
*/
/**
* @brief reset the crm register
* @param none
* @retval none
*/
void crm_reset(void)
{
/* reset the crm clock configuration to the default reset state(for debug purpose) */
/* set hicken bit */
CRM->ctrl_bit.hicken = TRUE;
/* wait hick stable */
while(CRM->ctrl_bit.hickstbl != SET);
/* hick used as system clock */
CRM->cfg_bit.sclksel = CRM_SCLK_HICK;
/* wait sclk switch status */
while(CRM->cfg_bit.sclksts != CRM_SCLK_HICK);
/* reset hexten, hextbyps, cfden and pllen bits */
CRM->ctrl &= ~(0x010D0000U);
/* reset cfg register, include sclk switch, ahbdiv, apb1div, apb2div, adcdiv,
clkout pllrcs, pllhextdiv, pllmult, usbdiv and pllrange bits */
CRM->cfg = 0;
/* reset clkout[3], usbbufs, hickdiv, clkoutdiv */
CRM->misc1 = 0;
/* disable all interrupts enable and clear pending bits */
CRM->clkint = 0x009F0000;
}
/**
* @brief enable or disable crm low speed external crystal bypass
* @param new_state (TRUE or FALSE)
* @retval none
*/
void crm_lext_bypass(confirm_state new_state)
{
CRM->bpdc_bit.lextbyps = new_state;
}
/**
* @brief enable or disable crm high speed external crystal bypass
* @param new_state (TRUE or FALSE)
* @retval none
*/
void crm_hext_bypass(confirm_state new_state)
{
CRM->ctrl_bit.hextbyps = new_state;
}
/**
* @brief get crm flag status
* @param flag
* this parameter can be one of the following values:
* - CRM_HICK_STABLE_FLAG
* - CRM_HEXT_STABLE_FLAG
* - CRM_PLL_STABLE_FLAG
* - CRM_LEXT_STABLE_FLAG
* - CRM_LICK_STABLE_FLAG
* - CRM_NRST_RESET_FLAG
* - CRM_POR_RESET_FLAG
* - CRM_SW_RESET_FLAG
* - CRM_WDT_RESET_FLAG
* - CRM_WWDT_RESET_FLAG
* - CRM_LOWPOWER_RESET_FLAG
* interrupt flag:
* - CRM_LICK_READY_INT_FLAG
* - CRM_LEXT_READY_INT_FLAG
* - CRM_HICK_READY_INT_FLAG
* - CRM_HEXT_READY_INT_FLAG
* - CRM_PLL_READY_INT_FLAG
* - CRM_CLOCK_FAILURE_INT_FLAG
* @retval flag_status (SET or RESET)
*/
flag_status crm_flag_get(uint32_t flag)
{
flag_status status = RESET;
if((CRM_REG(flag) & CRM_REG_BIT(flag)) != CRM_REG_BIT(flag))
{
status = RESET;
}
else
{
status = SET;
}
return status;
}
/**
* @brief get crm interrupt flag status
* @param flag
* this parameter can be one of the following values:
* - CRM_LICK_READY_INT_FLAG
* - CRM_LEXT_READY_INT_FLAG
* - CRM_HICK_READY_INT_FLAG
* - CRM_HEXT_READY_INT_FLAG
* - CRM_PLL_READY_INT_FLAG
* - CRM_CLOCK_FAILURE_INT_FLAG
* @retval flag_status (SET or RESET)
*/
flag_status crm_interrupt_flag_get(uint32_t flag)
{
flag_status status = RESET;
switch(flag)
{
case CRM_LICK_READY_INT_FLAG:
if(CRM->clkint_bit.lickstblf && CRM->clkint_bit.lickstblien)
{
status = SET;
}
break;
case CRM_LEXT_READY_INT_FLAG:
if(CRM->clkint_bit.lextstblf && CRM->clkint_bit.lextstblien)
{
status = SET;
}
break;
case CRM_HICK_READY_INT_FLAG:
if(CRM->clkint_bit.hickstblf && CRM->clkint_bit.hickstblien)
{
status = SET;
}
break;
case CRM_HEXT_READY_INT_FLAG:
if(CRM->clkint_bit.hextstblf && CRM->clkint_bit.hextstblien)
{
status = SET;
}
break;
case CRM_PLL_READY_INT_FLAG:
if(CRM->clkint_bit.pllstblf && CRM->clkint_bit.pllstblien)
{
status = SET;
}
break;
case CRM_CLOCK_FAILURE_INT_FLAG:
if(CRM->clkint_bit.cfdf && CRM->ctrl_bit.cfden)
{
status = SET;
}
break;
}
return status;
}
/**
* @brief wait for hext stable
* @param none
* @retval error_status (ERROR or SUCCESS)
*/
error_status crm_hext_stable_wait(void)
{
uint32_t stable_cnt = 0;
error_status status = ERROR;
while((crm_flag_get(CRM_HEXT_STABLE_FLAG) != SET) && (stable_cnt < HEXT_STARTUP_TIMEOUT))
{
stable_cnt ++;
}
if(crm_flag_get(CRM_HEXT_STABLE_FLAG) != SET)
{
status = ERROR;
}
else
{
status = SUCCESS;
}
return status;
}
/**
* @brief set the hick trimming value
* @param trim_value (0x00~0x3F)
* @retval none
*/
void crm_hick_clock_trimming_set(uint8_t trim_value)
{
CRM->ctrl_bit.hicktrim = trim_value;
}
/**
* @brief set the crm calibration value
* @param cali_value (0x00~0xFF)
* @retval none
*/
void crm_hick_clock_calibration_set(uint8_t cali_value)
{
/* enable write hick calibration */
CRM->misc1_bit.hickcal_key = 0x5A;
/* write hick calibration value */
CRM->ctrl_bit.hickcal = cali_value;
/* disable write hick calibration */
CRM->misc1_bit.hickcal_key = 0x0;
}
/**
* @brief enable or disable the peripheral clock
* @param value
* this parameter can be one of the following values:
* - CRM_DMA1_PERIPH_CLOCK - CRM_DMA2_PERIPH_CLOCK - CRM_CRC_PERIPH_CLOCK - CRM_XMC_PERIPH_CLOCK
* - CRM_SDIO1_PERIPH_CLOCK - CRM_SDIO2_PERIPH_CLOCK - CRM_EMAC_PERIPH_CLOCK - CRM_EMACTX_PERIPH_CLOCK
* - CRM_EMACRX_PERIPH_CLOCK - CRM_EMACPTP_PERIPH_CLOCK - CRM_IOMUX_PERIPH_CLOCK - CRM_GPIOA_PERIPH_CLOCK
* - CRM_GPIOB_PERIPH_CLOCK - CRM_GPIOC_PERIPH_CLOCK - CRM_GPIOD_PERIPH_CLOCK - CRM_GPIOE_PERIPH_CLOCK
* - CRM_ADC1_PERIPH_CLOCK - CRM_ADC2_PERIPH_CLOCK - CRM_TMR1_PERIPH_CLOCK - CRM_SPI1_PERIPH_CLOCK
* - CRM_TMR8_PERIPH_CLOCK - CRM_USART1_PERIPH_CLOCK - CRM_ADC3_PERIPH_CLOCK - CRM_TMR9_PERIPH_CLOCK
* - CRM_TMR10_PERIPH_CLOCK - CRM_TMR11_PERIPH_CLOCK - CRM_ACC_PERIPH_CLOCK - CRM_I2C3_PERIPH_CLOCK
* - CRM_USART6_PERIPH_CLOCK - CRM_UART7_PERIPH_CLOCK - CRM_UART8_PERIPH_CLOCK - CRM_TMR2_PERIPH_CLOCK
* - CRM_TMR3_PERIPH_CLOCK - CRM_TMR4_PERIPH_CLOCK - CRM_TMR5_PERIPH_CLOCK - CRM_TMR6_PERIPH_CLOCK
* - CRM_TMR7_PERIPH_CLOCK - CRM_TMR12_PERIPH_CLOCK - CRM_TMR13_PERIPH_CLOCK - CRM_TMR14_PERIPH_CLOCK
* - CRM_WWDT_PERIPH_CLOCK - CRM_SPI2_PERIPH_CLOCK - CRM_SPI3_PERIPH_CLOCK - CRM_SPI4_PERIPH_CLOCK
* - CRM_USART2_PERIPH_CLOCK - CRM_USART3_PERIPH_CLOCK - CRM_UART4_PERIPH_CLOCK - CRM_UART5_PERIPH_CLOCK
* - CRM_I2C1_PERIPH_CLOCK - CRM_I2C2_PERIPH_CLOCK - CRM_USB_PERIPH_CLOCK - CRM_CAN1_PERIPH_CLOCK
* - CRM_CAN2_PERIPH_CLOCK - CRM_BPR_PERIPH_CLOCK - CRM_PWC_PERIPH_CLOCK - CRM_DAC_PERIPH_CLOCK
* @param new_state (TRUE or FALSE)
* @retval none
*/
void crm_periph_clock_enable(crm_periph_clock_type value, confirm_state new_state)
{
/* enable periph clock */
if(TRUE == new_state)
{
CRM_REG(value) |= CRM_REG_BIT(value);
}
/* disable periph clock */
else
{
CRM_REG(value) &= ~(CRM_REG_BIT(value));
}
}
/**
* @brief enable or disable the peripheral reset
* @param value
* this parameter can be one of the following values:
* - CRM_EMAC_PERIPH_RESET - CRM_IOMUX_PERIPH_RESET - CRM_EXINT_PERIPH_RESET - CRM_GPIOA_PERIPH_RESET
* - CRM_GPIOB_PERIPH_RESET - CRM_GPIOC_PERIPH_RESET - CRM_GPIOD_PERIPH_RESET - CRM_GPIOE_PERIPH_RESET
* - CRM_ADC1_PERIPH_RESET - CRM_ADC2_PERIPH_RESET - CRM_TMR1_PERIPH_RESET - CRM_SPI1_PERIPH_RESET
* - CRM_TMR8_PERIPH_RESET - CRM_USART1_PERIPH_RESET - CRM_ADC3_PERIPH_RESET - CRM_TMR9_PERIPH_RESET
* - CRM_TMR10_PERIPH_RESET - CRM_TMR11_PERIPH_RESET - CRM_ACC_PERIPH_RESET - CRM_I2C3_PERIPH_RESET
* - CRM_USART6_PERIPH_RESET - CRM_UART7_PERIPH_RESET - CRM_UART8_PERIPH_RESET - CRM_TMR2_PERIPH_RESET
* - CRM_TMR3_PERIPH_RESET - CRM_TMR4_PERIPH_RESET - CRM_TMR5_PERIPH_RESET - CRM_TMR6_PERIPH_RESET
* - CRM_TMR7_PERIPH_RESET - CRM_TMR12_PERIPH_RESET - CRM_TMR13_PERIPH_RESET - CRM_TMR14_PERIPH_RESET
* - CRM_WWDT_PERIPH_RESET - CRM_SPI2_PERIPH_RESET - CRM_SPI3_PERIPH_RESET - CRM_SPI4_PERIPH_RESET
* - CRM_USART2_PERIPH_RESET - CRM_USART3_PERIPH_RESET - CRM_UART4_PERIPH_RESET - CRM_UART5_PERIPH_RESET
* - CRM_I2C1_PERIPH_RESET - CRM_I2C2_PERIPH_RESET - CRM_USB_PERIPH_RESET - CRM_CAN1_PERIPH_RESET
* - CRM_CAN2_PERIPH_RESET - CRM_BPR_PERIPH_RESET - CRM_PWC_PERIPH_RESET - CRM_DAC_PERIPH_RESET
* @param new_state (TRUE or FALSE)
* @retval none
*/
void crm_periph_reset(crm_periph_reset_type value, confirm_state new_state)
{
/* enable periph reset */
if(new_state == TRUE)
{
CRM_REG(value) |= (CRM_REG_BIT(value));
}
/* disable periph reset */
else
{
CRM_REG(value) &= ~(CRM_REG_BIT(value));
}
}
/**
* @brief enable or disable the peripheral clock in sleep mode
* @param value
* this parameter can be one of the following values:
* - CRM_SRAM_PERIPH_CLOCK_SLEEP_MODE
* - CRM_FLASH_PERIPH_CLOCK_SLEEP_MODE
* @param new_state (TRUE or FALSE)
* @retval none
*/
void crm_periph_sleep_mode_clock_enable(crm_periph_clock_sleepmd_type value, confirm_state new_state)
{
/* enable periph clock in sleep mode */
if(new_state == TRUE)
{
CRM_REG(value) |= (CRM_REG_BIT(value));
}
/* disable perph clock in sleep mode */
else
{
CRM_REG(value) &= ~(CRM_REG_BIT(value));
}
}
/**
* @brief enable or disable the crm clock source
* @param source
* this parameter can be one of the following values:
* - CRM_CLOCK_SOURCE_HICK
* - CRM_CLOCK_SOURCE_HEXT
* - CRM_CLOCK_SOURCE_PLL
* - CRM_CLOCK_SOURCE_LEXT
* - CRM_CLOCK_SOURCE_LICK
* @param new_state (TRUE or FALSE)
* @retval none
*/
void crm_clock_source_enable(crm_clock_source_type source, confirm_state new_state)
{
switch(source)
{
case CRM_CLOCK_SOURCE_HICK:
CRM->ctrl_bit.hicken = new_state;
break;
case CRM_CLOCK_SOURCE_HEXT:
CRM->ctrl_bit.hexten = new_state;
break;
case CRM_CLOCK_SOURCE_PLL:
CRM->ctrl_bit.pllen = new_state;
break;
case CRM_CLOCK_SOURCE_LEXT:
CRM->bpdc_bit.lexten = new_state;
break;
case CRM_CLOCK_SOURCE_LICK:
CRM->ctrlsts_bit.licken = new_state;
break;
default:
break;
}
}
/**
* @brief clear the crm reset flags
* @param flag
* this parameter can be one of the following values:
* reset flag:
* - CRM_NRST_RESET_FLAG
* - CRM_POR_RESET_FLAG
* - CRM_SW_RESET_FLAG
* - CRM_WDT_RESET_FLAG
* - CRM_WWDT_RESET_FLAG
* - CRM_LOWPOWER_RESET_FLAG
* - CRM_ALL_RESET_FLAG
* interrupt flag:
* - CRM_LICK_READY_INT_FLAG
* - CRM_LEXT_READY_INT_FLAG
* - CRM_HICK_READY_INT_FLAG
* - CRM_HEXT_READY_INT_FLAG
* - CRM_PLL_READY_INT_FLAG
* - CRM_CLOCK_FAILURE_INT_FLAG
* @retval none
*/
void crm_flag_clear(uint32_t flag)
{
switch(flag)
{
case CRM_NRST_RESET_FLAG:
case CRM_POR_RESET_FLAG:
case CRM_SW_RESET_FLAG:
case CRM_WDT_RESET_FLAG:
case CRM_WWDT_RESET_FLAG:
case CRM_LOWPOWER_RESET_FLAG:
case CRM_ALL_RESET_FLAG:
CRM->ctrlsts_bit.rstfc = TRUE;
while(CRM->ctrlsts_bit.rstfc == TRUE);
break;
case CRM_LICK_READY_INT_FLAG:
CRM->clkint_bit.lickstblfc = TRUE;
break;
case CRM_LEXT_READY_INT_FLAG:
CRM->clkint_bit.lextstblfc = TRUE;
break;
case CRM_HICK_READY_INT_FLAG:
CRM->clkint_bit.hickstblfc = TRUE;
break;
case CRM_HEXT_READY_INT_FLAG:
CRM->clkint_bit.hextstblfc = TRUE;
break;
case CRM_PLL_READY_INT_FLAG:
CRM->clkint_bit.pllstblfc = TRUE;
break;
case CRM_CLOCK_FAILURE_INT_FLAG:
CRM->clkint_bit.cfdfc = TRUE;
break;
default:
break;
}
}
/**
* @brief select rtc clock
* @param value
* this parameter can be one of the following values:
* - CRM_RTC_CLOCK_LEXT
* - CRM_RTC_CLOCK_LICK
* - CRM_RTC_CLOCK_HEXT_DIV
* @retval none
*/
void crm_rtc_clock_select(crm_rtc_clock_type value)
{
CRM->bpdc_bit.rtcsel = value;
}
/**
* @brief enable or disable rtc
* @param new_state (TRUE or FALSE)
* @retval none
*/
void crm_rtc_clock_enable(confirm_state new_state)
{
CRM->bpdc_bit.rtcen = new_state;
}
/**
* @brief set crm ahb division
* @param value
* this parameter can be one of the following values:
* - CRM_AHB_DIV_1
* - CRM_AHB_DIV_2
* - CRM_AHB_DIV_4
* - CRM_AHB_DIV_8
* - CRM_AHB_DIV_16
* - CRM_AHB_DIV_64
* - CRM_AHB_DIV_128
* - CRM_AHB_DIV_256
* - CRM_AHB_DIV_512
* @retval none
*/
void crm_ahb_div_set(crm_ahb_div_type value)
{
CRM->cfg_bit.ahbdiv = value;
}
/**
* @brief set crm apb1 division
* @note the maximum frequency of APB1/APB2 clock is 120 MHz
* @param value
* this parameter can be one of the following values:
* - CRM_APB1_DIV_1
* - CRM_APB1_DIV_2
* - CRM_APB1_DIV_4
* - CRM_APB1_DIV_8
* - CRM_APB1_DIV_16
* @retval none
*/
void crm_apb1_div_set(crm_apb1_div_type value)
{
CRM->cfg_bit.apb1div = value;
}
/**
* @brief set crm apb2 division
* @note the maximum frequency of APB1/APB2 clock is 120 MHz
* @param value
* this parameter can be one of the following values:
* - CRM_APB2_DIV_1
* - CRM_APB2_DIV_2
* - CRM_APB2_DIV_4
* - CRM_APB2_DIV_8
* - CRM_APB2_DIV_16
* @retval none
*/
void crm_apb2_div_set(crm_apb2_div_type value)
{
CRM->cfg_bit.apb2div = value;
}
/**
* @brief set crm adc division
* @param value
* this parameter can be one of the following values:
* - CRM_ADC_DIV_2
* - CRM_ADC_DIV_4
* - CRM_ADC_DIV_6
* - CRM_ADC_DIV_8
* - CRM_ADC_DIV_12
* - CRM_ADC_DIV_16
* @retval none
*/
void crm_adc_clock_div_set(crm_adc_div_type div_value)
{
CRM->cfg_bit.adcdiv_l = div_value & 0x03;
CRM->cfg_bit.adcdiv_h = (div_value >> 2) & 0x01;
}
/**
* @brief set crm usb division
* @param value
* this parameter can be one of the following values:
* - CRM_USB_DIV_1_5
* - CRM_USB_DIV_1
* - CRM_USB_DIV_2_5
* - CRM_USB_DIV_2
* - CRM_USB_DIV_3_5
* - CRM_USB_DIV_3
* - CRM_USB_DIV_4
* @retval none
*/
void crm_usb_clock_div_set(crm_usb_div_type div_value)
{
CRM->cfg_bit.usbdiv_l = div_value & 0x03;
CRM->cfg_bit.usbdiv_h = (div_value >> 2) & 0x01;
}
/**
* @brief enable or disable clock failure detection
* @param new_state (TRUE or FALSE)
* @retval none
*/
void crm_clock_failure_detection_enable(confirm_state new_state)
{
CRM->ctrl_bit.cfden = new_state;
}
/**
* @brief battery powered domain software reset
* @param new_state (TRUE or FALSE)
* @retval none
*/
void crm_battery_powered_domain_reset(confirm_state new_state)
{
CRM->bpdc_bit.bpdrst = new_state;
}
/**
* @brief config crm pll
* @param clock_source
* this parameter can be one of the following values:
* - CRM_PLL_SOURCE_HICK
* - CRM_PLL_SOURCE_HEXT
* - CRM_PLL_SOURCE_HEXT_DIV
* @param mult_value (CRM_PLL_MULT_2~64)
* @param pll_range
* this parameter can be one of the following values:
* - CRM_PLL_OUTPUT_RANGE_LE72MHZ
* - CRM_PLL_OUTPUT_RANGE_GT72MHZ
* @retval none
*/
void crm_pll_config(crm_pll_clock_source_type clock_source, crm_pll_mult_type mult_value, crm_pll_output_range_type pll_range)
{
/* config pll clock source */
if(clock_source == CRM_PLL_SOURCE_HICK)
{
CRM->cfg_bit.pllrcs = FALSE;
CRM->misc1_bit.hickdiv = CRM_HICK48_NODIV;
}
else
{
CRM->cfg_bit.pllrcs = TRUE;
if(CRM_PLL_SOURCE_HEXT == clock_source)
{
CRM->cfg_bit.pllhextdiv = FALSE;
}
else
{
CRM->cfg_bit.pllhextdiv = TRUE;
}
}
/* config pll multiplication factor */
CRM->cfg_bit.pllmult_l = (mult_value & 0x0F);
CRM->cfg_bit.pllmult_h = ((mult_value & 0x30) >> 4);
/* config pll output range */
CRM->cfg_bit.pllrange = pll_range;
}
/**
* @brief select system clock source
* @param value
* this parameter can be one of the following values:
* - CRM_SCLK_HICK
* - CRM_SCLK_HEXT
* - CRM_SCLK_PLL
* @retval none
*/
void crm_sysclk_switch(crm_sclk_type value)
{
CRM->cfg_bit.sclksel = value;
DUMMY_NOP();
}
/**
* @brief indicate which clock source is used as system clock
* @param none
* @retval crm_sclk
* this return can be one of the following values:
* - CRM_SCLK_HICK
* - CRM_SCLK_HEXT
* - CRM_SCLK_PLL
*/
crm_sclk_type crm_sysclk_switch_status_get(void)
{
return (crm_sclk_type)CRM->cfg_bit.sclksts;
}
/**
* @brief get crm clocks freqency
* @param clocks
* - pointer to the crm_clocks_freq structure
* @retval none
*/
void crm_clocks_freq_get(crm_clocks_freq_type *clocks_struct)
{
uint32_t hext_prediv = 0, pll_mult = 0, pll_mult_h = 0, pll_clock_source = 0, temp = 0, div_value = 0;
crm_sclk_type sclk_source;
static const uint8_t sclk_ahb_div_table[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
static const uint8_t ahb_apb1_div_table[8] = {0, 0, 0, 0, 1, 2, 3, 4};
static const uint8_t ahb_apb2_div_table[8] = {0, 0, 0, 0, 1, 2, 3, 4};
static const uint8_t adc_div_table[8] = {2, 4, 6, 8, 2, 12, 8, 16};
/* get sclk source */
sclk_source = crm_sysclk_switch_status_get();
switch(sclk_source)
{
case CRM_SCLK_HICK:
if(((CRM->misc3_bit.hick_to_sclk) != RESET) && ((CRM->misc1_bit.hickdiv) != RESET))
clocks_struct->sclk_freq = HICK_VALUE * 6;
else
clocks_struct->sclk_freq = HICK_VALUE;
break;
case CRM_SCLK_HEXT:
clocks_struct->sclk_freq = HEXT_VALUE;
break;
case CRM_SCLK_PLL:
pll_clock_source = CRM->cfg_bit.pllrcs;
/* get multiplication factor */
pll_mult = CRM->cfg_bit.pllmult_l;
pll_mult_h = CRM->cfg_bit.pllmult_h;
/* process high bits */
if((pll_mult_h != 0U) || (pll_mult == 15U))
{
pll_mult += ((16U * pll_mult_h) + 1U);
}
else
{
pll_mult += 2U;
}
if (pll_clock_source == 0x00)
{
/* hick divided by 2 selected as pll clock entry */
clocks_struct->sclk_freq = (HICK_VALUE >> 1) * pll_mult;
}
else
{
/* hext selected as pll clock entry */
if (CRM->cfg_bit.pllhextdiv != RESET)
{
hext_prediv = CRM->misc3_bit.hextdiv;
/* hext clock divided by 2 */
clocks_struct->sclk_freq = (HEXT_VALUE / (hext_prediv + 2)) * pll_mult;
}
else
{
clocks_struct->sclk_freq = HEXT_VALUE * pll_mult;
}
}
break;
default:
clocks_struct->sclk_freq = HICK_VALUE;
break;
}
/* compute sclk, ahbclk, abp1clk apb2clk and adcclk frequencies */
/* get ahb division */
temp = CRM->cfg_bit.ahbdiv;
div_value = sclk_ahb_div_table[temp];
/* ahbclk frequency */
clocks_struct->ahb_freq = clocks_struct->sclk_freq >> div_value;
/* get apb1 division */
temp = CRM->cfg_bit.apb1div;
div_value = ahb_apb1_div_table[temp];
/* apb1clk frequency */
clocks_struct->apb1_freq = clocks_struct->ahb_freq >> div_value;
/* get apb2 division */
temp = CRM->cfg_bit.apb2div;
div_value = ahb_apb2_div_table[temp];
/* apb2clk frequency */
clocks_struct->apb2_freq = clocks_struct->ahb_freq >> div_value;
/* get adc division */
temp = CRM->cfg_bit.adcdiv_h;
temp = ((temp << 2) | (CRM->cfg_bit.adcdiv_l));
div_value = adc_div_table[temp];
/* adcclk clock frequency */
clocks_struct->adc_freq = clocks_struct->apb2_freq / div_value;
}
/**
* @brief set crm clkout
* @param clkout
* this parameter can be one of the following values:
* - CRM_CLKOUT_NOCLK
* - CRM_CLKOUT_LICK
* - CRM_CLKOUT_LEXT
* - CRM_CLKOUT_SCLK
* - CRM_CLKOUT_HICK
* - CRM_CLKOUT_HEXT
* - CRM_CLKOUT_PLL_DIV_2
* - CRM_CLKOUT_PLL_DIV_4
* - CRM_CLKOUT_USB
* - CRM_CLKOUT_ADC
* @retval none
*/
void crm_clock_out_set(crm_clkout_select_type clkout)
{
CRM->cfg_bit.clkout_sel = clkout & 0x7;
CRM->misc1_bit.clkout_sel = (clkout >> 3) & 0x1;
}
/**
* @brief config crm interrupt
* @param int
* this parameter can be any combination of the following values:
* - CRM_LICK_STABLE_INT
* - CRM_LEXT_STABLE_INT
* - CRM_HICK_STABLE_INT
* - CRM_HEXT_STABLE_INT
* - CRM_PLL_STABLE_INT
* @param new_state (TRUE or FALSE)
* @retval none
*/
void crm_interrupt_enable(uint32_t crm_int, confirm_state new_state)
{
if(new_state == TRUE)
CRM->clkint |= crm_int;
else
CRM->clkint &= ~crm_int;
}
/**
* @brief auto step clock switch enable
* @param new_state (TRUE or FALSE)
* @retval none
*/
void crm_auto_step_mode_enable(confirm_state new_state)
{
if(new_state == TRUE)
CRM->misc3_bit.auto_step_en = CRM_AUTO_STEP_MODE_ENABLE;
else
CRM->misc3_bit.auto_step_en = CRM_AUTO_STEP_MODE_DISABLE;
}
/**
* @brief usbdev interrupt remapping control
* @param int_remap
* this parameter can be one of the following values:
* - CRM_USB_INT19_INT20
* - CRM_USB_INT73_INT74
* @retval none
*/
void crm_usb_interrupt_remapping_set(crm_usb_int_map_type int_remap)
{
CRM->intmap_bit.usbintmap = int_remap;
}
/**
* @brief config hick divider select
* @param value
* this parameter can be one of the following values:
* - CRM_HICK48_DIV6
* - CRM_HICK48_NODIV
* @retval none
*/
void crm_hick_divider_select(crm_hick_div_6_type value)
{
CRM->misc1_bit.hickdiv = value;
}
/**
* @brief hick as system clock frequency select
* @param value
* this parameter can be one of the following values:
* - CRM_HICK_SCLK_8MHZ
* - CRM_HICK_SCLK_48MHZ
* @retval none
*/
void crm_hick_sclk_frequency_select(crm_hick_sclk_frequency_type value)
{
crm_hick_divider_select(CRM_HICK48_NODIV);
CRM->misc3_bit.hick_to_sclk = value;
}
/**
* @brief usb 48 mhz clock source select
* @param value
* this parameter can be one of the following values:
* - CRM_USB_CLOCK_SOURCE_PLL
* - CRM_USB_CLOCK_SOURCE_HICK
* @retval none
*/
void crm_usb_clock_source_select(crm_usb_clock_source_type value)
{
if(value == CRM_USB_CLOCK_SOURCE_HICK)
{
crm_hick_sclk_frequency_select(CRM_HICK_SCLK_48MHZ);
}
CRM->misc3_bit.hick_to_usb = value;
}
/**
* @brief enable or disable clkout direct to tmr10 channel 1
* @param new_state (TRUE or FALSE)
* @retval none
*/
void crm_clkout_to_tmr10_enable(confirm_state new_state)
{
CRM->misc2_bit.clk_to_tmr = new_state;
}
/**
* @brief set hext clock division
* @param value
* this parameter can be one of the following values:
* - CRM_HEXT_DIV_2
* - CRM_HEXT_DIV_3
* - CRM_HEXT_DIV_4
* - CRM_HEXT_DIV_5
* @retval none
*/
void crm_hext_clock_div_set(crm_hext_div_type value)
{
CRM->misc3_bit.hextdiv = value;
}
/**
* @brief set crm clkout division
* @param clkout_div
* this parameter can be one of the following values:
* - CRM_CLKOUT_DIV_1
* - CRM_CLKOUT_DIV_2
* - CRM_CLKOUT_DIV_4
* - CRM_CLKOUT_DIV_8
* - CRM_CLKOUT_DIV_16
* - CRM_CLKOUT_DIV_64
* - CRM_CLKOUT_DIV_128
* - CRM_CLKOUT_DIV_256
* - CRM_CLKOUT_DIV_512
* @retval none
*/
void crm_clkout_div_set(crm_clkout_div_type clkout_div)
{
CRM->misc1_bit.clkoutdiv = clkout_div;
}
#if defined (AT32F407xx)
/**
* @brief set emac output pulse width
* @param width
* this parameter can be one of the following values:
* - CRM_EMAC_PULSE_125MS
* - CRM_EMAC_PULSE_1SCLK
* @retval none
*/
void crm_emac_output_pulse_set(crm_emac_output_pulse_type width)
{
CRM->misc3_bit.emac_pps_sel = width;
}
#endif
/**
* @}
*/
#endif
/**
* @}
*/
/**
* @}
*/

View File

@@ -0,0 +1,95 @@
/**
**************************************************************************
* @file at32f403a_407_debug.c
* @brief contains all the functions for the debug firmware library
**************************************************************************
* Copyright notice & Disclaimer
*
* The software Board Support Package (BSP) that is made available to
* download from Artery official website is the copyrighted work of Artery.
* Artery authorizes customers to use, copy, and distribute the BSP
* software and its related documentation for the purpose of design and
* development in conjunction with Artery microcontrollers. Use of the
* software is governed by this copyright notice and the following disclaimer.
*
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
*
**************************************************************************
*/
#include "at32f403a_407_conf.h"
/** @addtogroup AT32F403A_407_periph_driver
* @{
*/
/** @defgroup DEBUG
* @brief DEBUG driver modules
* @{
*/
#ifdef DEBUG_MODULE_ENABLED
/** @defgroup DEBUG_private_functions
* @{
*/
/**
* @brief get debug device id
* @param none
* @retval the debug device id
*/
uint32_t debug_device_id_get(void)
{
return DEBUGMCU->pid;
}
/**
* @brief set periph debug mode
* @param periph_debug_mode
* this parameter can be any combination of the following values:
* - DEBUG_SLEEP - DEBUG_DEEPSLEEP
* - DEBUG_STANDBY - DEBUG_WDT_PAUSE
* - DEBUG_WWDT_PAUSE - DEBUG_TMR1_PAUSE
* - DEBUG_TMR3_PAUSE - DEBUG_I2C1_SMBUS_TIMEOUT
* - DEBUG_I2C2_SMBUS_TIMEOUT - DEBUG_I2C3_SMBUS_TIMEOUT
* - DEBUG_TMR2_PAUSE - DEBUG_TMR4_PAUSE
* - DEBUG_CAN1_PAUSE - DEBUG_TMR8_PAUSE
* - DEBUG_TMR5_PAUSE - DEBUG_TMR6_PAUSE
* - DEBUG_TMR7_PAUSE - DEBUG_CAN2_PAUSE
* - DEBUG_TMR12_PAUSE - DEBUG_TMR13_PAUSE
* - DEBUG_TMR14_PAUSE - DEBUG_TMR9_PAUSE
* - DEBUG_TMR10_PAUSE - DEBUG_TMR11_PAUSE
* @param new_state (TRUE or FALSE)
* @retval none
*/
void debug_periph_mode_set(uint32_t periph_debug_mode, confirm_state new_state)
{
if(new_state != FALSE)
{
DEBUGMCU->ctrl |= periph_debug_mode;
}
else
{
DEBUGMCU->ctrl &= ~periph_debug_mode;
}
}
/**
* @}
*/
#endif
/**
* @}
*/
/**
* @}
*/

View File

@@ -0,0 +1,271 @@
/**
**************************************************************************
* @file at32f403a_407_exint.c
* @brief contains all the functions for the exint firmware library
**************************************************************************
* Copyright notice & Disclaimer
*
* The software Board Support Package (BSP) that is made available to
* download from Artery official website is the copyrighted work of Artery.
* Artery authorizes customers to use, copy, and distribute the BSP
* software and its related documentation for the purpose of design and
* development in conjunction with Artery microcontrollers. Use of the
* software is governed by this copyright notice and the following disclaimer.
*
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
*
**************************************************************************
*/
#include "at32f403a_407_conf.h"
/** @addtogroup AT32F403A_407_periph_driver
* @{
*/
/** @defgroup EXINT
* @brief EXINT driver modules
* @{
*/
#ifdef EXINT_MODULE_ENABLED
/** @defgroup EXINT_private_functions
* @{
*/
/**
* @brief exint reset
* @param none
* @retval none
*/
void exint_reset(void)
{
EXINT->inten = 0x00000000;
EXINT->polcfg1 = 0x00000000;
EXINT->polcfg2 = 0x00000000;
EXINT->evten = 0x00000000;
EXINT->intsts = 0x000FFFFF;
}
/**
* @brief exint default para init
* @param exint_struct
* - to the structure of exint_init_type
* @retval none
*/
void exint_default_para_init(exint_init_type *exint_struct)
{
exint_struct->line_enable = FALSE;
exint_struct->line_select = EXINT_LINE_NONE;
exint_struct->line_polarity = EXINT_TRIGGER_FALLING_EDGE;
exint_struct->line_mode = EXINT_LINE_EVENT;
}
/**
* @brief exint init
* @param exint_struct
* - to the structure of exint_init_type
* @retval none
*/
void exint_init(exint_init_type *exint_struct)
{
uint32_t line_index = 0;
line_index = exint_struct->line_select;
EXINT->inten &= ~line_index;
EXINT->evten &= ~line_index;
if(exint_struct->line_enable != FALSE)
{
if(exint_struct->line_mode == EXINT_LINE_INTERRUPUT)
{
EXINT->inten |= line_index;
}
else
{
EXINT->evten |= line_index;
}
EXINT->polcfg1 &= ~line_index;
EXINT->polcfg2 &= ~line_index;
if(exint_struct->line_polarity == EXINT_TRIGGER_RISING_EDGE)
{
EXINT->polcfg1 |= line_index;
}
else if(exint_struct->line_polarity == EXINT_TRIGGER_FALLING_EDGE)
{
EXINT->polcfg2 |= line_index;
}
else
{
EXINT->polcfg1 |= line_index;
EXINT->polcfg2 |= line_index;
}
}
}
/**
* @brief clear exint flag
* @param exint_line
* this parameter can be any combination of the following values:
* - EXINT_LINE_0
* - EXINT_LINE_1
* ...
* - EXINT_LINE_18
* - EXINT_LINE_19
* @retval none
*/
void exint_flag_clear(uint32_t exint_line)
{
if((EXINT->swtrg & exint_line) == exint_line)
{
EXINT->intsts = exint_line;
EXINT->intsts = exint_line;
}
else
{
EXINT->intsts = exint_line;
}
}
/**
* @brief get exint flag
* @param exint_line
* this parameter can be one of the following values:
* - EXINT_LINE_0
* - EXINT_LINE_1
* ...
* - EXINT_LINE_18
* - EXINT_LINE_19
* @retval the new state of exint flag(SET or RESET).
*/
flag_status exint_flag_get(uint32_t exint_line)
{
flag_status status = RESET;
uint32_t exint_flag =0;
exint_flag = EXINT->intsts & exint_line;
if((exint_flag != (uint16_t)RESET))
{
status = SET;
}
else
{
status = RESET;
}
return status;
}
/**
* @brief get exint interrupt flag
* @param exint_line
* this parameter can be one of the following values:
* - EXINT_LINE_0
* - EXINT_LINE_1
* ...
* - EXINT_LINE_18
* - EXINT_LINE_19
* @retval the new state of exint flag(SET or RESET).
*/
flag_status exint_interrupt_flag_get(uint32_t exint_line)
{
flag_status status = RESET;
uint32_t exint_flag = 0;
exint_flag = EXINT->intsts & exint_line;
exint_flag = exint_flag & EXINT->inten;
if((exint_flag != (uint16_t)RESET))
{
status = SET;
}
else
{
status = RESET;
}
return status;
}
/**
* @brief generate exint software interrupt event
* @param exint_line
* this parameter can be one of the following values:
* - EXINT_LINE_0
* - EXINT_LINE_1
* ...
* - EXINT_LINE_18
* - EXINT_LINE_19
* @retval none
*/
void exint_software_interrupt_event_generate(uint32_t exint_line)
{
EXINT->swtrg |= exint_line;
}
/**
* @brief enable or disable exint interrupt
* @param exint_line
* this parameter can be any combination of the following values:
* - EXINT_LINE_0
* - EXINT_LINE_1
* ...
* - EXINT_LINE_18
* - EXINT_LINE_19
* @param new_state: new state of exint interrupt.
* this parameter can be: TRUE or FALSE.
* @retval none
*/
void exint_interrupt_enable(uint32_t exint_line, confirm_state new_state)
{
if(new_state == TRUE)
{
EXINT->inten |= exint_line;
}
else
{
EXINT->inten &= ~exint_line;
}
}
/**
* @brief enable or disable exint event
* @param exint_line
* this parameter can be any combination of the following values:
* - EXINT_LINE_0
* - EXINT_LINE_1
* ...
* - EXINT_LINE_18
* - EXINT_LINE_19
* @param new_state: new state of exint event.
* this parameter can be: TRUE or FALSE.
* @retval none
*/
void exint_event_enable(uint32_t exint_line, confirm_state new_state)
{
if(new_state == TRUE)
{
EXINT->evten |= exint_line;
}
else
{
EXINT->evten &= ~exint_line;
}
}
/**
* @}
*/
#endif
/**
* @}
*/
/**
* @}
*/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,663 @@
/**
**************************************************************************
* @file at32f403a_407_gpio.c
* @brief contains all the functions for the gpio firmware library
**************************************************************************
* Copyright notice & Disclaimer
*
* The software Board Support Package (BSP) that is made available to
* download from Artery official website is the copyrighted work of Artery.
* Artery authorizes customers to use, copy, and distribute the BSP
* software and its related documentation for the purpose of design and
* development in conjunction with Artery microcontrollers. Use of the
* software is governed by this copyright notice and the following disclaimer.
*
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
*
**************************************************************************
*/
#include "at32f403a_407_conf.h"
/** @addtogroup AT32F403A_407_periph_driver
* @{
*/
/** @defgroup GPIO
* @brief GPIO driver modules
* @{
*/
#ifdef GPIO_MODULE_ENABLED
/** @defgroup GPIO_private_functions
* @{
*/
/**
* @brief reset the gpio register
* @param gpio_x: to select the gpio peripheral.
* this parameter can be one of the following values:
* GPIOA, GPIOB, GPIOC, GPIOD, GPIOE.
* @retval none
*/
void gpio_reset(gpio_type *gpio_x)
{
if(gpio_x == GPIOA)
{
crm_periph_reset(CRM_GPIOA_PERIPH_RESET, TRUE);
crm_periph_reset(CRM_GPIOA_PERIPH_RESET, FALSE);
}
else if(gpio_x == GPIOB)
{
crm_periph_reset(CRM_GPIOB_PERIPH_RESET, TRUE);
crm_periph_reset(CRM_GPIOB_PERIPH_RESET, FALSE);
}
else if(gpio_x == GPIOC)
{
crm_periph_reset(CRM_GPIOC_PERIPH_RESET, TRUE);
crm_periph_reset(CRM_GPIOC_PERIPH_RESET, FALSE);
}
else if(gpio_x == GPIOD)
{
crm_periph_reset(CRM_GPIOD_PERIPH_RESET, TRUE);
crm_periph_reset(CRM_GPIOD_PERIPH_RESET, FALSE);
}
else if(gpio_x == GPIOE)
{
crm_periph_reset(CRM_GPIOE_PERIPH_RESET, TRUE);
crm_periph_reset(CRM_GPIOE_PERIPH_RESET, FALSE);
}
}
/**
* @brief reset the mux functions (remap, event control
and exint configuration) registers to their default values.
* @param none
* @retval none
*/
void gpio_iomux_reset(void)
{
crm_periph_reset(CRM_IOMUX_PERIPH_RESET, TRUE);
crm_periph_reset(CRM_IOMUX_PERIPH_RESET, FALSE);
}
/**
* @brief initialize the gpio peripheral.
* @param gpio_x: to select the gpio peripheral.
* this parameter can be one of the following values:
* GPIOA, GPIOB, GPIOC, GPIOD, GPIOE.
* @param gpio_init_struct: pointer to gpio init structure.
* @retval none
*/
void gpio_init(gpio_type *gpio_x, gpio_init_type *gpio_init_struct)
{
uint32_t temp;
uint16_t pinx_value, pin_index;
pin_index = (uint16_t)gpio_init_struct->gpio_pins;
/* pinx_value indecate pin grounp bit[3:0] from modey[1:0] confy[1:0] */
/* pin input analog config */
if(gpio_init_struct->gpio_mode == GPIO_MODE_ANALOG)
{
pinx_value = 0x00;
}
/* pin input config */
else if(gpio_init_struct->gpio_mode == GPIO_MODE_INPUT)
{
pinx_value = gpio_init_struct->gpio_pull & 0x0F;
if(gpio_init_struct->gpio_pull == GPIO_PULL_UP)
{
gpio_x->scr = pin_index;
}
else if(gpio_init_struct->gpio_pull == GPIO_PULL_DOWN)
{
gpio_x->clr = pin_index;
}
}
else
{
pinx_value = (gpio_init_struct->gpio_mode & 0x08) | (gpio_init_struct->gpio_out_type & 0x04) | \
(gpio_init_struct->gpio_drive_strength & 0x03);
}
/* pin 0~7 config */
if(((uint32_t)pin_index & ((uint32_t)0x00FF)) != 0x00)
{
for(temp = 0; temp < 0x08; temp++)
{
if((1 << temp) & pin_index)
{
gpio_x->cfglr &= (uint32_t)~(0x0F << (temp * 4));
gpio_x->cfglr |= (uint32_t)(pinx_value << (temp * 4));
}
}
}
/* pin 8~15 config */
if(pin_index > 0x00ff)
{
pin_index = pin_index >> 8;
for(temp = 0; temp < 0x8; temp++)
{
if((1 << temp) & pin_index)
{
gpio_x->cfghr &= (uint32_t)~(0xf << (temp * 4));
gpio_x->cfghr |= (uint32_t)(pinx_value << (temp * 4));
}
}
}
}
/**
* @brief fill each gpio_init_type member with its default value.
* @param gpio_init_struct : pointer to a gpio_init_type structure which will be initialized.
* @retval none
*/
void gpio_default_para_init(gpio_init_type *gpio_init_struct)
{
/* reset gpio init structure parameters values */
gpio_init_struct->gpio_pins = GPIO_PINS_ALL;
gpio_init_struct->gpio_mode = GPIO_MODE_INPUT;
gpio_init_struct->gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct->gpio_pull = GPIO_PULL_NONE;
gpio_init_struct->gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
}
/**
* @brief read the specified input port pin.
* @param gpio_x: to select the gpio peripheral.
* this parameter can be one of the following values:
* GPIOA, GPIOB, GPIOC, GPIOD, GPIOE.
* @param pins: gpio pin number
* this parameter can be one of the following values:
* - GPIO_PINS_0
* - GPIO_PINS_1
* - GPIO_PINS_2
* - GPIO_PINS_3
* - GPIO_PINS_4
* - GPIO_PINS_5
* - GPIO_PINS_6
* - GPIO_PINS_7
* - GPIO_PINS_8
* - GPIO_PINS_9
* - GPIO_PINS_10
* - GPIO_PINS_11
* - GPIO_PINS_12
* - GPIO_PINS_13
* - GPIO_PINS_14
* - GPIO_PINS_15
* @retval flag_status (SET or RESET)
*/
flag_status gpio_input_data_bit_read(gpio_type *gpio_x, uint16_t pins)
{
flag_status status = RESET;
if(pins != (pins & gpio_x->idt))
{
status = RESET;
}
else
{
status = SET;
}
return status;
}
/**
* @brief read the specified gpio input data port.
* @param gpio_x: to select the gpio peripheral.
* this parameter can be one of the following values:
* GPIOA, GPIOB, GPIOC, GPIOD, GPIOE.
* @retval gpio input data port value.
*/
uint16_t gpio_input_data_read(gpio_type *gpio_x)
{
return ((uint16_t)(gpio_x->idt));
}
/**
* @brief read the specified output port pin.
* @param gpio_x: to select the gpio peripheral.
* this parameter can be one of the following values:
* GPIOA, GPIOB, GPIOC, GPIOD, GPIOE.
* @param pins: gpio pin number
* this parameter can be one of the following values:
* - GPIO_PINS_0
* - GPIO_PINS_1
* - GPIO_PINS_2
* - GPIO_PINS_3
* - GPIO_PINS_4
* - GPIO_PINS_5
* - GPIO_PINS_6
* - GPIO_PINS_7
* - GPIO_PINS_8
* - GPIO_PINS_9
* - GPIO_PINS_10
* - GPIO_PINS_11
* - GPIO_PINS_12
* - GPIO_PINS_13
* - GPIO_PINS_14
* - GPIO_PINS_15
* @retval flag_status (SET or RESET)
*/
flag_status gpio_output_data_bit_read(gpio_type *gpio_x, uint16_t pins)
{
flag_status status = RESET;
if((gpio_x->odt & pins) != RESET)
{
status = SET;
}
else
{
status = RESET;
}
return status;
}
/**
* @brief read the specified gpio ouput data port.
* @param gpio_x: to select the gpio peripheral.
* this parameter can be one of the following values:
* GPIOA, GPIOB, GPIOC, GPIOD, GPIOE.
* @retval gpio input data port value.
*/
uint16_t gpio_output_data_read(gpio_type *gpio_x)
{
return ((uint16_t)(gpio_x->odt));
}
/**
* @brief set the selected data port bits.
* @param gpio_x: to select the gpio peripheral.
* this parameter can be one of the following values:
* GPIOA, GPIOB, GPIOC, GPIOD, GPIOE.
* @param pins: gpio pin number
* parameter can be any combination of gpio_pin_x, gpio_pin_x as following values:
* - GPIO_PINS_0
* - GPIO_PINS_1
* - GPIO_PINS_2
* - GPIO_PINS_3
* - GPIO_PINS_4
* - GPIO_PINS_5
* - GPIO_PINS_6
* - GPIO_PINS_7
* - GPIO_PINS_8
* - GPIO_PINS_9
* - GPIO_PINS_10
* - GPIO_PINS_11
* - GPIO_PINS_12
* - GPIO_PINS_13
* - GPIO_PINS_14
* - GPIO_PINS_15
* - GPIO_PINS_ALL
* @retval none
*/
void gpio_bits_set(gpio_type *gpio_x, uint16_t pins)
{
gpio_x->scr = pins;
}
/**
* @brief clear the selected data port bits.
* @param gpio_x: to select the gpio peripheral.
* this parameter can be one of the following values:
* GPIOA, GPIOB, GPIOC, GPIOD, GPIOE.
* @param pins: gpio pin number
* parameter can be any combination of gpio_pin_x, gpio_pin_x as following values:
* - GPIO_PINS_0
* - GPIO_PINS_1
* - GPIO_PINS_2
* - GPIO_PINS_3
* - GPIO_PINS_4
* - GPIO_PINS_5
* - GPIO_PINS_6
* - GPIO_PINS_7
* - GPIO_PINS_8
* - GPIO_PINS_9
* - GPIO_PINS_10
* - GPIO_PINS_11
* - GPIO_PINS_12
* - GPIO_PINS_13
* - GPIO_PINS_14
* - GPIO_PINS_15
* - GPIO_PINS_ALL
* @retval none
*/
void gpio_bits_reset(gpio_type *gpio_x, uint16_t pins)
{
gpio_x->clr = pins;
}
/**
* @brief set or clear the selected data port bit.
* @param gpio_x: to select the gpio peripheral.
* this parameter can be one of the following values:
* GPIOA, GPIOB, GPIOC, GPIOD, GPIOE.
* @param pins: gpio pin number
* parameter can be any combination of gpio_pin_x, gpio_pin_x as following values:
* - GPIO_PINS_0
* - GPIO_PINS_1
* - GPIO_PINS_2
* - GPIO_PINS_3
* - GPIO_PINS_4
* - GPIO_PINS_5
* - GPIO_PINS_6
* - GPIO_PINS_7
* - GPIO_PINS_8
* - GPIO_PINS_9
* - GPIO_PINS_10
* - GPIO_PINS_11
* - GPIO_PINS_12
* - GPIO_PINS_13
* - GPIO_PINS_14
* - GPIO_PINS_15
* - GPIO_PINS_ALL
* @param bit_state: specifies the value to be written to the selected bit (TRUE or FALSE).
* @retval none
*/
void gpio_bits_write(gpio_type *gpio_x, uint16_t pins, confirm_state bit_state)
{
if(bit_state != FALSE)
{
gpio_x->scr = pins;
}
else
{
gpio_x->clr = pins;
}
}
/**
* @brief write data to the specified gpio data port.
* @param gpio_x: to select the gpio peripheral.
* this parameter can be one of the following values:
* GPIOA, GPIOB, GPIOC, GPIOD, GPIOE.
* @param port_value: specifies the value to be written to the port output data register.
* @retval none
*/
void gpio_port_write(gpio_type *gpio_x, uint16_t port_value)
{
gpio_x->odt = port_value;
}
/**
* @brief write protect gpio pins configuration registers.
* @param gpio_x: to select the gpio peripheral.
* this parameter can be one of the following values:
* GPIOA, GPIOB, GPIOC, GPIOD, GPIOE.
* @param pins: gpio pin number
* this parameter can be any combination of the following:
* - GPIO_PINS_0
* - GPIO_PINS_1
* - GPIO_PINS_2
* - GPIO_PINS_3
* - GPIO_PINS_4
* - GPIO_PINS_5
* - GPIO_PINS_6
* - GPIO_PINS_7
* - GPIO_PINS_8
* - GPIO_PINS_9
* - GPIO_PINS_10
* - GPIO_PINS_11
* - GPIO_PINS_12
* - GPIO_PINS_13
* - GPIO_PINS_14
* - GPIO_PINS_15
* - GPIO_PINS_ALL
* @retval none
*/
void gpio_pin_wp_config(gpio_type *gpio_x, uint16_t pins)
{
uint32_t temp = 0x00010000;
temp |= pins;
/* set wpen bit */
gpio_x->wpr = temp;
/* reset wpen bit */
gpio_x->wpr = pins;
/* set wpen bit */
gpio_x->wpr = temp;
/* read wpen bit*/
temp = gpio_x->wpr;
/* read wpen bit*/
temp = gpio_x->wpr;
}
/**
* @brief enable or disable gpio pins huge driven.
* @param gpio_x: to select the gpio peripheral.
* this parameter can be one of the following values:
* GPIOA, GPIOB, GPIOC, GPIOD, GPIOE.
* @param pins: gpio pin number
* parameter can be any combination of gpio_pin_x, gpio_pin_x as following values:
* - GPIO_PINS_0
* - GPIO_PINS_1
* - GPIO_PINS_2
* - GPIO_PINS_3
* - GPIO_PINS_4
* - GPIO_PINS_5
* - GPIO_PINS_6
* - GPIO_PINS_7
* - GPIO_PINS_8
* - GPIO_PINS_9
* - GPIO_PINS_10
* - GPIO_PINS_11
* - GPIO_PINS_12
* - GPIO_PINS_13
* - GPIO_PINS_14
* - GPIO_PINS_15
* - GPIO_PINS_ALL
* @param new_state: new state of the slew rate.
* this parameter can be: true or false.
* @retval none
*/
void gpio_pins_huge_driven_config(gpio_type *gpio_x, uint16_t pins, confirm_state new_state)
{
if(new_state != FALSE)
{
gpio_x->hdrv |= pins;
}
else
{
gpio_x->hdrv &= ~pins;
}
}
/**
* @brief select the gpio pin used as event output.
* @param gpio_port_source: select the gpio port to be used as source
* for event output.
* this parameter can be one of the following values:
* - GPIO_PORT_SOURCE_GPIOA
* - GPIO_PORT_SOURCE_GPIOB
* - GPIO_PORT_SOURCE_GPIOC
* - GPIO_PORT_SOURCE_GPIOD
* - GPIO_PORT_SOURCE_GPIOE
* @param gpio_pin_source: specifies the pin for the event output.
* this parameter can be one of the following values:
* - GPIO_PINS_SOURCE0
* - GPIO_PINS_SOURCE1
* - GPIO_PINS_SOURCE2
* - GPIO_PINS_SOURCE3
* - GPIO_PINS_SOURCE4
* - GPIO_PINS_SOURCE5
* - GPIO_PINS_SOURCE6
* - GPIO_PINS_SOURCE7
* - GPIO_PINS_SOURCE8
* - GPIO_PINS_SOURCE9
* - GPIO_PINS_SOURCE10
* - GPIO_PINS_SOURCE11
* - GPIO_PINS_SOURCE12
* - GPIO_PINS_SOURCE13
* - GPIO_PINS_SOURCE14
* - GPIO_PINS_SOURCE15
* @retval none
*/
void gpio_event_output_config(gpio_port_source_type gpio_port_source, gpio_pins_source_type gpio_pin_source)
{
uint32_t tmpreg = 0x00;
tmpreg = IOMUX->evtout;
/* clear the port[6:4] and pin[3:0] bits */
tmpreg &= 0x80;
tmpreg |= (uint32_t)gpio_port_source << 0x04;
tmpreg |= gpio_pin_source;
IOMUX->evtout = tmpreg;
}
/**
* @brief enable or disable the event output.
* @param confirm_state: new state of the event output.
* this parameter can be: TRUE or FALSE.
* @retval none
*/
void gpio_event_output_enable(confirm_state new_state)
{
IOMUX->evtout_bit.evoen = new_state;
}
/**
* @brief iomux remap and debug i/o configuration.
* @param gpio_remap: select the pin to remap.
* this parameter can be one of the following values:
* - SPI1_MUX_01 - SPI1_MUX_10 - SPI1_MUX_11 - I2C1_MUX
* - USART1_MUX - USART2_MUX - USART3_MUX_01 - USART3_MUX_11
* - TMR1_MUX_01 - TMR1_MUX_11 - TMR2_MUX_01 - TMR2_MUX_10
* - TMR2_MUX_11 - TMR3_MUX_10 - TMR3_MUX_11 - TMR4_MUX
* - CAN_MUX_10 - CAN_MUX_11 - PD01_MUX - TMR5CH4_MUX
* - ADC1_EXTRGPRE_MUX - ADC1_EXTRGORD_MUX - ADC2_EXTRGPRE_MUX - ADC2_EXTRGORD_MUX
* - EMAC_MUX - CAN2_MUX - MII_RMII_SEL_MUX - SWJTAG_MUX_001
* - SWJTAG_MUX_010 - SWJTAG_MUX_100 - SPI3_MUX - TMR2ITR1_MUX
* - PTP_PPS_MUX - TMR9_MUX - XMC_NADV_MUX - SPI4_MUX
* - I2C3_MUX - SDIO2_MUX01 - SDIO2_MUX10 - SDIO2_MUX11
* - EXT_SPIM_EN_MUX - TMR9_GMUX - TMR1_GMUX_0001 - TMR1_GMUX_0011
* - TMR2_GMUX_01 - TMR2_GMUX_10 - TMR2_GMUX_11 - TMR2ITR1_GMUX_10
* - TMR2ITR1_GMUX_11 - TMR3_GMUX_0010 - TMR3_GMUX_0011 - TMR4_GMUX_0001
* - TMR5CH4_GMUX - UART5_GMUX_0001 - I2C1_GMUX_0001 - I2C3_GMUX_0001
* - SPI1_GMUX_0001 - SPI1_GMUX_0010 - SPI1_GMUX_0011 - SPI2_GMUX_0001
* - SPI2_GMUX_0010 - SPI3_GMUX_0001 - SPI3_GMUX_0010 - SPI3_GMUX_0011
* - SPI4_GMUX_0001 - SPI4_GMUX_0010 - SPI4_GMUX_0011 - CAN1_GMUX_0010
* - CAN1_GMUX_0011 - CAN2_GMUX_0001 - SDIO2_GMUX_0001 - SDIO2_GMUX_0010
* - SDIO2_GMUX_0011 - USART1_GMUX_0001 - USART2_GMUX_0001 - USART3_GMUX_0001
* - USART3_GMUX_0011 - UART4_GMUX_0010 - EXT_SPIM_GMUX_1000 - EXT_SPIM_GMUX_1001
* - ADC1_ETP_GMUX - ADC1_ETO_GMUX - ADC2_ETP_GMUX - ADC2_ETO_GMUX
* - SWJTAG_GMUX_001 - SWJTAG_GMUX_010 - SWJTAG_GMUX_100 - PD01_GMUX
* - XMC_GMUX_001 - XMC_GMUX_010 - XMC_NADV_GMUX - EMAC_GMUX_01
* - MII_RMII_SEL_GMUX - PTP_PPS_GMUX - USART6_GMUX - UART7_GMUX
* - UART8_GMUX
* @param new_state: (TRUE or FALSE)
* @retval none
*/
void gpio_pin_remap_config(uint32_t gpio_remap, confirm_state new_state)
{
uint32_t reg_addr, remap_mask;
uint8_t bit_offset, bit_num, bit_val;
/* get register address, bit offset, bit number and remap value */
reg_addr = IOMUX_BASE + (gpio_remap >> 24);
bit_offset = (gpio_remap >> 16) & 0xFF;
bit_num = (gpio_remap >> 8) & 0xFF;
bit_val = gpio_remap & 0xFF;
/* get remap mask value */
remap_mask = 0xFFFFFFFF << (32 - bit_num - bit_offset);
remap_mask = remap_mask >> (32 - bit_num - bit_offset);
remap_mask = remap_mask >> bit_offset;
remap_mask = remap_mask << bit_offset;
/* clear remap value */
*(uint32_t*)reg_addr &= ~remap_mask;
if(new_state != FALSE)
{
/* set remap value */
*(uint32_t*)reg_addr |= (uint32_t)(bit_val << bit_offset);
}
}
/**
* @brief select the gpio pin used as exint line.
* @param gpio_port_source: select the gpio port to be used as source for exint.
* this parameter can be one of the following values:
* - GPIO_PORT_SOURCE_GPIOA
* - GPIO_PORT_SOURCE_GPIOB
* - GPIO_PORT_SOURCE_GPIOC
* - GPIO_PORT_SOURCE_GPIOD
* - GPIO_PORT_SOURCE_GPIOE
* - GPIO_PORT_SOURCE_GPIOF
* - GPIO_PORT_SOURCE_GPIOG
* @param gpio_pin_source: specifies the pin for the event output.
* this parameter can be one of the following values:
* - GPIO_PINS_SOURCE0
* - GPIO_PINS_SOURCE1
* - GPIO_PINS_SOURCE2
* - GPIO_PINS_SOURCE3
* - GPIO_PINS_SOURCE4
* - GPIO_PINS_SOURCE5
* - GPIO_PINS_SOURCE6
* - GPIO_PINS_SOURCE7
* - GPIO_PINS_SOURCE8
* - GPIO_PINS_SOURCE9
* - GPIO_PINS_SOURCE10
* - GPIO_PINS_SOURCE11
* - GPIO_PINS_SOURCE12
* - GPIO_PINS_SOURCE13
* - GPIO_PINS_SOURCE14
* - GPIO_PINS_SOURCE15
* @retval none
*/
void gpio_exint_line_config(gpio_port_source_type gpio_port_source, gpio_pins_source_type gpio_pin_source)
{
uint32_t tmp = 0x00;
tmp = ((uint32_t)0x0F) << (0x04 * (gpio_pin_source & (uint8_t)0x03));
switch (gpio_pin_source >> 0x02)
{
case 0:
IOMUX->exintc1 &= ~tmp;
IOMUX->exintc1 |= (((uint32_t)gpio_port_source) << (0x04 * (gpio_pin_source & (uint8_t)0x03)));
break;
case 1:
IOMUX->exintc2 &= ~tmp;
IOMUX->exintc2 |= (((uint32_t)gpio_port_source) << (0x04 * (gpio_pin_source & (uint8_t)0x03)));
break;
case 2:
IOMUX->exintc3 &= ~tmp;
IOMUX->exintc3 |= (((uint32_t)gpio_port_source) << (0x04 * (gpio_pin_source & (uint8_t)0x03)));
break;
case 3:
IOMUX->exintc4 &= ~tmp;
IOMUX->exintc4 |= (((uint32_t)gpio_port_source) << (0x04 * (gpio_pin_source & (uint8_t)0x03)));
break;
default:
break;
}
}
/**
* @}
*/
#endif
/**
* @}
*/
/**
* @}
*/

View File

@@ -0,0 +1,730 @@
/**
**************************************************************************
* @file at32f403a_407_i2c.c
* @brief contains all the functions for the i2c firmware library
**************************************************************************
* Copyright notice & Disclaimer
*
* The software Board Support Package (BSP) that is made available to
* download from Artery official website is the copyrighted work of Artery.
* Artery authorizes customers to use, copy, and distribute the BSP
* software and its related documentation for the purpose of design and
* development in conjunction with Artery microcontrollers. Use of the
* software is governed by this copyright notice and the following disclaimer.
*
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
*
**************************************************************************
*/
#include "at32f403a_407_conf.h"
/** @addtogroup AT32F403A_407_periph_driver
* @{
*/
/** @defgroup I2C
* @brief I2C driver modules
* @{
*/
#ifdef I2C_MODULE_ENABLED
/** @defgroup I2C_private_functions
* @{
*/
/**
* @brief reset the i2c register
* @param i2c_x: to select the i2c peripheral.
* this parameter can be one of the following values:
* I2C1, I2C2, I2C3.
* @retval none
*/
void i2c_reset(i2c_type *i2c_x)
{
if(i2c_x == I2C1)
{
crm_periph_reset(CRM_I2C1_PERIPH_RESET, TRUE);
crm_periph_reset(CRM_I2C1_PERIPH_RESET, FALSE);
}
else if(i2c_x == I2C2)
{
crm_periph_reset(CRM_I2C2_PERIPH_RESET, TRUE);
crm_periph_reset(CRM_I2C2_PERIPH_RESET, FALSE);
}
else if(i2c_x == I2C3)
{
crm_periph_reset(CRM_I2C3_PERIPH_RESET, TRUE);
crm_periph_reset(CRM_I2C3_PERIPH_RESET, FALSE);
}
}
/**
* @brief software reset.
* @param i2c_x: to select the i2c peripheral.
* this parameter can be one of the following values:
* I2C1, I2C2, I2C3.
* @param new_state (TRUE or FALSE)
* @retval none
*/
void i2c_software_reset(i2c_type *i2c_x, confirm_state new_state)
{
i2c_x->ctrl1_bit.reset = new_state;
}
/**
* @brief init i2c speed and duty cycle.
* @param i2c_x: to select the i2c peripheral.
* this parameter can be one of the following values:
* I2C1, I2C2, I2C3.
* @param duty
* this parameter can be one of the following values:
* - I2C_FSMODE_DUTY_2_1: duty cycle 2:1
* - I2C_FSMODE_DUTY_16_9: duty cycle 16:9
* @param speed: i2c scl clock speed, such as 100000
* @retval none
*/
void i2c_init(i2c_type *i2c_x, i2c_fsmode_duty_cycle_type duty, uint32_t speed)
{
uint32_t apb_freq = 0;
uint16_t freq_mhz = 0, temp = 0;
crm_clocks_freq_type clocks;
/* disable i2c peripherals */
i2c_x->ctrl1_bit.i2cen = FALSE;
/* get system clock */
crm_clocks_freq_get(&clocks);
if((i2c_x == I2C1) || (i2c_x == I2C2))
{
apb_freq = clocks.apb1_freq;
}
else if(i2c_x == I2C3)
{
apb_freq = clocks.apb2_freq;
}
freq_mhz = (apb_freq / 1000000);
/* set i2c input clock frequency */
i2c_x->ctrl2_bit.clkfreq = freq_mhz;
/* standard mode */
if(speed <= 100000)
{
temp = (uint16_t)(apb_freq / (speed << 1));
if (temp < 0x04)
{
temp = 0x04;
}
/* set scl clock */
i2c_x->clkctrl_bit.speed = temp;
/* disable fast mode */
i2c_x->clkctrl_bit.speedmode = FALSE;
/* set the maximum rise time */
if((freq_mhz + 1) > 0x3F)
{
i2c_x->tmrise_bit.risetime = 0x3F;
}
else
{
i2c_x->tmrise_bit.risetime = (freq_mhz + 1);
}
}
/* fast mode */
else
{
if (duty == I2C_FSMODE_DUTY_2_1)
{
temp = (uint16_t)(apb_freq / (speed * 3));
/* the ratio of high level to low level is 1:2 */
i2c_x->clkctrl_bit.dutymode = I2C_FSMODE_DUTY_2_1;
}
else
{
temp = (uint16_t)(apb_freq / (speed * 25));
/* the ratio of high level to low level is 9:16 */
i2c_x->clkctrl_bit.dutymode = I2C_FSMODE_DUTY_16_9;
}
if (temp == 0)
{
temp = 0x0001;
}
/* set scl clock*/
i2c_x->clkctrl_bit.speed = temp;
/* set the mode to fast mode */
i2c_x->clkctrl_bit.speedmode = TRUE;
/* set the maximum rise time */
i2c_x->tmrise_bit.risetime = (uint16_t)(((freq_mhz * (uint16_t)300) / (uint16_t)1000) + (uint16_t)1);
}
}
/**
* @brief config own address1.
* @param i2c_x: to select the i2c peripheral.
* this parameter can be one of the following values:
* I2C1, I2C2, I2C3.
* @param mode
* this parameter can be one of the following values:
* - I2C_ADDRESS_MODE_7BIT: 7bit address.
* - I2C_ADDRESS_MODE_10BIT: 10bit address.
* @param address: own address1, such as 0xb0.
* @retval none
*/
void i2c_own_address1_set(i2c_type *i2c_x, i2c_address_mode_type mode, uint16_t address)
{
/* set address mode */
i2c_x->oaddr1_bit.addr1mode = mode;
/* set own address1 */
i2c_x->oaddr1_bit.addr1 = address;
}
/**
* @brief config own address2.
* @param i2c_x: to select the i2c peripheral.
* this parameter can be one of the following values:
* I2C1, I2C2, I2C3.
* @param address: specifies the 7bit i2c own address2, such as 0xa0.
* @retval none.
*/
void i2c_own_address2_set(i2c_type *i2c_x, uint8_t address)
{
i2c_x->oaddr2_bit.addr2 = (address >> 1);
}
/**
* @brief enable or disable own address2.
* @param i2c_x: to select the i2c peripheral.
* this parameter can be one of the following values:
* I2C1, I2C2, I2C3.
* @param new_state (TRUE or FALSE)
* @retval none
*/
void i2c_own_address2_enable(i2c_type *i2c_x, confirm_state new_state)
{
i2c_x->oaddr2_bit.addr2en = new_state;
}
/**
* @brief enable or disable the smbus mode
* @param i2c_x: to select the i2c peripheral.
* this parameter can be one of the following values:
* I2C1, I2C2, I2C3.
* @param new_state (TRUE or FALSE)
* @retval none
*/
void i2c_smbus_enable(i2c_type *i2c_x, confirm_state new_state)
{
i2c_x->ctrl1_bit.permode = new_state;
}
/**
* @brief enable or disable i2c periph
* @param i2c_x: to select the i2c peripheral.
* this parameter can be one of the following values:
* I2C1, I2C2, I2C3.
* @param new_state (TRUE or FALSE)
* @retval none
*/
void i2c_enable(i2c_type *i2c_x, confirm_state new_state)
{
i2c_x->ctrl1_bit.i2cen = new_state;
}
/**
* @brief config fast mode duty cycle
* @param i2c_x: to select the i2c peripheral.
* this parameter can be one of the following values:
* I2C1, I2C2, I2C3.
* @param duty
* this parameter can be one of the following values:
* - I2C_FSMODE_DUTY_2_1: duty cycle 2:1
* - I2C_FSMODE_DUTY_16_9: duty cycle 16:9
* @retval none
*/
void i2c_fast_mode_duty_set(i2c_type *i2c_x, i2c_fsmode_duty_cycle_type duty)
{
i2c_x->clkctrl_bit.dutymode = duty;
}
/**
* @brief enable or disable clock stretch.
* @param i2c_x: to select the i2c peripheral.
* this parameter can be one of the following values:
* I2C1, I2C2, I2C3.
* @param new_state (TRUE or FALSE)
* @retval none
*/
void i2c_clock_stretch_enable(i2c_type *i2c_x, confirm_state new_state)
{
i2c_x->ctrl1_bit.stretch = !new_state;
}
/**
* @brief enable or disable acknowledge.
* @param i2c_x: to select the i2c peripheral.
* this parameter can be one of the following values:
* I2C1, I2C2, I2C3.
* @param new_state (TRUE or FALSE)
* @retval none.
*/
void i2c_ack_enable(i2c_type *i2c_x, confirm_state new_state)
{
i2c_x->ctrl1_bit.acken = new_state;
}
/**
* @brief master receiving mode acknowledge control.
* @param i2c_x: to select the i2c peripheral.
* this parameter can be one of the following values:
* I2C1, I2C2, I2C3.
* @param pos
* this parameter can be one of the following values:
* - I2C_MASTER_ACK_CURRENT: acken bit acts on the current byte
* - I2C_MASTER_ACK_NEXT: acken bit acts on the next byte
* @retval none
*/
void i2c_master_receive_ack_set(i2c_type *i2c_x, i2c_master_ack_type pos)
{
i2c_x->ctrl1_bit.mackctrl = pos;
}
/**
* @brief pec position set.
* @param i2c_x: to select the i2c peripheral.
* this parameter can be one of the following values:
* I2C1, I2C2, I2C3.
* @param pos
* this parameter can be one of the following values:
* - I2C_PEC_POSITION_CURRENT: the current byte is pec
* - I2C_PEC_POSITION_NEXT: the next byte is pec
* @retval none
*/
void i2c_pec_position_set(i2c_type *i2c_x, i2c_pec_position_type pos)
{
i2c_x->ctrl1_bit.mackctrl = pos;
}
/**
* @brief enable or disable general call.
* @param i2c_x: to select the i2c peripheral.
* this parameter can be one of the following values:
* I2C1, I2C2, I2C3.
* @param new_state (TRUE or FALSE)
* @retval none
*/
void i2c_general_call_enable(i2c_type *i2c_x, confirm_state new_state)
{
i2c_x->ctrl1_bit.gcaen = new_state;
}
/**
* @brief enable or disable arp mode.
* @param i2c_x: to select the i2c peripheral.
* this parameter can be one of the following values:
* I2C1, I2C2, I2C3.
* @param new_state (TRUE or FALSE)
* @retval none
*/
void i2c_arp_mode_enable(i2c_type *i2c_x, confirm_state new_state)
{
i2c_x->ctrl1_bit.arpen = new_state;
}
/**
* @brief config smbus host or device.
* @param i2c_x: to select the i2c peripheral.
* this parameter can be one of the following values:
* I2C1, I2C2, I2C3.
* @param level
* this parameter can be one of the following values:
* - I2C_SMBUS_MODE_DEVICE: smbus device.
* - I2C_SMBUS_MODE_HOST: smbus host.
* @retval none
*/
void i2c_smbus_mode_set(i2c_type *i2c_x, i2c_smbus_mode_set_type mode)
{
i2c_x->ctrl1_bit.smbmode = mode;
}
/**
* @brief drive the smbus alert pin high or low.
* @param i2c_x: to select the i2c peripheral.
* this parameter can be one of the following values:
* I2C1, I2C2, I2C3.
* @param level
* this parameter can be one of the following values:
* - I2C_SMBUS_ALERT_LOW: smbus alert pin set low.
* - I2C_SMBUS_ALERT_HIGH: smbus alert pin set high.
* @retval none
*/
void i2c_smbus_alert_set(i2c_type *i2c_x, i2c_smbus_alert_set_type level)
{
i2c_x->ctrl1_bit.smbalert = level;
}
/**
* @brief enable or disable pec transfer.
* @param i2c_x: to select the i2c peripheral.
* this parameter can be one of the following values:
* I2C1, I2C2, I2C3.
* @param new_state (TRUE or FALSE)
* @retval none
*/
void i2c_pec_transmit_enable(i2c_type *i2c_x, confirm_state new_state)
{
i2c_x->ctrl1_bit.pecten = new_state;
}
/**
* @brief enable or disable pec calcultetion.
* @param i2c_x: to select the i2c peripheral.
* this parameter can be one of the following values:
* I2C1, I2C2, I2C3.
* @param new_state (TRUE or FALSE)
* @retval none
*/
void i2c_pec_calculate_enable(i2c_type *i2c_x, confirm_state new_state)
{
i2c_x->ctrl1_bit.pecen = new_state;
}
/**
* @brief get pec value.
* @param i2c_x: to select the i2c peripheral.
* this parameter can be one of the following values:
* I2C1, I2C2, I2C3.
* @retval uint8_t: pec value.
*/
uint8_t i2c_pec_value_get(i2c_type *i2c_x)
{
return i2c_x->sts2_bit.pecval;
}
/**
* @brief enable or disable if the next dma transfer will be the last one.
* @param i2c_x: to select the i2c peripheral.
* this parameter can be one of the following values:
* I2C1, I2C2, I2C3.
* @param new_state (TRUE or FALSE)
* @retval none
*/
void i2c_dma_end_transfer_set(i2c_type *i2c_x, confirm_state new_state)
{
i2c_x->ctrl2_bit.dmaend = new_state;
}
/**
* @brief enable or disable dma requests.
* @param i2c_x: to select the i2c peripheral.
* this parameter can be one of the following values:
* I2C1, I2C2, I2C3.
* @param new_state (TRUE or FALSE)
* @retval none
*/
void i2c_dma_enable(i2c_type *i2c_x, confirm_state new_state)
{
i2c_x->ctrl2_bit.dmaen = new_state;
}
/**
* @brief enable or disable interrupt
* @param i2c_x: to select the i2c peripheral.
* this parameter can be one of the following values:
* I2C1, I2C2, I2C3.
* @param source
* this parameter can be one of the following values:
* - I2C_DATA_INT: data interrupt.
* - I2C_EV_INT: event interrupt.
* - I2C_ERR_INT: error interrupt.
* @param new_state (TRUE or FALSE)
* @retval none
*/
void i2c_interrupt_enable(i2c_type *i2c_x, uint16_t source, confirm_state new_state)
{
if (new_state != FALSE)
{
i2c_x->ctrl2 |= source;
}
else
{
i2c_x->ctrl2 &= (uint16_t)~source;
}
}
/**
* @brief generate start condition.
* @param i2c_x: to select the i2c peripheral.
* this parameter can be one of the following values:
* I2C1, I2C2, I2C3.
* @retval none.
*/
void i2c_start_generate(i2c_type *i2c_x)
{
i2c_x->ctrl1_bit.genstart = TRUE;
}
/**
* @brief generate stop condition.
* @param i2c_x: to select the i2c peripheral.
* this parameter can be one of the following values:
* I2C1, I2C2, I2C3.
* @retval none.
*/
void i2c_stop_generate(i2c_type *i2c_x)
{
i2c_x->ctrl1_bit.genstop = TRUE;
}
/**
* @brief transmit the slave address.
* @param i2c_x: to select the i2c peripheral.
* this parameter can be one of the following values:
* I2C1, I2C2, I2C3.
* @param address: specifies the slave address which will be transmitted
* @param direction
* this parameter can be one of the following values:
* - I2C_DIRECTION_TRANSMIT: transmit mode.
* - I2C_DIRECTION_RECEIVE: receive mode.
* @retval none.
*/
void i2c_7bit_address_send(i2c_type *i2c_x, uint8_t address, i2c_direction_type direction)
{
if(direction == I2C_DIRECTION_TRANSMIT)
{
i2c_x->dt = address & 0xFE;
}
else
{
i2c_x->dt = address | 0x01;
}
}
/**
* @brief send a byte through the i2c periph.
* @param i2c_x: to select the i2c peripheral.
* this parameter can be one of the following values:
* I2C1, I2C2, I2C3.
* @param data: byte to be transmitted.
* @retval none
*/
void i2c_data_send(i2c_type *i2c_x, uint8_t data)
{
i2c_x->dt = data;
}
/**
* @brief receive a byte through the i2c periph.
* @param i2c_x: to select the i2c peripheral.
* this parameter can be one of the following values:
* I2C1, I2C2, I2C3.
* @retval uint8_t: received byte
*/
uint8_t i2c_data_receive(i2c_type *i2c_x)
{
return (uint8_t)i2c_x->dt;
}
/**
* @brief get flag status
* @param i2c_x: to select the i2c peripheral.
* this parameter can be one of the following values:
* I2C1, I2C2, I2C3.
* @param flag
* this parameter can be one of the following values:
* - I2C_STARTF_FLAG: start condition generation complete flag.
* - I2C_ADDR7F_FLAG: 0~7 bit address match flag.
* - I2C_TDC_FLAG: transmit data complete flag.
* - I2C_ADDRHF_FLAG: master 9~8 bit address header match flag.
* - I2C_STOPF_FLAG: stop condition generation complete flag.
* - I2C_RDBF_FLAG: receive data buffer full flag.
* - I2C_TDBE_FLAG: transmit data buffer empty flag.
* - I2C_BUSERR_FLAG: bus error flag.
* - I2C_ARLOST_FLAG: arbitration lost flag.
* - I2C_ACKFAIL_FLAG: acknowledge failure flag.
* - I2C_OUF_FLAG: overflow or underflow flag.
* - I2C_PECERR_FLAG: pec receive error flag.
* - I2C_TMOUT_FLAG: smbus timeout flag.
* - I2C_ALERTF_FLAG: smbus alert flag.
* - I2C_TRMODE_FLAG: transmission mode.
* - I2C_BUSYF_FLAG: bus busy flag transmission mode.
* - I2C_DIRF_FLAG: transmission direction flag.
* - I2C_GCADDRF_FLAG: general call address received flag.
* - I2C_DEVADDRF_FLAG: smbus device address received flag.
* - I2C_HOSTADDRF_FLAG: smbus host address received flag.
* - I2C_ADDR2_FLAG: own address 2 received flag.
* @retval flag_status (SET or RESET)
*/
flag_status i2c_flag_get(i2c_type *i2c_x, uint32_t flag)
{
__IO uint32_t reg = 0, value = 0;
reg = flag >> 28;
flag &= (uint32_t)0x00FFFFFF;
if(reg == 0)
{
value = i2c_x->sts1;
}
else
{
flag = (uint32_t)(flag >> 16);
value = i2c_x->sts2;
}
if((value & flag) != (uint32_t)RESET)
{
return SET;
}
else
{
return RESET;
}
}
/**
* @brief get interrupt flag status
* @param i2c_x: to select the i2c peripheral.
* this parameter can be one of the following values:
* I2C1, I2C2, I2C3.
* @param flag
* this parameter can be one of the following values:
* - I2C_STARTF_FLAG: start condition generation complete flag.
* - I2C_ADDR7F_FLAG: 0~7 bit address match flag.
* - I2C_TDC_FLAG: transmit data complete flag.
* - I2C_ADDRHF_FLAG: master 9~8 bit address header match flag.
* - I2C_STOPF_FLAG: stop condition generation complete flag.
* - I2C_RDBF_FLAG: receive data buffer full flag.
* - I2C_TDBE_FLAG: transmit data buffer empty flag.
* - I2C_BUSERR_FLAG: bus error flag.
* - I2C_ARLOST_FLAG: arbitration lost flag.
* - I2C_ACKFAIL_FLAG: acknowledge failure flag.
* - I2C_OUF_FLAG: overflow or underflow flag.
* - I2C_PECERR_FLAG: pec receive error flag.
* - I2C_TMOUT_FLAG: smbus timeout flag.
* - I2C_ALERTF_FLAG: smbus alert flag.
* @retval flag_status (SET or RESET)
*/
flag_status i2c_interrupt_flag_get(i2c_type *i2c_x, uint32_t flag)
{
__IO uint32_t reg = 0, value = 0, iten = 0;
switch(flag)
{
case I2C_STARTF_FLAG:
case I2C_ADDR7F_FLAG:
case I2C_TDC_FLAG:
case I2C_ADDRHF_FLAG:
case I2C_STOPF_FLAG:
iten = i2c_x->ctrl2_bit.evtien;
break;
case I2C_RDBF_FLAG:
case I2C_TDBE_FLAG:
iten = i2c_x->ctrl2_bit.dataien && i2c_x->ctrl2_bit.evtien;
break;
case I2C_BUSERR_FLAG:
case I2C_ARLOST_FLAG:
case I2C_ACKFAIL_FLAG:
case I2C_OUF_FLAG:
case I2C_PECERR_FLAG:
case I2C_TMOUT_FLAG:
case I2C_ALERTF_FLAG:
iten = i2c_x->ctrl2_bit.errien;
break;
default:
break;
}
reg = flag >> 28;
flag &= (uint32_t)0x00FFFFFF;
if(reg == 0)
{
value = i2c_x->sts1;
}
else
{
flag = (uint32_t)(flag >> 16);
value = i2c_x->sts2;
}
if(((value & flag) != (uint32_t)RESET) && (iten))
{
return SET;
}
else
{
return RESET;
}
}
/**
* @brief clear flag status
* @param i2c_x: to select the i2c peripheral.
* this parameter can be one of the following values:
* I2C1, I2C2, I2C3.
* @param flag
* this parameter can be any combination of the following values:
* - I2C_BUSERR_FLAG: bus error flag.
* - I2C_ARLOST_FLAG: arbitration lost flag.
* - I2C_ACKFAIL_FLAG: acknowledge failure flag.
* - I2C_OUF_FLAG: overflow or underflow flag.
* - I2C_PECERR_FLAG: pec receive error flag.
* - I2C_TMOUT_FLAG: smbus timeout flag.
* - I2C_ALERTF_FLAG: smbus alert flag.
* - I2C_STOPF_FLAG: stop condition generation complete flag.
* - I2C_ADDR7F_FLAG: i2c 0~7 bit address match flag.
* @retval none
*/
void i2c_flag_clear(i2c_type *i2c_x, uint32_t flag)
{
i2c_x->sts1 = (uint16_t)~(flag & (uint32_t)0x0000DF00);
if(i2c_x->sts1 & I2C_ADDR7F_FLAG)
{
UNUSED(i2c_x->sts2);
}
if(i2c_x->sts1 & I2C_STOPF_FLAG)
{
i2c_x->ctrl1_bit.i2cen = TRUE;
}
}
/**
* @}
*/
#endif
/**
* @}
*/
/**
* @}
*/

View File

@@ -0,0 +1,171 @@
/**
**************************************************************************
* @file at32f403a_407_misc.c
* @brief contains all the functions for the misc firmware library
**************************************************************************
* Copyright notice & Disclaimer
*
* The software Board Support Package (BSP) that is made available to
* download from Artery official website is the copyrighted work of Artery.
* Artery authorizes customers to use, copy, and distribute the BSP
* software and its related documentation for the purpose of design and
* development in conjunction with Artery microcontrollers. Use of the
* software is governed by this copyright notice and the following disclaimer.
*
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
*
**************************************************************************
*/
/* includes ------------------------------------------------------------------*/
#include "at32f403a_407_conf.h"
/** @addtogroup AT32F403A_407_periph_driver
* @{
*/
/** @defgroup MISC
* @brief MISC driver modules
* @{
*/
#ifdef MISC_MODULE_ENABLED
/** @defgroup MISC_private_functions
* @{
*/
#define AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000)
/**
* @brief system reset
* @param none
* @retval none
*/
void nvic_system_reset(void)
{
NVIC_SystemReset();
}
/**
* @brief enable nvic irq
* @param irqn (IRQn_Type number)
* @param preempt_priority: preemptive priority value (starting from 0)
* @param sub_priority: subpriority value (starting from 0)
* @retval none
*/
void nvic_irq_enable(IRQn_Type irqn, uint32_t preempt_priority, uint32_t sub_priority)
{
uint32_t temp_priority = 0;
/* encode priority */
temp_priority = NVIC_EncodePriority(NVIC_GetPriorityGrouping(), preempt_priority, sub_priority);
/* set priority */
NVIC_SetPriority(irqn, temp_priority);
/* enable irqn */
NVIC_EnableIRQ(irqn);
}
/**
* @brief disable nvic irq number
* @param irqn (IRQn_Type number)
* @retval none
*/
void nvic_irq_disable(IRQn_Type irqn)
{
NVIC_DisableIRQ(irqn);
}
/**
* @brief config nvic priority group
* @param priority_group
* this parameter can be one of the following values:
* - NVIC_PRIORITY_GROUP_0
* - NVIC_PRIORITY_GROUP_1
* - NVIC_PRIORITY_GROUP_2
* - NVIC_PRIORITY_GROUP_3
* - NVIC_PRIORITY_GROUP_4
* @retval none
*/
void nvic_priority_group_config(nvic_priority_group_type priority_group)
{
/* set the prigroup[10:8] bits according to nvic_prioritygroup value */
NVIC_SetPriorityGrouping(priority_group);
}
/**
* @brief set the vector table location and offset.
* @param base
* this parameter can be one of the following values:
* - NVIC_VECTTAB_RAM
* - NVIC_VECTTAB_FLASH
* @param offset (vector table base offset field. this value must be a multiple of 0x200)
* @retval none
*/
void nvic_vector_table_set(uint32_t base, uint32_t offset)
{
SCB->VTOR = base | (offset & (uint32_t)0x1FFFFF80);
}
/**
* @brief config nvic lowpower mode
* @param lp_mode
* this parameter can be one of the following values:
* - NVIC_LP_SEVONPEND
* - NVIC_LP_SLEEPDEEP
* - NVIC_LP_SLEEPONEXIT
* @param new_state (new state of lp condition. ENABLE or DISABLE)
* @retval none
*/
void nvic_lowpower_mode_config(nvic_lowpower_mode_type lp_mode, confirm_state new_state)
{
if(new_state != FALSE)
{
SCB->SCR |= lp_mode;
}
else
{
SCB->SCR &= (uint32_t)(~(uint32_t)lp_mode);
}
}
/**
* @brief config systick clock source
* @param source
* this parameter can be one of the following values:
* - SYSTICK_CLOCK_SOURCE_AHBCLK_DIV8
* - SYSTICK_CLOCK_SOURCE_AHBCLK_NODIV
* @retval none
*/
void systick_clock_source_config(systick_clock_source_type source)
{
if(source == SYSTICK_CLOCK_SOURCE_AHBCLK_NODIV)
{
SysTick->CTRL |= SYSTICK_CLOCK_SOURCE_AHBCLK_NODIV;
}
else
{
SysTick->CTRL &= ~(uint32_t)SYSTICK_CLOCK_SOURCE_AHBCLK_NODIV;
}
}
/**
* @}
*/
#endif
/**
* @}
*/
/**
* @}
*/

View File

@@ -0,0 +1,247 @@
/**
**************************************************************************
* @file at32f403a_407_pwc.c
* @brief contains all the functions for the pwc firmware library
**************************************************************************
* Copyright notice & Disclaimer
*
* The software Board Support Package (BSP) that is made available to
* download from Artery official website is the copyrighted work of Artery.
* Artery authorizes customers to use, copy, and distribute the BSP
* software and its related documentation for the purpose of design and
* development in conjunction with Artery microcontrollers. Use of the
* software is governed by this copyright notice and the following disclaimer.
*
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
*
**************************************************************************
*/
#include "at32f403a_407_conf.h"
/** @addtogroup AT32F403A_407_periph_driver
* @{
*/
/** @defgroup PWC
* @brief PWC driver modules
* @{
*/
#ifdef PWC_MODULE_ENABLED
/** @defgroup PWC_private_functions
* @{
*/
/**
* @brief deinitialize the pwc peripheral registers to their default reset values.
* @param none
* @retval none
*/
void pwc_reset(void)
{
crm_periph_reset(CRM_PWC_PERIPH_RESET, TRUE);
crm_periph_reset(CRM_PWC_PERIPH_RESET, FALSE);
}
/**
* @brief enable or disable access to the battery powered domain.
* @param new_state: new state of battery powered domain access.
* this parameter can be: TRUE or FALSE.
* @retval none
*/
void pwc_battery_powered_domain_access(confirm_state new_state)
{
PWC->ctrl_bit.bpwen = new_state;
}
/**
* @brief select the voltage threshold detected by the power voltage detector.
* @param pvm_voltage: select pwc pvm voltage
* this parameter can be one of the following values:
* - PWC_PVM_VOLTAGE_2V3
* - PWC_PVM_VOLTAGE_2V4
* - PWC_PVM_VOLTAGE_2V5
* - PWC_PVM_VOLTAGE_2V6
* - PWC_PVM_VOLTAGE_2V7
* - PWC_PVM_VOLTAGE_2V8
* - PWC_PVM_VOLTAGE_2V9
* @retval none
*/
void pwc_pvm_level_select(pwc_pvm_voltage_type pvm_voltage)
{
PWC->ctrl_bit.pvmsel = pvm_voltage;
}
/**
* @brief enable or disable pwc power voltage monitor (pvm)
* @param new_state: new state of pvm.
* this parameter can be: TRUE or FALSE.
* @retval none
*/
void pwc_power_voltage_monitor_enable(confirm_state new_state)
{
PWC->ctrl_bit.pvmen = new_state;
}
/**
* @brief enable or disable pwc standby wakeup pin
* @param pin_num: choose the wakeup pin.
* this parameter can be be any combination of the following values:
* - PWC_WAKEUP_PIN_1
* @param new_state: new state of the standby wakeup pin.
* this parameter can be one of the following values:
* - TRUE <wakeup pin is used for wake up cpu from standby mode>
* - FALSE <wakeup pin is used for general purpose I/O>
* @retval none
*/
void pwc_wakeup_pin_enable(uint32_t pin_num, confirm_state new_state)
{
if(new_state == TRUE)
{
PWC->ctrlsts |= pin_num;
}
else
{
PWC->ctrlsts &= ~pin_num;
}
}
/**
* @brief clear flag of pwc
* @param pwc_flag: select the pwc flag.
* this parameter can be any combination of the following values:
* - PWC_WAKEUP_FLAG
* - PWC_STANDBY_FLAG
* - note:"PWC_PVM_OUTPUT_FLAG" cannot be choose!this bit is readonly bit,it means the voltage monitoring output state
* @retval none
*/
void pwc_flag_clear(uint32_t pwc_flag)
{
if(pwc_flag & PWC_STANDBY_FLAG)
PWC->ctrl_bit.clsef = TRUE;
if(pwc_flag & PWC_WAKEUP_FLAG)
PWC->ctrl_bit.clswef = TRUE;
}
/**
* @brief get flag of pwc
* @param pwc_flag: select the pwc flag.
* this parameter can be one of the following values:
* - PWC_WAKEUP_FLAG
* - PWC_STANDBY_FLAG
* - PWC_PVM_OUTPUT_FLAG
* @retval state of select flag(SET or RESET).
*/
flag_status pwc_flag_get(uint32_t pwc_flag)
{
flag_status status = RESET;
if ((PWC->ctrlsts & pwc_flag) == RESET)
{
status = RESET;
}
else
{
status = SET;
}
return status;
}
/**
* @brief enter pwc sleep mode
* @param sleep_mode_enter: choose the instruction to enter sleep mode.
* this parameter can be one of the following values:
* - PWC_SLEEP_ENTER_WFI
* - PWC_SLEEP_ENTER_WFE
* @retval none
*/
void pwc_sleep_mode_enter(pwc_sleep_enter_type pwc_sleep_enter)
{
SCB->SCR &= (uint32_t)~0x4;
if(pwc_sleep_enter == PWC_SLEEP_ENTER_WFE)
{
__SEV();
__WFE();
__WFE();
}
else if(pwc_sleep_enter == PWC_SLEEP_ENTER_WFI)
{
__WFI();
}
}
/**
* @brief enter pwc deep-sleep mode
* @param pwc_deep_sleep_enter: choose the instruction to enter deep sleep mode.
* this parameter can be one of the following values:
* - PWC_DEEP_SLEEP_ENTER_WFI
* - PWC_DEEP_SLEEP_ENTER_WFE
* @retval none
*/
void pwc_deep_sleep_mode_enter(pwc_deep_sleep_enter_type pwc_deep_sleep_enter)
{
SCB->SCR |= 0x04;
if(pwc_deep_sleep_enter == PWC_DEEP_SLEEP_ENTER_WFE)
{
__SEV();
__WFE();
__WFE();
}
else if(pwc_deep_sleep_enter == PWC_DEEP_SLEEP_ENTER_WFI)
{
__WFI();
}
SCB->SCR &= (uint32_t)~0x4;
}
/**
* @brief regulate low power consumption in the deep sleep mode
* @param pwc_regulator: set the regulator state.
* this parameter can be one of the following values:
* - PWC_REGULATOR_ON
* - PWC_REGULATOR_LOW_POWER
* @retval none
*/
void pwc_voltage_regulate_set(pwc_regulator_type pwc_regulator)
{
PWC->ctrl_bit.vrsel = pwc_regulator;
}
/**
* @brief enter pwc standby mode
* @param none
* @retval none
*/
void pwc_standby_mode_enter(void)
{
PWC->ctrl_bit.clswef = TRUE;
PWC->ctrl_bit.lpsel = TRUE;
SCB->SCR |= 0x04;
#if defined (__CC_ARM)
__force_stores();
#endif
while(1)
{
__WFI();
}
}
/**
* @}
*/
#endif
/**
* @}
*/
/**
* @}
*/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,719 @@
/**
**************************************************************************
* @file at32f403a_407_usart.c
* @brief contains all the functions for the usart firmware library
**************************************************************************
* Copyright notice & Disclaimer
*
* The software Board Support Package (BSP) that is made available to
* download from Artery official website is the copyrighted work of Artery.
* Artery authorizes customers to use, copy, and distribute the BSP
* software and its related documentation for the purpose of design and
* development in conjunction with Artery microcontrollers. Use of the
* software is governed by this copyright notice and the following disclaimer.
*
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
*
**************************************************************************
*/
/* includes ------------------------------------------------------------------*/
#include "at32f403a_407_conf.h"
/** @addtogroup AT32F403A_407_periph_driver
* @{
*/
/** @defgroup USART
* @brief USART driver modules
* @{
*/
#ifdef USART_MODULE_ENABLED
/** @defgroup USART_private_functions
* @{
*/
/**
* @brief deinitialize the usart peripheral registers to their default reset values.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2, USART3, UART4, UART5, USART6, UART7,or UART8.
* @retval none
*/
void usart_reset(usart_type* usart_x)
{
if(usart_x == USART1)
{
crm_periph_reset(CRM_USART1_PERIPH_RESET, TRUE);
crm_periph_reset(CRM_USART1_PERIPH_RESET, FALSE);
}
else if(usart_x == USART2)
{
crm_periph_reset(CRM_USART2_PERIPH_RESET, TRUE);
crm_periph_reset(CRM_USART2_PERIPH_RESET, FALSE);
}
else if(usart_x == USART3)
{
crm_periph_reset(CRM_USART3_PERIPH_RESET, TRUE);
crm_periph_reset(CRM_USART3_PERIPH_RESET, FALSE);
}
else if(usart_x == UART4)
{
crm_periph_reset(CRM_UART4_PERIPH_RESET, TRUE);
crm_periph_reset(CRM_UART4_PERIPH_RESET, FALSE);
}
else if(usart_x == UART5)
{
crm_periph_reset(CRM_UART5_PERIPH_RESET, TRUE);
crm_periph_reset(CRM_UART5_PERIPH_RESET, FALSE);
}
else if(usart_x == USART6)
{
crm_periph_reset(CRM_USART6_PERIPH_RESET, TRUE);
crm_periph_reset(CRM_USART6_PERIPH_RESET, FALSE);
}
else if(usart_x == UART7)
{
crm_periph_reset(CRM_UART7_PERIPH_RESET, TRUE);
crm_periph_reset(CRM_UART7_PERIPH_RESET, FALSE);
}
#if defined (AT32F403ARx) || defined (AT32F403AVx) || defined (AT32F407Rx) || \
defined (AT32F407Vx)
else if(usart_x == UART8)
{
crm_periph_reset(CRM_UART8_PERIPH_RESET, TRUE);
crm_periph_reset(CRM_UART8_PERIPH_RESET, FALSE);
}
#endif
}
/**
* @brief initialize the usart peripheral according to the specified parameters.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2, USART3, UART4 ,UART5, USART6, UART7 or UART8.
* @param baud_rate: configure the usart communication baud rate.
* @param data_bit: data bits transmitted or received in a frame
* this parameter can be one of the following values:
* - USART_DATA_8BITS
* - USART_DATA_9BITS.
* note
* - when parity check is disabled, the data bit width is the actual data bit number.
* - when parity check is enabled, the data bit width is the actual data bit number minus 1, and the MSB bit is replaced with the parity bit.
* @param stop_bit: stop bits transmitted
* this parameter can be one of the following values:
* - USART_STOP_1_BIT
* - USART_STOP_0_5_BIT.
* - USART_STOP_2_BIT
* - USART_STOP_1_5_BIT.
* @retval none
*/
void usart_init(usart_type* usart_x, uint32_t baud_rate, usart_data_bit_num_type data_bit, usart_stop_bit_num_type stop_bit)
{
crm_clocks_freq_type clocks_freq;
uint32_t apb_clock, temp_val;
crm_clocks_freq_get(&clocks_freq);
if((usart_x == USART1) || (usart_x == USART6) || (usart_x == UART7)
#if defined (AT32F403ARx) || defined (AT32F403AVx) || defined (AT32F407Rx) || \
defined (AT32F407Vx)
|| (usart_x == UART8)
#endif
)
{
apb_clock = clocks_freq.apb2_freq;
}
else
{
apb_clock = clocks_freq.apb1_freq;
}
temp_val = (apb_clock * 10 / baud_rate);
if((temp_val % 10) < 5)
{
temp_val = (temp_val / 10);
}
else
{
temp_val = (temp_val / 10) + 1;
}
usart_x->baudr_bit.div = temp_val;
usart_x->ctrl1_bit.dbn = data_bit;
usart_x->ctrl2_bit.stopbn = stop_bit;
}
/**
* @brief usart parity selection config.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2, USART3, UART4 ,UART5, USART6, UART7 or UART8.
* @param parity: select the none, odd or even parity.
* this parameter can be one of the following values:
* - USART_PARITY_NONE
* - USART_PARITY_EVEN.
* - USART_PARITY_ODD
* @retval none
*/
void usart_parity_selection_config(usart_type* usart_x, usart_parity_selection_type parity)
{
if(parity == USART_PARITY_NONE)
{
usart_x->ctrl1_bit.psel = FALSE;
usart_x->ctrl1_bit.pen = FALSE;
}
else if(parity == USART_PARITY_EVEN)
{
usart_x->ctrl1_bit.psel = FALSE;
usart_x->ctrl1_bit.pen = TRUE;
}
else if(parity == USART_PARITY_ODD)
{
usart_x->ctrl1_bit.psel = TRUE;
usart_x->ctrl1_bit.pen = TRUE;
}
}
/**
* @brief enable or disable the specified usart peripheral.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8.
* @param new_state: new state of the usart peripheral.
* this parameter can be: TRUE or FALSE.
* @retval none
*/
void usart_enable(usart_type* usart_x, confirm_state new_state)
{
usart_x->ctrl1_bit.uen = new_state;
}
/**
* @brief usart transmitter enable.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2, USART3, UART4 ,UART5, USART6, UART7 or UART8.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void usart_transmitter_enable(usart_type* usart_x, confirm_state new_state)
{
usart_x->ctrl1_bit.ten = new_state;
}
/**
* @brief usart receiver enable.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2, USART3, UART4 ,UART5, USART6, UART7 or UART8.
* @param new_state: TRUE or FALSE.
* @retval none
*/
void usart_receiver_enable(usart_type* usart_x, confirm_state new_state)
{
usart_x->ctrl1_bit.ren = new_state;
}
/**
* @brief usart clock config.
* @note clock config are not available for UART4, UART5, UART7 and UART8.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2, USART3 or USART6.
* @param clk_pol: polarity of the clock output on the ck pin.
* this parameter can be one of the following values:
* - USART_CLOCK_POLARITY_LOW
* - USART_CLOCK_POLARITY_HIGH
* @param clk_pha: phase of the clock output on the ck pin.
* this parameter can be one of the following values:
* - USART_CLOCK_PHASE_1EDGE
* - USART_CLOCK_PHASE_2EDGE
* @param clk_lb: whether the clock pulse of the last data bit transmitted (MSB) is outputted on the ck pin.
* this parameter can be one of the following values:
* - USART_CLOCK_LAST_BIT_NONE
* - USART_CLOCK_LAST_BIT_OUTPUT
* @retval none
*/
void usart_clock_config(usart_type* usart_x, usart_clock_polarity_type clk_pol, usart_clock_phase_type clk_pha, usart_lbcp_type clk_lb)
{
usart_x->ctrl2_bit.clkpol = clk_pol;
usart_x->ctrl2_bit.clkpha = clk_pha;
usart_x->ctrl2_bit.lbcp = clk_lb;
}
/**
* @brief usart enable the ck pin.
* @note clock enable are not available for UART4, UART5, UART7 and UART8.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2, USART3 or USART6.
* @param new_state: TRUE or FALSE
* @retval none
*/
void usart_clock_enable(usart_type* usart_x, confirm_state new_state)
{
usart_x->ctrl2_bit.clken = new_state;
}
/**
* @brief enable or disable the specified usart interrupts.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8.
* @param usart_int: specifies the USART interrupt sources to be enabled or disabled.
* this parameter can be one of the following values:
* - USART_IDLE_INT: idle interrupt
* - USART_RDBF_INT: rdbf interrupt
* - USART_TDC_INT: tdc interrupt
* - USART_TDBE_INT: tdbe interrupt
* - USART_PERR_INT: perr interrupt
* - USART_BF_INT: break frame interrupt
* - USART_ERR_INT: err interrupt
* - USART_CTSCF_INT: ctscf interrupt
* @param new_state: new state of the specified usart interrupts.
* this parameter can be: TRUE or FALSE.
* @retval none
*/
void usart_interrupt_enable(usart_type* usart_x, uint32_t usart_int, confirm_state new_state)
{
if(new_state == TRUE)
PERIPH_REG((uint32_t)usart_x, usart_int) |= PERIPH_REG_BIT(usart_int);
else
PERIPH_REG((uint32_t)usart_x, usart_int) &= ~PERIPH_REG_BIT(usart_int);
}
/**
* @brief enable or disable the usart's dma transmitter interface.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8.
* @param new_state: new state of the dma request sources.
* this parameter can be: TRUE or FALSE.
* @retval none
*/
void usart_dma_transmitter_enable(usart_type* usart_x, confirm_state new_state)
{
usart_x->ctrl3_bit.dmaten = new_state;
}
/**
* @brief enable or disable the usart's dma receiver interface.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8.
* @param new_state: new state of the dma request sources.
* this parameter can be: TRUE or FALSE.
* @retval none
*/
void usart_dma_receiver_enable(usart_type* usart_x, confirm_state new_state)
{
usart_x->ctrl3_bit.dmaren = new_state;
}
/**
* @brief set the wakeup id of the usart.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8.
* @param usart_id: the matching id(0x0~0xF).
* @retval none
*/
void usart_wakeup_id_set(usart_type* usart_x, uint8_t usart_id)
{
usart_x->ctrl2_bit.id = usart_id;
}
/**
* @brief select the usart wakeup method in multi-processor communication.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8.
* @param wakeup_mode: determines the way to wake up usart method.
* this parameter can be one of the following values:
* - USART_WAKEUP_BY_IDLE_FRAME
* - USART_WAKEUP_BY_MATCHING_ID
* @retval none
*/
void usart_wakeup_mode_set(usart_type* usart_x, usart_wakeup_mode_type wakeup_mode)
{
usart_x->ctrl1_bit.wum = wakeup_mode;
}
/**
* @brief config the usart in mute mode in multi-processor communication.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8.
* @param new_state: new state of the usart mute mode.
* this parameter can be: TRUE or FALSE.
* @retval none
*/
void usart_receiver_mute_enable(usart_type* usart_x, confirm_state new_state)
{
usart_x->ctrl1_bit.rm = new_state;
}
/**
* @brief set the usart break frame bit num.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8.
* @param break_bit: specifies the break bit num.
* this parameter can be one of the following values:
* - USART_BREAK_10BITS
* - USART_BREAK_11BITS
* @retval none
*/
void usart_break_bit_num_set(usart_type* usart_x, usart_break_bit_num_type break_bit)
{
usart_x->ctrl2_bit.bfbn = break_bit;
}
/**
* @brief enable or disable the usart lin mode.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8.
* @param new_state: new state of the usart lin mode.
* this parameter can be: TRUE or FALSE.
* @retval none
*/
void usart_lin_mode_enable(usart_type* usart_x, confirm_state new_state)
{
usart_x->ctrl2_bit.linen = new_state;
}
/**
* @brief transmit single data through the usart peripheral.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8.
* @param data: the data to transmit.
* @retval none
*/
void usart_data_transmit(usart_type* usart_x, uint16_t data)
{
usart_x->dt = (data & 0x01FF);
}
/**
* @brief return the most recent received data by the usart peripheral.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8.
* @retval the received data.
*/
uint16_t usart_data_receive(usart_type* usart_x)
{
return (uint16_t)(usart_x->dt);
}
/**
* @brief transmit break characters.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8.
* @retval none
*/
void usart_break_send(usart_type* usart_x)
{
usart_x->ctrl1_bit.sbf = TRUE;
}
/**
* @brief config the specified usart smartcard guard time.
* @note The guard time bits are not available for UART4, UART5, UART7 or UART8.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2, USART3 or USART6.
* @param guard_time_val: specifies the guard time (0x00~0xFF).
* @retval none
*/
void usart_smartcard_guard_time_set(usart_type* usart_x, uint8_t guard_time_val)
{
usart_x->gdiv_bit.scgt = guard_time_val;
}
/**
* @brief config the irda/smartcard division.
* @note the division are not available for UART4, UART5, UART7 or UART8.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2, USART3 or USART6.
* @param div_val: specifies the division.
* @retval none
*/
void usart_irda_smartcard_division_set(usart_type* usart_x, uint8_t div_val)
{
usart_x->gdiv_bit.isdiv = div_val;
}
/**
* @brief enable or disable the usart smart card mode.
* @note the smart card mode are not available for UART4, UART5, UART7 or UART8.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2, USART3 or USART6.
* @param new_state: new state of the smart card mode.
* this parameter can be: TRUE or FALSE.
* @retval none
*/
void usart_smartcard_mode_enable(usart_type* usart_x, confirm_state new_state)
{
usart_x->ctrl3_bit.scmen = new_state;
}
/**
* @brief enable or disable nack transmission in smartcard mode.
* @note the smart card nack are not available for UART4, UART5, UART7 or UART8.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2, USART3 or USART6.
* @param new_state: new state of the nack transmission.
* this parameter can be: TRUE or FALSE.
* @retval none
*/
void usart_smartcard_nack_set(usart_type* usart_x, confirm_state new_state)
{
usart_x->ctrl3_bit.scnacken = new_state;
}
/**
* @brief enable or disable the usart single line bidirectional half-duplex communication.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8.
* @param new_state: new state of the single line half-duplex select.
* this parameter can be: TRUE or FALSE.
* @retval none
*/
void usart_single_line_halfduplex_select(usart_type* usart_x, confirm_state new_state)
{
usart_x->ctrl3_bit.slben = new_state;
}
/**
* @brief enable or disable the usart's irda interface.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8.
* @param new_state: new state of the irda mode.
* this parameter can be: TRUE or FALSE.
* @retval none
*/
void usart_irda_mode_enable(usart_type* usart_x, confirm_state new_state)
{
usart_x->ctrl3_bit.irdaen = new_state;
}
/**
* @brief configure the usart's irda low power.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8.
* @param new_state: new state of the irda mode.
* this parameter can be: TRUE or FALSE.
* @retval none
*/
void usart_irda_low_power_enable(usart_type* usart_x, confirm_state new_state)
{
usart_x->ctrl3_bit.irdalp = new_state;
}
/**
* @brief configure the usart's hardware flow control.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2, USART3
* @param flow_state: specifies the hardware flow control.
* this parameter can be one of the following values:
* - USART_HARDWARE_FLOW_NONE
* - USART_HARDWARE_FLOW_RTS,
* - USART_HARDWARE_FLOW_CTS,
* - USART_HARDWARE_FLOW_RTS_CTS
* @retval none
*/
void usart_hardware_flow_control_set(usart_type* usart_x,usart_hardware_flow_control_type flow_state)
{
if(flow_state == USART_HARDWARE_FLOW_NONE)
{
usart_x->ctrl3_bit.rtsen = FALSE;
usart_x->ctrl3_bit.ctsen = FALSE;
}
else if(flow_state == USART_HARDWARE_FLOW_RTS)
{
usart_x->ctrl3_bit.rtsen = TRUE;
usart_x->ctrl3_bit.ctsen = FALSE;
}
else if(flow_state == USART_HARDWARE_FLOW_CTS)
{
usart_x->ctrl3_bit.rtsen = FALSE;
usart_x->ctrl3_bit.ctsen = TRUE;
}
else if(flow_state == USART_HARDWARE_FLOW_RTS_CTS)
{
usart_x->ctrl3_bit.rtsen = TRUE;
usart_x->ctrl3_bit.ctsen = TRUE;
}
}
/**
* @brief check whether the specified usart flag is set or not.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8.
* @param flag: specifies the flag to check.
* this parameter can be one of the following values:
* - USART_CTSCF_FLAG: cts change flag (not available for UART4,UART5,USART6,UART7 and UART8)
* - USART_BFF_FLAG: break frame flag
* - USART_TDBE_FLAG: transmit data buffer empty flag
* - USART_TDC_FLAG: transmit data complete flag
* - USART_RDBF_FLAG: receive data buffer full flag
* - USART_IDLEF_FLAG: idle flag
* - USART_ROERR_FLAG: receiver overflow error flag
* - USART_NERR_FLAG: noise error flag
* - USART_FERR_FLAG: framing error flag
* - USART_PERR_FLAG: parity error flag
* @retval the new state of usart_flag (SET or RESET).
*/
flag_status usart_flag_get(usart_type* usart_x, uint32_t flag)
{
if(usart_x->sts & flag)
{
return SET;
}
else
{
return RESET;
}
}
/**
* @brief check whether the specified usart interrupt flag is set or not.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8.
* @param flag: specifies the flag to check.
* this parameter can be one of the following values:
* - USART_CTSCF_FLAG: cts change flag (not available for UART4,UART5)
* - USART_BFF_FLAG: break frame flag
* - USART_TDBE_FLAG: transmit data buffer empty flag
* - USART_TDC_FLAG: transmit data complete flag
* - USART_RDBF_FLAG: receive data buffer full flag
* - USART_IDLEF_FLAG: idle flag
* - USART_ROERR_FLAG: receiver overflow error flag
* - USART_NERR_FLAG: noise error flag
* - USART_FERR_FLAG: framing error flag
* - USART_PERR_FLAG: parity error flag
* @retval the new state of usart_flag (SET or RESET).
*/
flag_status usart_interrupt_flag_get(usart_type* usart_x, uint32_t flag)
{
flag_status int_status = RESET;
switch(flag)
{
case USART_CTSCF_FLAG:
int_status = (flag_status)usart_x->ctrl3_bit.ctscfien;
break;
case USART_BFF_FLAG:
int_status = (flag_status)usart_x->ctrl2_bit.bfien;
break;
case USART_TDBE_FLAG:
int_status = (flag_status)usart_x->ctrl1_bit.tdbeien;
break;
case USART_TDC_FLAG:
int_status = (flag_status)usart_x->ctrl1_bit.tdcien;
break;
case USART_RDBF_FLAG:
int_status = (flag_status)usart_x->ctrl1_bit.rdbfien;
break;
case USART_ROERR_FLAG:
int_status = (flag_status)(usart_x->ctrl1_bit.rdbfien || usart_x->ctrl3_bit.errien);
break;
case USART_IDLEF_FLAG:
int_status = (flag_status)usart_x->ctrl1_bit.idleien;
break;
case USART_NERR_FLAG:
case USART_FERR_FLAG:
int_status = (flag_status)usart_x->ctrl3_bit.errien;
break;
case USART_PERR_FLAG:
int_status = (flag_status)usart_x->ctrl1_bit.perrien;
break;
default:
int_status = RESET;
break;
}
if(int_status != SET)
{
return RESET;
}
if(usart_x->sts & flag)
{
return SET;
}
else
{
return RESET;
}
}
/**
* @brief clear the usart's pending flags.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2, USART3, UART4, UART5, USART6, UART7 or UART8.
* @param flag: specifies the flag to clear.
* this parameter can be any combination of the following values:
* - USART_CTSCF_FLAG: (not available for UART4,UART5,USART6,UART7 and UART8).
* - USART_BFF_FLAG:
* - USART_TDC_FLAG:
* - USART_RDBF_FLAG:
* - USART_PERR_FLAG:
* - USART_FERR_FLAG:
* - USART_NERR_FLAG:
* - USART_ROERR_FLAG:
* - USART_IDLEF_FLAG:
* @note
* - USART_PERR_FLAG, USART_FERR_FLAG, USART_NERR_FLAG, USART_ROERR_FLAG and USART_IDLEF_FLAG are cleared by software
* sequence: a read operation to usart sts register (usart_flag_get())
* followed by a read operation to usart dt register (usart_data_receive()).
* - USART_RDBF_FLAG can be also cleared by a read to the usart dt register(usart_data_receive()).
* - USART_TDC_FLAG can be also cleared by software sequence: a read operation to usart sts register (usart_flag_get())
* followed by a write operation to usart dt register (usart_data_transmit()).
* - USART_TDBE_FLAG is cleared only by a write to the usart dt register(usart_data_transmit()).
* @retval none
*/
void usart_flag_clear(usart_type* usart_x, uint32_t flag)
{
if(flag & (USART_PERR_FLAG | USART_FERR_FLAG | USART_NERR_FLAG | USART_ROERR_FLAG | USART_IDLEF_FLAG))
{
UNUSED(usart_x->sts);
UNUSED(usart_x->dt);
}
else
{
usart_x->sts = ~flag;
}
}
/**
* @}
*/
#endif
/**
* @}
*/
/**
* @}
*/