initial commit

This commit is contained in:
bmy
2024-04-25 22:31:01 +08:00
commit 200b5703f9
119 changed files with 52620 additions and 0 deletions

View File

@@ -0,0 +1,232 @@
/**
**************************************************************************
* @file at32f413_acc.c
* @brief contains all the functions for the acc 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 "at32f413_conf.h"
/** @addtogroup AT32F413_periph_driver
* @{
*/
/** @defgroup ACC
* @brief ACC driver modules
* @{
*/
#ifdef ACC_MODULE_ENABLED
/** @defgroup ACC_private_functions
* @{
*/
/**
* @brief enable or disable the acc calibration mode.
* @param acc_trim: specifies the acc calibration type.
* this parameter can be one of the following values:
* - ACC_CAL_HICKCAL
* - ACC_CAL_HICKTRIM
* @param new_state: specifies the acc calibration to be enabled or disabled.(TRUE or FALSE)
* @retval none
*/
void acc_calibration_mode_enable(uint16_t acc_trim, confirm_state new_state)
{
if(acc_trim == ACC_CAL_HICKCAL)
{
ACC->ctrl1_bit.entrim = FALSE;
}
else
{
ACC->ctrl1_bit.entrim = TRUE;
}
ACC->ctrl1_bit.calon = new_state;
}
/**
* @brief store calibration step data in acc's ctrl1 register.
* @param step_value: value to be stored in the acc's ctrl1 register
* @retval none
*/
void acc_step_set(uint8_t step_value)
{
ACC->ctrl1_bit.step = step_value;
}
/**
* @brief enable or disable the specified acc interrupts.
* @param acc_int: specifies the acc interrupt sources to be enabled or disabled.
* this parameter can be one of the following values:
* - ACC_CALRDYIEN_INT
* - ACC_EIEN_INT
* @param new_state (TRUE or FALSE)
* @retval none
*/
void acc_interrupt_enable(uint16_t acc_int, confirm_state new_state)
{
if(acc_int == ACC_CALRDYIEN_INT)
{
ACC->ctrl1_bit.calrdyien = new_state;
}
else
{
ACC->ctrl1_bit.eien = new_state;
}
}
/**
* @brief return the current acc hicktrim value.
* @param none
* @retval 8-bit hicktrim value.
*/
uint8_t acc_hicktrim_get(void)
{
return ((uint8_t)(ACC->ctrl2_bit.hicktrim));
}
/**
* @brief return the current acc hickcal value.
* @param none
* @retval 8-bit hicktrim value.
*/
uint8_t acc_hickcal_get(void)
{
return ((uint8_t)(ACC->ctrl2_bit.hickcal));
}
/**
* @brief wtire the value to acc c1 register.
* @param acc_c1_value
* @retval none.
*/
void acc_write_c1(uint16_t acc_c1_value)
{
ACC->c1 = acc_c1_value;
}
/**
* @brief wtire the value to acc c2 register.
* @param acc_c2_value
* @retval none.
*/
void acc_write_c2(uint16_t acc_c2_value)
{
ACC->c2 = acc_c2_value;
}
/**
* @brief wtire the value to acc c3 register.
* @param acc_c3_value
* @retval none.
*/
void acc_write_c3(uint16_t acc_c3_value)
{
ACC->c3 = acc_c3_value;
}
/**
* @brief return the current acc c1 value.
* @param none
* @retval 16-bit c1 value.
*/
uint16_t acc_read_c1(void)
{
return ((uint16_t)(ACC->c1));
}
/**
* @brief return the current acc c2 value.
* @param none
* @retval 16-bit c2 value.
*/
uint16_t acc_read_c2(void)
{
return ((uint16_t)(ACC->c2));
}
/**
* @brief return the current acc c3 value.
* @param none
* @retval 16-bit c3 value.
*/
uint16_t acc_read_c3(void)
{
return ((uint16_t)(ACC->c3));
}
/**
* @brief check whether the specified acc flag is set or not.
* @param acc_flag: specifies the flag to check.
* this parameter can be one of the following values:
* - ACC_RSLOST_FLAG
* - ACC_CALRDY_FLAG
* @retval flag_status (SET or RESET)
*/
flag_status acc_flag_get(uint16_t acc_flag)
{
if(acc_flag == ACC_CALRDY_FLAG)
return (flag_status)(ACC->sts_bit.calrdy);
else
return (flag_status)(ACC->sts_bit.rslost);
}
/**
* @brief check whether the specified acc interrupt flag is set or not.
* @param acc_flag: specifies the flag to check.
* this parameter can be one of the following values:
* - ACC_RSLOST_FLAG
* - ACC_CALRDY_FLAG
* @retval flag_status (SET or RESET)
*/
flag_status acc_interrupt_flag_get(uint16_t acc_flag)
{
if(acc_flag == ACC_CALRDY_FLAG)
return (flag_status)(ACC->sts_bit.calrdy && ACC->ctrl1_bit.calrdyien);
else
return (flag_status)(ACC->sts_bit.rslost && ACC->ctrl1_bit.eien);
}
/**
* @brief clear the specified acc flag is set or not.
* @param acc_flag: specifies the flag to check.
* this parameter can be any combination of the following values:
* - ACC_RSLOST_FLAG
* - ACC_CALRDY_FLAG
* @retval none
*/
void acc_flag_clear(uint16_t acc_flag)
{
ACC->sts = ~acc_flag;
}
/**
* @}
*/
#endif
/**
* @}
*/
/**
* @}
*/

View File

@@ -0,0 +1,857 @@
/**
**************************************************************************
* @file at32f413_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 "at32f413_conf.h"
/** @addtogroup AT32F413_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.
* @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);
}
}
/**
* @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.
* @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
* @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.
* @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.
* 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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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
* @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.
* @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
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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
/**
* @}
*/
/**
* @}
*/

View File

@@ -0,0 +1,222 @@
/**
**************************************************************************
* @file at32f413_bpr.c
* @brief contains all the functions for the bpr 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 "at32f413_conf.h"
/** @addtogroup AT32F413_periph_driver
* @{
*/
/** @defgroup BPR
* @brief BPR driver modules
* @{
*/
#ifdef BPR_MODULE_ENABLED
/** @defgroup BPR_private_functions
* @{
*/
/**
* @brief bpr reset by crm reset register
* @param none
* @retval none
*/
void bpr_reset(void)
{
crm_battery_powered_domain_reset(TRUE);
crm_battery_powered_domain_reset(FALSE);
}
/**
* @brief bpr event flag get, for tamper event flag
* @param flag: specifies the flag to check.
* this parameter can be one of the following values:
* - BPR_TAMPER_INTERRUPT_FLAG: tamper interrupt flag
* - BPR_TAMPER_EVENT_FLAG: tamper event flag
* @retval state of tamper event flag
*/
flag_status bpr_flag_get(uint32_t flag)
{
if(flag == BPR_TAMPER_INTERRUPT_FLAG)
{
return (flag_status)(BPR->ctrlsts_bit.tpif);
}
else
{
return (flag_status)(BPR->ctrlsts_bit.tpef);
}
}
/**
* @brief bpr interrupt flag get
* @param flag: specifies the flag to check.
* this parameter can be one of the following values:
* - BPR_TAMPER_INTERRUPT_FLAG: tamper interrupt flag
* - BPR_TAMPER_EVENT_FLAG: tamper event flag
* @retval state of tamper event flag
*/
flag_status bpr_interrupt_flag_get(uint32_t flag)
{
if(flag == BPR_TAMPER_INTERRUPT_FLAG)
{
return (flag_status)(BPR->ctrlsts_bit.tpif && BPR->ctrlsts_bit.tpien);
}
else
{
return (flag_status)(BPR->ctrlsts_bit.tpef && BPR->ctrlsts_bit.tpien);
}
}
/**
* @brief clear bpr tamper flag
* @param flag: specifies the flag to clear.
* this parameter can be one of the following values:
* - BPR_TAMPER_INTERRUPT_FLAG: tamper interrupt flag
* - BPR_TAMPER_EVENT_FLAG: tamper event flag
* @retval none
*/
void bpr_flag_clear(uint32_t flag)
{
if(flag == BPR_TAMPER_INTERRUPT_FLAG)
{
BPR->ctrlsts_bit.tpifclr = TRUE;
}
else
{
BPR->ctrlsts_bit.tpefclr = TRUE;
}
}
/**
* @brief enable or disable bpr tamper interrupt
* @param new_state (TRUE or FALSE)
* @retval none
*/
void bpr_interrupt_enable(confirm_state new_state)
{
BPR->ctrlsts_bit.tpien = new_state;
}
/**
* @brief read bpr bpr data
* @param bpr_data
* this parameter can be one of the following values:
* - BPR_DATA1
* - BPR_DATA2
* ...
* - BPR_DATA41
* - BPR_DATA42
* @retval none
*/
uint16_t bpr_data_read(bpr_data_type bpr_data)
{
return (*(__IO uint16_t *)(BPR_BASE + bpr_data));
}
/**
* @brief write bpr data
* @param bpr_data
* this parameter can be one of the following values:
* - BPR_DATA1
* - BPR_DATA2
* ...
* - BPR_DATA41
* - BPR_DATA42
* @param data_value (0x0000~0xFFFF)
* @retval none
*/
void bpr_data_write(bpr_data_type bpr_data, uint16_t data_value)
{
(*(__IO uint32_t *)(BPR_BASE + bpr_data)) = data_value;
}
/**
* @brief select bpr rtc output
* @param output_source
* this parameter can be one of the following values:
* - BPR_RTC_OUTPUT_NONE: output disable.
* - BPR_RTC_OUTPUT_CLOCK_CAL_BEFORE: output clock before calibration.
* - BPR_RTC_OUTPUT_ALARM: output alarm event with pluse mode.
* - BPR_RTC_OUTPUT_SECOND: output second event with pluse mode.
* - BPR_RTC_OUTPUT_CLOCK_CAL_AFTER: output clock after calibration.
* @retval none
*/
void bpr_rtc_output_select(bpr_rtc_output_type output_source)
{
/* clear cco,asoe,asos,ccos,togen bits */
BPR->rtccal &= (uint32_t)~0x0F80;
/* set output_source value */
BPR->rtccal |= output_source;
}
/**
* @brief set rtc clock calibration value
* @param calibration_value (0x00~0x7f)
* @retval none
*/
void bpr_rtc_clock_calibration_value_set(uint8_t calibration_value)
{
/* set rtc clock calibration value */
BPR->rtccal_bit.calval= calibration_value;
}
/**
* @brief enable or disable bpr tamper pin
* @param new_state (TRUE or FALSE)
* @retval none
*/
void bpr_tamper_pin_enable(confirm_state new_state)
{
BPR->ctrl_bit.tpen = new_state;
}
/**
* @brief set bpr tamper pin active level
* @param active_level
* this parameter can be one of the following values:
* - BPR_TAMPER_PIN_ACTIVE_HIGH: tamper pin input active level is high.
* - BPR_TAMPER_PIN_ACTIVE_LOW: tamper pin input active level is low.
* @retval none
*/
void bpr_tamper_pin_active_level_set(bpr_tamper_pin_active_level_type active_level)
{
BPR->ctrl_bit.tpp = active_level;
}
/**
* @}
*/
#endif
/**
* @}
*/
/**
* @}
*/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,208 @@
/**
**************************************************************************
* @file at32f413_crc.c
* @brief contains all the functions for the crc 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 "at32f413_conf.h"
/** @addtogroup AT32F413_periph_driver
* @{
*/
/** @defgroup CRC
* @brief CRC driver modules
* @{
*/
#ifdef CRC_MODULE_ENABLED
/** @defgroup CRC_private_functions
* @{
*/
/**
* @brief reset the crc data register.
* @param none
* @retval none
*/
void crc_data_reset(void)
{
/* reset crc generator */
CRC->ctrl_bit.rst = 0x1;
}
/**
* @brief compute the 32-bit crc of a given data word(32-bit).
* @param data: data word(32-bit) to compute its crc
* @retval 32-bit crc
*/
uint32_t crc_one_word_calculate(uint32_t data)
{
CRC->dt = data;
return (CRC->dt);
}
/**
* @brief compute the 32-bit crc of a given buffer of data word(32-bit).
* @param pbuffer: pointer to the buffer containing the data to be computed
* @param length: length of the buffer to be computed
* @retval 32-bit crc
*/
uint32_t crc_block_calculate(uint32_t *pbuffer, uint32_t length)
{
uint32_t index = 0;
for(index = 0; index < length; index++)
{
CRC->dt = pbuffer[index];
}
return (CRC->dt);
}
/**
* @brief return the current crc value.
* @param none
* @retval 32-bit crc
*/
uint32_t crc_data_get(void)
{
return (CRC->dt);
}
/**
* @brief store a 8-bit data in the common data register.
* @param cdt_value: 8-bit value to be stored in the common data register
* @retval none
*/
void crc_common_data_set(uint8_t cdt_value)
{
CRC->cdt_bit.cdt = cdt_value;
}
/**
* @brief return the 8-bit data stored in the common data register
* @param none
* @retval 8-bit value of the common data register
*/
uint8_t crc_common_data_get(void)
{
return (CRC->cdt_bit.cdt);
}
/**
* @brief set the 32-bit initial data of crc
* @param value: initial data
* @retval none
*/
void crc_init_data_set(uint32_t value)
{
CRC->idt = value;
}
/**
* @brief control the reversal of the bit order in the input data
* @param value
* this parameter can be one of the following values:
* - CRC_REVERSE_INPUT_NO_AFFECTE
* - CRC_REVERSE_INPUT_BY_BYTE
* - CRC_REVERSE_INPUT_BY_HALFWORD
* - CRC_REVERSE_INPUT_BY_WORD
* @retval none.
*/
void crc_reverse_input_data_set(crc_reverse_input_type value)
{
CRC->ctrl_bit.revid = value;
}
/**
* @brief control the reversal of the bit order in the output data
* @param value
* this parameter can be one of the following values:
* - CRC_REVERSE_OUTPUT_NO_AFFECTE
* - CRC_REVERSE_OUTPUT_DATA
* @retval none.
*/
void crc_reverse_output_data_set(crc_reverse_output_type value)
{
CRC->ctrl_bit.revod = value;
}
/**
* @brief config crc polynomial value
* @param value
* 32-bit new data of crc poly value
* @retval none.
*/
void crc_poly_value_set(uint32_t value)
{
CRC->poly = value;
}
/**
* @brief return crc polynomial value
* @param none
* @retval 32-bit value of the polynomial value.
*/
uint32_t crc_poly_value_get(void)
{
return (CRC->poly);
}
/**
* @brief config crc polynomial data size
* @param size
* this parameter can be one of the following values:
* - CRC_POLY_SIZE_32B
* - CRC_POLY_SIZE_16B
* - CRC_POLY_SIZE_8B
* - CRC_POLY_SIZE_7B
* @retval none.
*/
void crc_poly_size_set(crc_poly_size_type size)
{
CRC->ctrl_bit.poly_size = size;
}
/**
* @brief return crc polynomial data size
* @param none
* @retval polynomial data size.
*/
crc_poly_size_type crc_poly_size_get(void)
{
return (crc_poly_size_type)(CRC->ctrl_bit.poly_size);
}
/**
* @}
*/
#endif
/**
* @}
*/
/**
* @}
*/

View File

@@ -0,0 +1,881 @@
/**
**************************************************************************
* @file at32f413_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 "at32f413_conf.h"
/** @addtogroup AT32F413_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_SDIO1_PERIPH_CLOCK
* - CRM_IOMUX_PERIPH_CLOCK - CRM_GPIOA_PERIPH_CLOCK - CRM_GPIOB_PERIPH_CLOCK - CRM_GPIOC_PERIPH_CLOCK
* - CRM_GPIOD_PERIPH_CLOCK - CRM_GPIOF_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_TMR9_PERIPH_CLOCK - CRM_TMR10_PERIPH_CLOCK - CRM_TMR11_PERIPH_CLOCK - CRM_ACC_PERIPH_CLOCK
* - CRM_TMR3_PERIPH_CLOCK - CRM_TMR4_PERIPH_CLOCK - CRM_TMR5_PERIPH_CLOCK - CRM_WWDT_PERIPH_CLOCK
* - CRM_SPI2_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_BPR_PERIPH_CLOCK - CRM_PWC_PERIPH_CLOCK - CRM_CAN2_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_IOMUX_PERIPH_RESET - CRM_EXINT_PERIPH_RESET - CRM_GPIOA_PERIPH_RESET - CRM_GPIOB_PERIPH_RESET
* - CRM_GPIOC_PERIPH_RESET - CRM_GPIOD_PERIPH_RESET - CRM_GPIOF_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_TMR9_PERIPH_RESET - CRM_TMR10_PERIPH_RESET - CRM_TMR11_PERIPH_RESET
* - CRM_ACC_PERIPH_RESET - CRM_TMR2_PERIPH_RESET - CRM_TMR3_PERIPH_RESET - CRM_TMR4_PERIPH_RESET
* - CRM_TMR5_PERIPH_RESET - CRM_WWDT_PERIPH_RESET - CRM_SPI2_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_BPR_PERIPH_RESET
* - CRM_PWC_PERIPH_RESET - CRM_CAN2_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 100 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 100 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 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 clock divided by 2 */
clocks_struct->sclk_freq = (HEXT_VALUE / 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 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;
}
/**
* @}
*/
#endif
/**
* @}
*/
/**
* @}
*/

View File

@@ -0,0 +1,102 @@
/**
**************************************************************************
* @file at32f413_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 "at32f413_conf.h"
/** @addtogroup AT32F413_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_TMR2_PAUSE
* - DEBUG_TMR3_PAUSE
* - DEBUG_TMR4_PAUSE
* - DEBUG_CAN1_PAUSE
* - DEBUG_I2C1_SMBUS_TIMEOUT
* - DEBUG_I2C2_SMBUS_TIMEOUT
* - DEBUG_TMR8_PAUSE
* - DEBUG_TMR5_PAUSE
* - DEBUG_CAN2_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,470 @@
/**
**************************************************************************
* @file at32f413_dma.c
* @brief contains all the functions for the dma 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 "at32f413_conf.h"
/** @addtogroup AT32F413_periph_driver
* @{
*/
/** @defgroup DMA
* @brief DMA driver modules
* @{
*/
#ifdef DMA_MODULE_ENABLED
/** @defgroup DMA_private_functions
* @{
*/
/**
* @brief reset the dmax channely registers.
* @param dmax_channely:
* this parameter can be one of the following values:
* - DMA1_CHANNEL1
* - DMA1_CHANNEL2
* - DMA1_CHANNEL3
* - DMA1_CHANNEL4
* - DMA1_CHANNEL5
* - DMA1_CHANNEL6
* - DMA1_CHANNEL7
* - DMA2_CHANNEL1
* - DMA2_CHANNEL2
* - DMA2_CHANNEL3
* - DMA2_CHANNEL4
* - DMA2_CHANNEL5
* - DMA2_CHANNEL6
* - DMA2_CHANNEL7
* @retval none
*/
void dma_reset(dma_channel_type* dmax_channely)
{
uint32_t temp = 0;
dmax_channely->ctrl_bit.chen = FALSE;
dmax_channely->ctrl = 0;
dmax_channely->dtcnt = 0;
dmax_channely->paddr = 0;
dmax_channely->maddr = 0;
temp = (uint32_t)dmax_channely;
if((temp & 0x4ff) < 0x408)
{
/* dma1 channel */
DMA1->clr |= (uint32_t)(0x0f << ((((temp & 0xff) - 0x08) / 0x14) * 4));
}
else if((temp & 0x4ff) < 0x488)
{
/* dma2 channel */
DMA2->clr |= (uint32_t)(0x0f << ((((temp & 0xff) - 0x08) / 0x14) * 4));
}
}
/**
* @brief set the number of data to be transferred
* @param dmax_channely:
* this parameter can be one of the following values:
* - DMA1_CHANNEL1
* - DMA1_CHANNEL2
* - DMA1_CHANNEL3
* - DMA1_CHANNEL4
* - DMA1_CHANNEL5
* - DMA1_CHANNEL6
* - DMA1_CHANNEL7
* - DMA2_CHANNEL1
* - DMA2_CHANNEL2
* - DMA2_CHANNEL3
* - DMA2_CHANNEL4
* - DMA2_CHANNEL5
* - DMA2_CHANNEL6
* - DMA2_CHANNEL7
* @param data_number: the number of data to be transferred(0x0000~0xFFFF)
* transfer.
* @retval none.
*/
void dma_data_number_set(dma_channel_type* dmax_channely, uint16_t data_number)
{
dmax_channely->dtcnt = data_number;
}
/**
* @brief get number of data from dtcnt register
* @param dmax_channely:
* this parameter can be one of the following values:
* - DMA1_CHANNEL1
* - DMA1_CHANNEL2
* - DMA1_CHANNEL3
* - DMA1_CHANNEL4
* - DMA1_CHANNEL5
* - DMA1_CHANNEL6
* - DMA1_CHANNEL7
* - DMA2_CHANNEL1
* - DMA2_CHANNEL2
* - DMA2_CHANNEL3
* - DMA2_CHANNEL4
* - DMA2_CHANNEL5
* - DMA2_CHANNEL6
* - DMA2_CHANNEL7
* @retval the number of data.
*/
uint16_t dma_data_number_get(dma_channel_type* dmax_channely)
{
return (uint16_t)dmax_channely->dtcnt;
}
/**
* @brief enable or disable dma interrupt
* @param dmax_channely:
* this parameter can be one of the following values:
* - DMA1_CHANNEL1
* - DMA1_CHANNEL2
* - DMA1_CHANNEL3
* - DMA1_CHANNEL4
* - DMA1_CHANNEL5
* - DMA1_CHANNEL6
* - DMA1_CHANNEL7
* - DMA2_CHANNEL1
* - DMA2_CHANNEL2
* - DMA2_CHANNEL3
* - DMA2_CHANNEL4
* - DMA2_CHANNEL5
* - DMA2_CHANNEL6
* - DMA2_CHANNEL7
* @param dma_int:
* this parameter can be any combination of the following values:
* - DMA_FDT_INT
* - DMA_HDT_INT
* - DMA_DTERR_INT
* @param new_state (TRUE or FALSE)
* @retval none
*/
void dma_interrupt_enable(dma_channel_type* dmax_channely, uint32_t dma_int, confirm_state new_state)
{
if (new_state != FALSE)
{
dmax_channely->ctrl |= dma_int;
}
else
{
dmax_channely->ctrl &= ~dma_int;
}
}
/**
* @brief enable or disable dma channely
* @param dmax_channely:
* this parameter can be one of the following values:
* - DMA1_CHANNEL1
* - DMA1_CHANNEL2
* - DMA1_CHANNEL3
* - DMA1_CHANNEL4
* - DMA1_CHANNEL5
* - DMA1_CHANNEL6
* - DMA1_CHANNEL7
* - DMA2_CHANNEL1
* - DMA2_CHANNEL2
* - DMA2_CHANNEL3
* - DMA2_CHANNEL4
* - DMA2_CHANNEL5
* - DMA2_CHANNEL6
* - DMA2_CHANNEL7
* @param new_state (TRUE or FALSE)
* @retval None
*/
void dma_channel_enable(dma_channel_type* dmax_channely, confirm_state new_state)
{
dmax_channely->ctrl_bit.chen = new_state;
}
/**
* @brief initialize the dma_x flexible function according to the specified parameters.
* @param dma_x:
* this parameter can be one of the following values:
* - DMA1
* - DMA2
* @param flex_channelx:
* this parameter can be one of the following values:
* - FLEX_CHANNEL1
* - FLEX_CHANNEL2
* - FLEX_CHANNEL3
* - FLEX_CHANNEL4
* - FLEX_CHANNEL5
* - FLEX_CHANNEL6
* - FLEX_CHANNEL7
* @param flexible_request: every peripheral have specified hardware_id.
* this parameter can be one of the following values:
* - DMA_FLEXIBLE_ADC1 - DMA_FLEXIBLE_SPI1_RX - DMA_FLEXIBLE_SPI1_TX - DMA_FLEXIBLE_SPI2_RX
* - DMA_FLEXIBLE_SPI2_TX - DMA_FLEXIBLE_UART1_RX - DMA_FLEXIBLE_UART1_TX - DMA_FLEXIBLE_UART2_RX
* - DMA_FLEXIBLE_UART2_TX - DMA_FLEXIBLE_UART3_RX - DMA_FLEXIBLE_UART3_TX - DMA_FLEXIBLE_UART4_RX
* - DMA_FLEXIBLE_UART4_TX - DMA_FLEXIBLE_UART5_RX - DMA_FLEXIBLE_UART5_TX - DMA_FLEXIBLE_I2C1_RX
* - DMA_FLEXIBLE_I2C1_TX - DMA_FLEXIBLE_I2C2_RX - DMA_FLEXIBLE_I2C2_TX - DMA_FLEXIBLE_SDIO1
* - DMA_FLEXIBLE_TMR1_TRIG - DMA_FLEXIBLE_TMR1_HALL - DMA_FLEXIBLE_TMR1_OVERFLOW- DMA_FLEXIBLE_TMR1_CH1
* - DMA_FLEXIBLE_TMR1_CH2 - DMA_FLEXIBLE_TMR1_CH3 - DMA_FLEXIBLE_TMR1_CH4 - DMA_FLEXIBLE_TMR2_TRIG
* - DMA_FLEXIBLE_TMR2_OVERFLOW- DMA_FLEXIBLE_TMR2_CH1 - DMA_FLEXIBLE_TMR2_CH2 - DMA_FLEXIBLE_TMR2_CH3
* - DMA_FLEXIBLE_TMR2_CH4 - DMA_FLEXIBLE_TMR3_TRIG - DMA_FLEXIBLE_TMR3_OVERFLOW- DMA_FLEXIBLE_TMR3_CH1
* - DMA_FLEXIBLE_TMR3_CH2 - DMA_FLEXIBLE_TMR3_CH3 - DMA_FLEXIBLE_TMR3_CH4 - DMA_FLEXIBLE_TMR4_TRIG
* - DMA_FLEXIBLE_TMR4_OVERFLOW- DMA_FLEXIBLE_TMR4_CH1 - DMA_FLEXIBLE_TMR4_CH2 - DMA_FLEXIBLE_TMR4_CH3
* - DMA_FLEXIBLE_TMR4_CH4 - DMA_FLEXIBLE_TMR5_TRIG - DMA_FLEXIBLE_TMR5_OVERFLOW- DMA_FLEXIBLE_TMR5_CH1
* - DMA_FLEXIBLE_TMR5_CH2 - DMA_FLEXIBLE_TMR5_CH3 - DMA_FLEXIBLE_TMR5_CH4 - DMA_FLEXIBLE_TMR8_TRIG
* - DMA_FLEXIBLE_TMR8_HALL - DMA_FLEXIBLE_TMR8_OVERFLOW- DMA_FLEXIBLE_TMR8_CH1 - DMA_FLEXIBLE_TMR8_CH2
* - DMA_FLEXIBLE_TMR8_CH3 - DMA_FLEXIBLE_TMR8_CH4
* @retval none
*/
void dma_flexible_config(dma_type* dma_x, uint8_t flex_channelx, dma_flexible_request_type flexible_request)
{
if(dma_x->src_sel1_bit.dma_flex_en == RESET)
{
dma_x->src_sel1_bit.dma_flex_en = TRUE;
}
if(flex_channelx == FLEX_CHANNEL1)
{
dma_x->src_sel0_bit.ch1_src = flexible_request;
}
else if(flex_channelx == FLEX_CHANNEL2)
{
dma_x->src_sel0_bit.ch2_src = flexible_request;
}
else if(flex_channelx == FLEX_CHANNEL3)
{
dma_x->src_sel0_bit.ch3_src = flexible_request;
}
else if(flex_channelx == FLEX_CHANNEL4)
{
dma_x->src_sel0_bit.ch4_src = flexible_request;
}
else if(flex_channelx == FLEX_CHANNEL5)
{
dma_x->src_sel1_bit.ch5_src = flexible_request;
}
else if(flex_channelx == FLEX_CHANNEL6)
{
dma_x->src_sel1_bit.ch6_src = flexible_request;
}
else
{
if(flex_channelx == FLEX_CHANNEL7)
{
dma_x->src_sel1_bit.ch7_src = flexible_request;
}
}
}
/**
* @brief get dma interrupt flag
* @param dmax_flag
* this parameter can be one of the following values:
* - DMA1_FDT1_FLAG - DMA1_HDT1_FLAG - DMA1_DTERR1_FLAG
* - DMA1_FDT2_FLAG - DMA1_HDT2_FLAG - DMA1_DTERR2_FLAG
* - DMA1_FDT3_FLAG - DMA1_HDT3_FLAG - DMA1_DTERR3_FLAG
* - DMA1_FDT4_FLAG - DMA1_HDT4_FLAG - DMA1_DTERR4_FLAG
* - DMA1_FDT5_FLAG - DMA1_HDT5_FLAG - DMA1_DTERR5_FLAG
* - DMA1_FDT6_FLAG - DMA1_HDT6_FLAG - DMA1_DTERR6_FLAG
* - DMA1_FDT7_FLAG - DMA1_HDT7_FLAG - DMA1_DTERR7_FLAG
* - DMA2_FDT1_FLAG - DMA2_HDT1_FLAG - DMA2_DTERR1_FLAG
* - DMA2_FDT2_FLAG - DMA2_HDT2_FLAG - DMA2_DTERR2_FLAG
* - DMA2_FDT3_FLAG - DMA2_HDT3_FLAG - DMA2_DTERR3_FLAG
* - DMA2_FDT4_FLAG - DMA2_HDT4_FLAG - DMA2_DTERR4_FLAG
* - DMA2_FDT5_FLAG - DMA2_HDT5_FLAG - DMA2_DTERR5_FLAG
* - DMA2_FDT6_FLAG - DMA2_HDT6_FLAG - DMA2_DTERR6_FLAG
* - DMA2_FDT7_FLAG - DMA2_HDT7_FLAG - DMA2_DTERR7_FLAG
* @retval state of dma flag
*/
flag_status dma_interrupt_flag_get(uint32_t dmax_flag)
{
flag_status status = RESET;
uint32_t temp = 0;
if(dmax_flag > 0x10000000)
{
temp = DMA2->sts;
}
else
{
temp = DMA1->sts;
}
if ((temp & dmax_flag) != (uint16_t)RESET)
{
status = SET;
}
else
{
status = RESET;
}
return status;
}
/**
* @brief get dma flag
* @param dmax_flag
* this parameter can be one of the following values:
* - DMA1_GL1_FLAG - DMA1_FDT1_FLAG - DMA1_HDT1_FLAG - DMA1_DTERR1_FLAG
* - DMA1_GL2_FLAG - DMA1_FDT2_FLAG - DMA1_HDT2_FLAG - DMA1_DTERR2_FLAG
* - DMA1_GL3_FLAG - DMA1_FDT3_FLAG - DMA1_HDT3_FLAG - DMA1_DTERR3_FLAG
* - DMA1_GL4_FLAG - DMA1_FDT4_FLAG - DMA1_HDT4_FLAG - DMA1_DTERR4_FLAG
* - DMA1_GL5_FLAG - DMA1_FDT5_FLAG - DMA1_HDT5_FLAG - DMA1_DTERR5_FLAG
* - DMA1_GL6_FLAG - DMA1_FDT6_FLAG - DMA1_HDT6_FLAG - DMA1_DTERR6_FLAG
* - DMA1_GL7_FLAG - DMA1_FDT7_FLAG - DMA1_HDT7_FLAG - DMA1_DTERR7_FLAG
* - DMA2_GL1_FLAG - DMA2_FDT1_FLAG - DMA2_HDT1_FLAG - DMA2_DTERR1_FLAG
* - DMA2_GL2_FLAG - DMA2_FDT2_FLAG - DMA2_HDT2_FLAG - DMA2_DTERR2_FLAG
* - DMA2_GL3_FLAG - DMA2_FDT3_FLAG - DMA2_HDT3_FLAG - DMA2_DTERR3_FLAG
* - DMA2_GL4_FLAG - DMA2_FDT4_FLAG - DMA2_HDT4_FLAG - DMA2_DTERR4_FLAG
* - DMA2_GL5_FLAG - DMA2_FDT5_FLAG - DMA2_HDT5_FLAG - DMA2_DTERR5_FLAG
* - DMA2_GL6_FLAG - DMA2_FDT6_FLAG - DMA2_HDT6_FLAG - DMA2_DTERR6_FLAG
* - DMA2_GL7_FLAG - DMA2_FDT7_FLAG - DMA2_HDT7_FLAG - DMA2_DTERR7_FLAG
* @retval state of dma flag
*/
flag_status dma_flag_get(uint32_t dmax_flag)
{
flag_status status = RESET;
uint32_t temp = 0;
if(dmax_flag > 0x10000000)
{
temp = DMA2->sts;
}
else
{
temp = DMA1->sts;
}
if ((temp & dmax_flag) != (uint16_t)RESET)
{
status = SET;
}
else
{
status = RESET;
}
return status;
}
/**
* @brief clear dma flag
* @param dmax_flag
* this parameter can be one of the following values:
* - DMA1_GL1_FLAG - DMA1_FDT1_FLAG - DMA1_HDT1_FLAG - DMA1_DTERR1_FLAG
* - DMA1_GL2_FLAG - DMA1_FDT2_FLAG - DMA1_HDT2_FLAG - DMA1_DTERR2_FLAG
* - DMA1_GL3_FLAG - DMA1_FDT3_FLAG - DMA1_HDT3_FLAG - DMA1_DTERR3_FLAG
* - DMA1_GL4_FLAG - DMA1_FDT4_FLAG - DMA1_HDT4_FLAG - DMA1_DTERR4_FLAG
* - DMA1_GL5_FLAG - DMA1_FDT5_FLAG - DMA1_HDT5_FLAG - DMA1_DTERR5_FLAG
* - DMA1_GL6_FLAG - DMA1_FDT6_FLAG - DMA1_HDT6_FLAG - DMA1_DTERR6_FLAG
* - DMA1_GL7_FLAG - DMA1_FDT7_FLAG - DMA1_HDT7_FLAG - DMA1_DTERR7_FLAG
* - DMA2_GL1_FLAG - DMA2_FDT1_FLAG - DMA2_HDT1_FLAG - DMA2_DTERR1_FLAG
* - DMA2_GL2_FLAG - DMA2_FDT2_FLAG - DMA2_HDT2_FLAG - DMA2_DTERR2_FLAG
* - DMA2_GL3_FLAG - DMA2_FDT3_FLAG - DMA2_HDT3_FLAG - DMA2_DTERR3_FLAG
* - DMA2_GL4_FLAG - DMA2_FDT4_FLAG - DMA2_HDT4_FLAG - DMA2_DTERR4_FLAG
* - DMA2_GL5_FLAG - DMA2_FDT5_FLAG - DMA2_HDT5_FLAG - DMA2_DTERR5_FLAG
* - DMA2_GL6_FLAG - DMA2_FDT6_FLAG - DMA2_HDT6_FLAG - DMA2_DTERR6_FLAG
* - DMA2_GL7_FLAG - DMA2_FDT7_FLAG - DMA2_HDT7_FLAG - DMA2_DTERR7_FLAG
* @retval none
*/
void dma_flag_clear(uint32_t dmax_flag)
{
if(dmax_flag > ((uint32_t)0x10000000))
{
DMA2->clr = (uint32_t)(dmax_flag & 0x0FFFFFFF);
}
else
{
DMA1->clr = dmax_flag;
}
}
/**
* @brief dma init config with its default value.
* @param dma_init_struct : pointer to a dma_init_type structure which will
* be initialized.
* @retval none
*/
void dma_default_para_init(dma_init_type* dma_init_struct)
{
dma_init_struct->peripheral_base_addr = 0x0;
dma_init_struct->memory_base_addr = 0x0;
dma_init_struct->direction = DMA_DIR_PERIPHERAL_TO_MEMORY;
dma_init_struct->buffer_size = 0x0;
dma_init_struct->peripheral_inc_enable = FALSE;
dma_init_struct->memory_inc_enable = FALSE;
dma_init_struct->peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE;
dma_init_struct->memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE;
dma_init_struct->loop_mode_enable = FALSE;
dma_init_struct->priority = DMA_PRIORITY_LOW;
}
/**
* @brief dma init
* @param dmax_channely:
* this parameter can be one of the following values:
* - DMA1_CHANNEL1
* - DMA1_CHANNEL2
* - DMA1_CHANNEL3
* - DMA1_CHANNEL4
* - DMA1_CHANNEL5
* - DMA1_CHANNEL6
* - DMA1_CHANNEL7
* - DMA2_CHANNEL1
* - DMA2_CHANNEL2
* - DMA2_CHANNEL3
* - DMA2_CHANNEL4
* - DMA2_CHANNEL5
* - DMA2_CHANNEL6
* - DMA2_CHANNEL7
* @param dma_initstruct : pointer to a dma_init_type structure.
* @retval none
*/
void dma_init(dma_channel_type* dmax_channely, dma_init_type* dma_init_struct)
{
/* clear ctrl register dtd bit and m2m bit */
dmax_channely->ctrl &= 0xbfef;
dmax_channely->ctrl |= dma_init_struct->direction;
dmax_channely->ctrl_bit.chpl = dma_init_struct->priority;
dmax_channely->ctrl_bit.mwidth = dma_init_struct->memory_data_width;
dmax_channely->ctrl_bit.pwidth = dma_init_struct->peripheral_data_width;
dmax_channely->ctrl_bit.mincm = dma_init_struct->memory_inc_enable;
dmax_channely->ctrl_bit.pincm = dma_init_struct->peripheral_inc_enable;
dmax_channely->ctrl_bit.lm = dma_init_struct->loop_mode_enable;
dmax_channely->dtcnt = dma_init_struct->buffer_size;
dmax_channely->paddr = dma_init_struct->peripheral_base_addr;
dmax_channely->maddr = dma_init_struct->memory_base_addr;
}
/**
* @}
*/
#endif
/**
* @}
*/
/**
* @}
*/

View File

@@ -0,0 +1,263 @@
/**
**************************************************************************
* @file at32f413_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 "at32f413_conf.h"
/** @addtogroup AT32F413_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 = 0x0007FFFF;
}
/**
* @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_17
* - EXINT_LINE_18
* @retval none
*/
void exint_flag_clear(uint32_t exint_line)
{
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_17
* - EXINT_LINE_18
* @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_17
* - EXINT_LINE_18
* @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_17
* - EXINT_LINE_18
* @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_17
* - EXINT_LINE_18
* @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_17
* - EXINT_LINE_18
* @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
/**
* @}
*/
/**
* @}
*/

View File

@@ -0,0 +1,961 @@
/**
**************************************************************************
* @file at32f413_flash.c
* @brief contains all the functions for the flash 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 "at32f413_conf.h"
/** @addtogroup AT32F413_periph_driver
* @{
*/
/** @defgroup FLASH
* @brief FLASH driver modules
* @{
*/
#ifdef FLASH_MODULE_ENABLED
/** @defgroup FLASH_private_functions
* @{
*/
/**
* @brief check whether the specified flash flag is set or not.
* @param flash_flag: specifies the flash flag to check.
* this parameter can be one of flash flag status:
* - FLASH_OBF_FLAG
* - FLASH_ODF_FLAG
* - FLASH_PRGMERR_FLAG
* - FLASH_EPPERR_FLAG
* - FLASH_SPIM_OBF_FLAG
* - FLASH_SPIM_ODF_FLAG
* - FLASH_SPIM_PRGMERR_FLAG
* - FLASH_SPIM_EPPERR_FLAG
* - FLASH_USDERR_FLAG
* @retval the new state of flash_flag (SET or RESET).
*/
flag_status flash_flag_get(uint32_t flash_flag)
{
flag_status status = RESET;
uint32_t flag_position;
flag_position = flash_flag & 0x70000000;
flash_flag &= 0x8FFFFFFF;
switch(flag_position)
{
case 0x00000000:
if(FLASH->sts & flash_flag)
status = SET;
break;
case 0x20000000:
if(FLASH->sts3 & flash_flag)
status = SET;
break;
case 0x40000000:
if(FLASH->usd & flash_flag)
status = SET;
break;
default:
break;
}
/* return the new state of flash_flag (SET or RESET) */
return status;
}
/**
* @brief clear the flash flag.
* @param flash_flag: specifies the flash flags to clear.
* this parameter can be any combination of the following values:
* - FLASH_ODF_FLAG
* - FLASH_PRGMERR_FLAG
* - FLASH_EPPERR_FLAG
* - FLASH_SPIM_ODF_FLAG
* - FLASH_SPIM_PRGMERR_FLAG
* - FLASH_SPIM_EPPERR_FLAG
* @retval none
*/
void flash_flag_clear(uint32_t flash_flag)
{
uint32_t flag_position;
flag_position = flash_flag & 0x70000000;
flash_flag &= 0x8FFFFFFF;
switch(flag_position)
{
case 0x00000000:
FLASH->sts = flash_flag;
break;
case 0x20000000:
FLASH->sts3 = flash_flag;
break;
default:
break;
}
}
/**
* @brief return the flash operation status.
* @param none
* @retval status: the returned value can be: FLASH_OPERATE_BUSY,
* FLASH_PROGRAM_ERROR, FLASH_EPP_ERROR or FLASH_OPERATE_DONE.
*/
flash_status_type flash_operation_status_get(void)
{
flash_status_type flash_status = FLASH_OPERATE_DONE;
if(FLASH->sts_bit.obf != RESET)
{
flash_status = FLASH_OPERATE_BUSY;
}
else if(FLASH->sts_bit.prgmerr != RESET)
{
flash_status = FLASH_PROGRAM_ERROR;
}
else if(FLASH->sts_bit.epperr != RESET)
{
flash_status = FLASH_EPP_ERROR;
}
else
{
flash_status = FLASH_OPERATE_DONE;
}
/* return the flash status */
return flash_status;
}
/**
* @brief return the flash spim operation status.
* @param none
* @retval status: the returned value can be: FLASH_OPERATE_BUSY,
* FLASH_PROGRAM_ERROR, FLASH_EPP_ERROR or FLASH_OPERATE_DONE.
*/
flash_status_type flash_spim_operation_status_get(void)
{
flash_status_type flash_status = FLASH_OPERATE_DONE;
if(FLASH->sts3_bit.obf != RESET)
{
flash_status = FLASH_OPERATE_BUSY;
}
else if(FLASH->sts3_bit.prgmerr != RESET)
{
flash_status = FLASH_PROGRAM_ERROR;
}
else if(FLASH->sts3_bit.epperr != RESET)
{
flash_status = FLASH_EPP_ERROR;
}
else
{
flash_status = FLASH_OPERATE_DONE;
}
/* return the flash status */
return flash_status;
}
/**
* @brief wait for flash operation complete or timeout.
* @param time_out: flash operation timeout
* @retval status: the returned value can be: FLASH_PROGRAM_ERROR,
* FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT.
*/
flash_status_type flash_operation_wait_for(uint32_t time_out)
{
flash_status_type status = FLASH_OPERATE_DONE;
/* check for the flash status */
status = flash_operation_status_get();
while((status == FLASH_OPERATE_BUSY) && (time_out != 0x00))
{
status = flash_operation_status_get();
time_out--;
}
if(time_out == 0x00)
{
status = FLASH_OPERATE_TIMEOUT;
}
/* return the status */
return status;
}
/**
* @brief wait for flash spim operation complete or timeout.
* @param time_out: flash operation timeout
* @retval status: the returned value can be: FLASH_PROGRAM_ERROR,
* FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT.
*/
flash_status_type flash_spim_operation_wait_for(uint32_t time_out)
{
flash_status_type status = FLASH_OPERATE_DONE;
/* check for the flash status */
status = flash_spim_operation_status_get();
while((status == FLASH_OPERATE_BUSY) && (time_out != 0x00))
{
status = flash_spim_operation_status_get();
time_out--;
}
if(time_out == 0x00)
{
status = FLASH_OPERATE_TIMEOUT;
}
/* return the operation status */
return status;
}
/**
* @brief unlock the flash controller.
* @param none
* @retval none
*/
void flash_unlock(void)
{
FLASH->unlock = FLASH_UNLOCK_KEY1;
FLASH->unlock = FLASH_UNLOCK_KEY2;
}
/**
* @brief unlock the flash spim controller.
* @param none
* @retval none
*/
void flash_spim_unlock(void)
{
FLASH->unlock3 = FLASH_UNLOCK_KEY1;
FLASH->unlock3 = FLASH_UNLOCK_KEY2;
}
/**
* @brief lock the flash controller.
* @param none
* @retval none
*/
void flash_lock(void)
{
FLASH->ctrl_bit.oplk = TRUE;
}
/**
* @brief lock the flash spim controller.
* @param none
* @retval none
*/
void flash_spim_lock(void)
{
FLASH->ctrl3_bit.oplk = TRUE;
}
/**
* @brief erase a specified flash sector.
* @param sector_address: the sector address to be erased.
* @retval status: the returned value can be: FLASH_PROGRAM_ERROR,
* FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT.
*/
flash_status_type flash_sector_erase(uint32_t sector_address)
{
flash_status_type status = FLASH_OPERATE_DONE;
/* spim : external flash */
if(sector_address >= FLASH_SPIM_START_ADDR)
{
FLASH->ctrl3_bit.secers = TRUE;
FLASH->addr3 = sector_address;
FLASH->ctrl3_bit.erstr = TRUE;
/* wait for operation to be completed */
status = flash_spim_operation_wait_for(SPIM_ERASE_TIMEOUT);
/* disable the secers bit */
FLASH->ctrl3_bit.secers = FALSE;
/* dummy read */
flash_spim_dummy_read();
}
else
{
FLASH->ctrl_bit.secers = TRUE;
FLASH->addr = sector_address;
FLASH->ctrl_bit.erstr = TRUE;
/* wait for operation to be completed */
status = flash_operation_wait_for(ERASE_TIMEOUT);
/* disable the secers bit */
FLASH->ctrl_bit.secers = FALSE;
}
/* return the erase status */
return status;
}
/**
* @brief erase flash all internal sectors.
* @param none
* @retval status: the returned value can be: FLASH_PROGRAM_ERROR,
* FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT.
*/
flash_status_type flash_internal_all_erase(void)
{
flash_status_type status = FLASH_OPERATE_DONE;
FLASH->ctrl_bit.bankers = TRUE;
FLASH->ctrl_bit.erstr = TRUE;
/* wait for operation to be completed */
status = flash_operation_wait_for(ERASE_TIMEOUT);
/* disable the bankers bit */
FLASH->ctrl_bit.bankers = FALSE;
/* return the erase status */
return status;
}
/**
* @brief erase flash spim sectors.
* @param none
* @retval status: the returned value can be: FLASH_PROGRAM_ERROR,
* FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT.
*/
flash_status_type flash_spim_all_erase(void)
{
flash_status_type status = FLASH_OPERATE_DONE;
FLASH->ctrl3_bit.chpers = TRUE;
FLASH->ctrl3_bit.erstr = TRUE;
/* wait for operation to be completed */
status = flash_spim_operation_wait_for(SPIM_ERASE_TIMEOUT);
/* disable the chpers bit */
FLASH->ctrl3_bit.chpers = FALSE;
/* dummy read */
flash_spim_dummy_read();
/* return the erase status */
return status;
}
/**
* @brief erase the flash user system data.
* @note this functions erases all user system data except the fap byte.
* @param none
* @retval status: the returned value can be: FLASH_PROGRAM_ERROR,
* FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT.
*/
flash_status_type flash_user_system_data_erase(void)
{
flash_status_type status = FLASH_OPERATE_DONE;
uint16_t fap_val = FAP_RELIEVE_KEY;
/* get the flash access protection status */
if(flash_fap_status_get() != RESET)
{
fap_val = 0x0000;
}
/* unlock the user system data */
FLASH->usd_unlock = FLASH_UNLOCK_KEY1;
FLASH->usd_unlock = FLASH_UNLOCK_KEY2;
while(FLASH->ctrl_bit.usdulks == RESET);
/* erase the user system data */
FLASH->ctrl_bit.usders = TRUE;
FLASH->ctrl_bit.erstr = TRUE;
/* wait for operation to be completed */
status = flash_operation_wait_for(ERASE_TIMEOUT);
/* disable the usders bit */
FLASH->ctrl_bit.usders = FALSE;
if((status == FLASH_OPERATE_DONE) && (fap_val == FAP_RELIEVE_KEY))
{
/* enable the user system data programming operation */
FLASH->ctrl_bit.usdprgm = TRUE;
/* restore the last flash access protection value */
USD->fap = (uint16_t)fap_val;
/* wait for operation to be completed */
status = flash_operation_wait_for(PROGRAMMING_TIMEOUT);
/*disable the usdprgm bit */
FLASH->ctrl_bit.usdprgm = FALSE;
}
/* return the erase status */
return status;
}
/**
* @brief program a word at a specified address.
* @param address: specifies the address to be programmed, word alignment is recommended.
* @param data: specifies the data to be programmed.
* @retval status: the returned value can be: FLASH_PROGRAM_ERROR,
* FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT.
*/
flash_status_type flash_word_program(uint32_t address, uint32_t data)
{
flash_status_type status = FLASH_OPERATE_DONE;
/* spim : external flash */
if(address >= FLASH_SPIM_START_ADDR)
{
FLASH->ctrl3_bit.fprgm = TRUE;
*(__IO uint32_t*)address = data;
/* wait for operation to be completed */
status = flash_spim_operation_wait_for(SPIM_PROGRAMMING_TIMEOUT);
/* disable the fprgm bit */
FLASH->ctrl3_bit.fprgm = FALSE;
/* dummy read */
flash_spim_dummy_read();
}
else
{
FLASH->ctrl_bit.fprgm = TRUE;
*(__IO uint32_t*)address = data;
/* wait for operation to be completed */
status = flash_operation_wait_for(PROGRAMMING_TIMEOUT);
/* disable the fprgm bit */
FLASH->ctrl_bit.fprgm = FALSE;
}
/* return the program status */
return status;
}
/**
* @brief program a halfword at a specified address.
* @param address: specifies the address to be programmed, halfword alignment is recommended.
* @param data: specifies the data to be programmed.
* @retval status: the returned value can be: FLASH_PROGRAM_ERROR,
* FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT.
*/
flash_status_type flash_halfword_program(uint32_t address, uint16_t data)
{
flash_status_type status = FLASH_OPERATE_DONE;
/* spim : external flash */
if(address >= FLASH_SPIM_START_ADDR)
{
FLASH->ctrl3_bit.fprgm = TRUE;
*(__IO uint16_t*)address = data;
/* wait for operation to be completed */
status = flash_spim_operation_wait_for(SPIM_PROGRAMMING_TIMEOUT);
/* disable the fprgm bit */
FLASH->ctrl3_bit.fprgm = FALSE;
/* dummy read */
flash_spim_dummy_read();
}
else
{
FLASH->ctrl_bit.fprgm = TRUE;
*(__IO uint16_t*)address = data;
/* wait for operation to be completed */
status = flash_operation_wait_for(PROGRAMMING_TIMEOUT);
/* disable the fprgm bit */
FLASH->ctrl_bit.fprgm = FALSE;
}
/* return the program status */
return status;
}
/**
* @brief program a byte at a specified address.
* @note this function cannot be used to program spim.
* @param address: specifies the address to be programmed.
* @param data: specifies the data to be programmed.
* @retval status: the returned value can be: FLASH_PROGRAM_ERROR,
* FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT.
*/
flash_status_type flash_byte_program(uint32_t address, uint8_t data)
{
flash_status_type status = FLASH_OPERATE_DONE;
FLASH->ctrl_bit.fprgm = TRUE;
*(__IO uint8_t*)address = data;
/* wait for operation to be completed */
status = flash_operation_wait_for(PROGRAMMING_TIMEOUT);
/* disable the fprgm bit */
FLASH->ctrl_bit.fprgm = FALSE;
/* return the program status */
return status;
}
/**
* @brief program a halfword at a specified user system data address.
* @param address: specifies the address to be programmed.
* @param data: specifies the data to be programmed.
* @retval status: the returned value can be: FLASH_PROGRAM_ERROR,
* FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT.
*/
flash_status_type flash_user_system_data_program(uint32_t address, uint8_t data)
{
flash_status_type status = FLASH_OPERATE_DONE;
if(address == USD_BASE)
{
if(data != 0xA5)
return FLASH_OPERATE_DONE;
}
/* unlock the user system data */
FLASH->usd_unlock = FLASH_UNLOCK_KEY1;
FLASH->usd_unlock = FLASH_UNLOCK_KEY2;
while(FLASH->ctrl_bit.usdulks==RESET);
/* enable the user system data programming operation */
FLASH->ctrl_bit.usdprgm = TRUE;
*(__IO uint16_t*)address = data;
/* wait for operation to be completed */
status = flash_operation_wait_for(PROGRAMMING_TIMEOUT);
/* disable the usdprgm bit */
FLASH->ctrl_bit.usdprgm = FALSE;
/* return the user system data program status */
return status;
}
/**
* @brief config erase/program protection for the desired sectors.
* @param sector_bits:
* the pointer of the address of the sectors to be erase/program protected.
* general every bit is used to protect the 4KB bytes, and the last one bit
* is used to protect the rest.
* @retval status: the returned value can be: FLASH_PROGRAM_ERROR,
* FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT.
*/
flash_status_type flash_epp_set(uint32_t *sector_bits)
{
uint16_t epp_data[4] = {0xFFFF,0xFFFF,0xFFFF,0xFFFF};
flash_status_type status = FLASH_OPERATE_DONE;
sector_bits[0] = (uint32_t)(~sector_bits[0]);
epp_data[0] = (uint16_t)((sector_bits[0] >> 0) & 0xFF);
epp_data[1] = (uint16_t)((sector_bits[0] >> 8) & 0xFF);
epp_data[2] = (uint16_t)((sector_bits[0] >> 16) & 0xFF);
epp_data[3] = (uint16_t)((sector_bits[0] >> 24) & 0xFF);
/* unlock the user system data */
FLASH->usd_unlock = FLASH_UNLOCK_KEY1;
FLASH->usd_unlock = FLASH_UNLOCK_KEY2;
while(FLASH->ctrl_bit.usdulks==RESET);
FLASH->ctrl_bit.usdprgm = TRUE;
USD->epp0 = epp_data[0];
/* wait for operation to be completed */
status = flash_operation_wait_for(PROGRAMMING_TIMEOUT);
if(status == FLASH_OPERATE_DONE)
{
USD->epp1 = epp_data[1];
/* wait for operation to be completed */
status = flash_operation_wait_for(PROGRAMMING_TIMEOUT);
}
if(status == FLASH_OPERATE_DONE)
{
USD->epp2 = epp_data[2];
/* wait for operation to be completed */
status = flash_operation_wait_for(PROGRAMMING_TIMEOUT);
}
if(status == FLASH_OPERATE_DONE)
{
USD->epp3 = epp_data[3];
/* wait for operation to be completed */
status = flash_operation_wait_for(PROGRAMMING_TIMEOUT);
}
/* disable the usdprgm bit */
FLASH->ctrl_bit.usdprgm = FALSE;
/* return the erase/program protection operation status */
return status;
}
/**
* @brief return the flash erase/program protection status.
* @param sector_bits: pointer to get the epps register.
* @retval none
*/
void flash_epp_status_get(uint32_t *sector_bits)
{
/* return the flash erase/program protection register value */
sector_bits[0] = (uint32_t)(FLASH->epps);
}
/**
* @brief enable or disable the flash access protection.
* @note if the user has already programmed the other user system data before calling
* this function, must re-program them since this function erase all user system data.
* @param new_state: new state of the flash access protection.
* this parameter can be: TRUE or FALSE.
* @retval status: the returned value can be: FLASH_PROGRAM_ERROR,
* FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT.
*/
flash_status_type flash_fap_enable(confirm_state new_state)
{
flash_status_type status = FLASH_OPERATE_DONE;
/* unlock the user system data */
FLASH->usd_unlock = FLASH_UNLOCK_KEY1;
FLASH->usd_unlock = FLASH_UNLOCK_KEY2;
while(FLASH->ctrl_bit.usdulks==RESET);
FLASH->ctrl_bit.usders = TRUE;
FLASH->ctrl_bit.erstr = TRUE;
/* wait for operation to be completed */
status = flash_operation_wait_for(ERASE_TIMEOUT);
/* disable the usders bit */
FLASH->ctrl_bit.usders = FALSE;
if(status == FLASH_OPERATE_DONE)
{
if(new_state == FALSE)
{
/* enable the user system data programming operation */
FLASH->ctrl_bit.usdprgm = TRUE;
USD->fap = FAP_RELIEVE_KEY;
/* Wait for operation to be completed */
status = flash_operation_wait_for(ERASE_TIMEOUT);
/* disable the usdprgm bit */
FLASH->ctrl_bit.usdprgm = FALSE;
}
}
/* return the flash access protection operation status */
return status;
}
/**
* @brief check the flash access protection status.
* @param none
* @retval flash access protection status(SET or RESET)
*/
flag_status flash_fap_status_get(void)
{
return (flag_status)FLASH->usd_bit.fap;
}
/**
* @brief program the flash system setting byte in usd: wdt_ato_en / depslp_rst / stdby_rst.
* @param usd_ssb: the system setting byte
* @note this parameter usd_ssb must contain a combination of all the following 3 types of data
* type 1: wdt_ato_en, select the wdt auto start
* this data can be one of the following values:
* - USD_WDT_ATO_DISABLE: disable wdt auto start
* - USD_WDT_ATO_ENABLE: enable wdt auto start
* type 2: depslp_rst, reset event when entering deepsleep mode.
* this data can be one of the following values:
* - USD_DEPSLP_NO_RST: no reset generated when entering in deepsleep
* - USD_DEPSLP_RST: reset generated when entering in deepsleep
* type 3: stdby_rst, reset event when entering standby mode.
* this data can be one of the following values:
* - USD_STDBY_NO_RST: no reset generated when entering in standby
* - USD_STDBY_RST: reset generated when entering in standby
* @retval status: the returned value can be: FLASH_PROGRAM_ERROR,
* FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT.
*/
flash_status_type flash_ssb_set(uint8_t usd_ssb)
{
flash_status_type status = FLASH_OPERATE_DONE;
/* unlock the user system data */
FLASH->usd_unlock = FLASH_UNLOCK_KEY1;
FLASH->usd_unlock = FLASH_UNLOCK_KEY2;
while(FLASH->ctrl_bit.usdulks==RESET);
/* enable the user system data programming operation */
FLASH->ctrl_bit.usdprgm = TRUE;
USD->ssb = usd_ssb;
/* wait for operation to be completed */
status = flash_operation_wait_for(PROGRAMMING_TIMEOUT);
/* disable the usdprgm bit */
FLASH->ctrl_bit.usdprgm = FALSE;
/* return the user system data program status */
return status;
}
/**
* @brief return the flash system setting byte status.
* @param none
* @retval values from flash_usd register: wdt_ato_en(bit0), depslp_rst(bit1) and stdby_rst(bit2).
*/
uint8_t flash_ssb_status_get(void)
{
/* return the system setting byte status */
return (uint8_t)(FLASH->usd >> 2);
}
/**
* @brief enable or disable the specified flash interrupts.
* @param flash_int: specifies the flash interrupt sources to be enabled or disabled.
* this parameter can be any combination of the following values:
* - FLASH_ERR_INT
* - FLASH_ODF_INT
* - FLASH_SPIM_ERR_INT
* - FLASH_SPIM_ODF_INT
* @param new_state: new state of the specified flash interrupts.
* this parameter can be: TRUE or FALSE.
* @retval none
*/
void flash_interrupt_enable(uint32_t flash_int, confirm_state new_state)
{
if(flash_int & FLASH_ERR_INT)
FLASH->ctrl_bit.errie = new_state;
if(flash_int & FLASH_ODF_INT)
FLASH->ctrl_bit.odfie = new_state;
if(flash_int & FLASH_SPIM_ERR_INT)
FLASH->ctrl3_bit.errie = new_state;
if(flash_int & FLASH_SPIM_ODF_INT)
FLASH->ctrl3_bit.odfie = new_state;
}
/**
* @brief select spim supports extended spi flash chip model.
* @param mode: the extended spi flash model
* @retval none
*/
void flash_spim_model_select(flash_spim_model_type mode)
{
FLASH->select = mode;
/* dummy read */
flash_spim_dummy_read();
}
/**
* @brief set the range of encryption in spim flash.
* when the address is larger than this value, the writing data will be
* directly written to spim without encryption.
* @param decode_address: the end address of encrypted data in spim
* @retval none
*/
void flash_spim_encryption_range_set(uint32_t decode_address)
{
FLASH->da = decode_address;
}
/**
* @brief operate the flash spim dummy read.
* @param none
* @retval none
*/
void flash_spim_dummy_read(void)
{
UNUSED(*(__IO uint32_t*)FLASH_SPIM_START_ADDR);
UNUSED(*(__IO uint32_t*)(FLASH_SPIM_START_ADDR + 0x1000));
UNUSED(*(__IO uint32_t*)(FLASH_SPIM_START_ADDR + 0x2000));
}
/**
* @brief mass program for flash spim.
* @param address: specifies the start address to be programmed, word or halfword alignment is recommended.
* @param buf: specifies the pointer of data to be programmed.
* @param cnt: specifies the data counter to be programmed.
* @retval status: the returned value can be: FLASH_PROGRAM_ERROR,
* FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT.
*/
flash_status_type flash_spim_mass_program(uint32_t address, uint8_t *buf, uint32_t cnt)
{
flash_status_type status = FLASH_OPERATE_DONE;
uint32_t index, temp_offset;
if(address >= FLASH_SPIM_START_ADDR)
{
temp_offset = cnt % 4;
if((temp_offset != 0) && (temp_offset != 2))
return status;
FLASH->ctrl3_bit.fprgm = TRUE;
for(index = 0; index < cnt / 4; index++)
{
*(__IO uint32_t*)(address + index * 4) = *(uint32_t*)(buf + index * 4);
/* wait for operation to be completed */
status = flash_spim_operation_wait_for(SPIM_PROGRAMMING_TIMEOUT);
if(status != FLASH_OPERATE_DONE)
return status;
}
if(temp_offset == 2)
{
*(__IO uint16_t*)(address + index * 4) = *(uint16_t*)(buf + index * 4);
/* wait for operation to be completed */
status = flash_spim_operation_wait_for(SPIM_PROGRAMMING_TIMEOUT);
}
/* disable the fprgm bit */
FLASH->ctrl3_bit.fprgm = FALSE;
/* dummy read */
flash_spim_dummy_read();
}
/* return the program status */
return status;
}
/**
* @brief enable security library function.
* @param pwd: slib password
* start_sector: security library start sector
* data_start_sector: security library d-bus area start sector
* end_sector: security library end sector
* @retval status: the returned value can be: FLASH_PROGRAM_ERROR,
* FLASH_EPP_ERROR, FLASH_OPERATE_DONE or FLASH_OPERATE_TIMEOUT.
*/
flash_status_type flash_slib_enable(uint32_t pwd, uint16_t start_sector, uint16_t data_start_sector, uint16_t end_sector)
{
uint32_t slib_range;
flash_status_type status = FLASH_OPERATE_DONE;
/*check range param limits*/
if((start_sector>=data_start_sector) || ((data_start_sector > end_sector) && \
(data_start_sector != 0x7FF)) || (start_sector > end_sector))
return FLASH_PROGRAM_ERROR;
/* unlock slib cfg register */
FLASH->slib_unlock = SLIB_UNLOCK_KEY;
while(FLASH->slib_misc_sts_bit.slib_ulkf==RESET);
slib_range = ((uint32_t)(data_start_sector << 11) & FLASH_SLIB_DATA_START_SECTOR) | \
((uint32_t)(end_sector << 22) & FLASH_SLIB_END_SECTOR) | \
(start_sector & FLASH_SLIB_START_SECTOR);
/* configure slib, set pwd and range */
FLASH->slib_set_pwd = pwd;
status = flash_operation_wait_for(PROGRAMMING_TIMEOUT);
if(status == FLASH_OPERATE_DONE)
{
FLASH->slib_set_range = slib_range;
status = flash_operation_wait_for(PROGRAMMING_TIMEOUT);
}
return status;
}
/**
* @brief disable slib when slib enabled.
* @param pwd: slib password
* @retval success or error
*/
error_status flash_slib_disable(uint32_t pwd)
{
flash_status_type status = FLASH_OPERATE_DONE;
/* write password to disable slib */
FLASH->slib_pwd_clr = pwd;
status = flash_operation_wait_for(ERASE_TIMEOUT);
if(status == FLASH_OPERATE_DONE)
{
if(FLASH->slib_misc_sts_bit.slib_pwd_ok)
return SUCCESS;
else
return ERROR;
}
return ERROR;
}
/**
* @brief get remaining count of slib(range: 256~0).
* @param none
* @retval uint32_t
*/
uint32_t flash_slib_remaining_count_get(void)
{
return (uint32_t)FLASH->slib_misc_sts_bit.slib_rcnt;
}
/**
* @brief get the slib state.
* @param none
* @retval SET or RESET
*/
flag_status flash_slib_state_get(void)
{
if(FLASH->slib_sts0_bit.slib_enf)
return SET;
else
return RESET;
}
/**
* @brief get the start sector of slib.
* @param none
* @retval uint16_t
*/
uint16_t flash_slib_start_sector_get(void)
{
return (uint16_t)FLASH->slib_sts1_bit.slib_ss;
}
/**
* @brief get the data start sector of slib.
* @param none
* @retval uint16_t
*/
uint16_t flash_slib_datastart_sector_get(void)
{
return (uint16_t)FLASH->slib_sts1_bit.slib_dat_ss;
}
/**
* @brief get the end sector of slib.
* @param none
* @retval uint16_t
*/
uint16_t flash_slib_end_sector_get(void)
{
return (uint16_t)FLASH->slib_sts1_bit.slib_es;
}
/**
* @brief flash crc calibration in main block.
* @param start_sector: crc calibration start sector number
* sector_cnt: crc calibration sector count
* @retval uint32: crc calibration result
*/
uint32_t flash_crc_calibrate(uint32_t start_sector, uint32_t sector_cnt)
{
FLASH->crc_ctrl_bit.crc_ss = start_sector;
FLASH->crc_ctrl_bit.crc_sn = sector_cnt;
FLASH->crc_ctrl_bit.crc_strt = TRUE;
flash_operation_wait_for(OPERATION_TIMEOUT);
return FLASH->crc_chkr;
}
/**
* @}
*/
#endif
/**
* @}
*/
/**
* @}
*/

View File

@@ -0,0 +1,611 @@
/**
**************************************************************************
* @file at32f413_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 "at32f413_conf.h"
/** @addtogroup AT32F413_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, GPIOF.
* @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 == GPIOF)
{
crm_periph_reset(CRM_GPIOF_PERIPH_RESET, TRUE);
crm_periph_reset(CRM_GPIOF_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, GPIOF.
* @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, GPIOF.
* @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, GPIOF.
* @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, GPIOF.
* @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, GPIOF.
* @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, GPIOF.
* @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, GPIOF.
* @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, GPIOF.
* @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, GPIOF.
* @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, GPIOF.
* @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 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_GPIOF
* @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 - I2C1_MUX - USART1_MUX - USART3_MUX_01
* - TMR1_MUX_01 - TMR2_MUX_01 - TMR2_MUX_10 - TMR2_MUX_11
* - TMR3_MUX_10 - TMR3_MUX_11 - CAN_MUX_10 - PD01_MUX
* - TMR5CH4_MUX - ADC1_EXTRGPRE_MUX - ADC1_EXTRGORD_MUX - ADC2_EXTRGPRE_MUX
* - ADC2_EXTRGORD_MUX - SWJTAG_CONF_001 - SWJTAG_CONF_010 - SWJTAG_CONF_100
* - EXT_SPIM_EN_MUX - TMR9_GMUX - TMR10_GMUX - TMR11_GMUX
* - TMR1_GMUX_0001 - TMR2_GMUX_001 - TMR2_GMUX_010 - TMR2_GMUX_011
* - TMR2ITR1_GMUX - TMR3_GMUX_0010 - TMR3_GMUX_0011 - TMR5_GMUX_001
* - TMR5CH4_GMUX - I2C1_GMUX_0001 - I2C1_GMUX_0011 - I2C2_GMUX_0001
* - I2C2_GMUX_0010 - I2C2_GMUX_0011 - SPI1_GMUX_0001 - SPI2_GMUX_0001
* - CAN1_GMUX_0010 - CAN2_GMUX_0001 - SDIO1_GMUX_0100 - SDIO1_GMUX_0101
* - SDIO1_GMUX_0110 - SDIO1_GMUX_0111 - USART1_GMUX_0001 - USART3_GMUX_0001
* - UART4_GMUX_0001 - 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
* @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_GPIOF
* @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,721 @@
/**
**************************************************************************
* @file at32f413_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 "at32f413_conf.h"
/** @addtogroup AT32F413_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.
* @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);
}
}
/**
* @brief software reset.
* @param i2c_x: to select the i2c peripheral.
* this parameter can be one of the following values:
* I2C1, I2C2.
* @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.
* @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;
}
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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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 at32f413_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 "at32f413_conf.h"
/** @addtogroup AT32F413_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,234 @@
/**
**************************************************************************
* @file at32f413_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 "at32f413_conf.h"
/** @addtogroup AT32F413_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 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
/**
* @}
*/
/**
* @}
*/

View File

@@ -0,0 +1,247 @@
/**
**************************************************************************
* @file at32f413_rtc.c
* @brief contains all the functions for the rtc 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 "at32f413_conf.h"
/** @addtogroup AT32F413_periph_driver
* @{
*/
/** @defgroup RTC
* @brief RTC driver modules
* @{
*/
#ifdef RTC_MODULE_ENABLED
/** @defgroup RTC_private_functions
* @{
*/
/**
* @brief rtc counter set
* @param counter_value (0x0000_0000 ~ 0xFFFF_FFFF)
* @retval none
*/
void rtc_counter_set(uint32_t counter_value)
{
/* enter rtc config mode */
RTC->ctrll = 0x003F;
/* set rtc counter */
RTC->cnth_bit.cnt = (uint16_t)(counter_value >> 16);
RTC->cntl_bit.cnt = (uint16_t)(counter_value & 0x0000FFFF);
/* exit rtc config mode */
RTC->ctrll = 0x000F;
}
/**
* @brief rtc counter get
* @param none
* @retval rtc counter
*/
uint32_t rtc_counter_get(void)
{
uint32_t cnt = 0;
cnt = RTC->cnth;
cnt = (cnt << 16) | RTC->cntl;
return cnt;
}
/**
* @brief rtc divider set
* @param div_value (0x0000_0000 ~ 0x000F_FFFF)
* @retval none
*/
void rtc_divider_set(uint32_t div_value)
{
/* enter rtc config mode */
RTC->ctrll = 0x003F;
/* set rtc divider */
RTC->divh_bit.div = (uint16_t)(div_value >> 16);
RTC->divl_bit.div = (uint16_t)(div_value & 0x0000FFFF);
/* exit rtc config mode */
RTC->ctrll = 0x000F;
}
/**
* @brief rtc divider get
* @param none
* @retval rtc counter
*/
uint32_t rtc_divider_get(void)
{
uint32_t div = 0;
div = RTC->divcnth;
div = (div << 16) | RTC->divcntl;
return div;
}
/**
* @brief rtc alarm value set
* @param alarm_value (0x0000_0000 ~ 0xFFFF_FFFF)
* @retval none
*/
void rtc_alarm_set(uint32_t alarm_value)
{
/* enter rtc config mode */
RTC->ctrll = 0x003F;
/* set rtc alarm value */
RTC->tah_bit.ta = (uint16_t)(alarm_value >> 16);
RTC->tal_bit.ta = (uint16_t)(alarm_value & 0x0000FFFF);
/* exit rtc config mode */
RTC->ctrll = 0x000F;
}
/**
* @brief rtc interrupt enable
* @param source
* this parameter can be any combination of the following values:
* - RTC_TS_INT: time second interrupt.
* - RTC_TA_INT: time alarm interrupt.
* - RTC_OVF_INT: overflow interrupt.
* @param new_state (TRUE or FALSE)
* @retval none
*/
void rtc_interrupt_enable(uint16_t source, confirm_state new_state)
{
if(new_state == FALSE)
{
RTC->ctrlh &= ~source;
}
else
{
RTC->ctrlh |= source;
}
}
/**
* @brief rtc flag get
* @param flag
* this parameter can be one of the following values:
* - RTC_TS_FLAG: time second flag.
* - RTC_TA_FLAG: time alarm flag.
* - RTC_OVF_FLAG: overflow flag.
* - RTC_UPDF_FLAG: rtc update finish flag.
* - RTC_CFGF_FLAG: rtc configuration finish flag.
* @retval state of rtc flag
*/
flag_status rtc_flag_get(uint16_t flag)
{
flag_status status = RESET;
if ((RTC->ctrll & flag) != (uint16_t)RESET)
{
status = SET;
}
else
{
status = RESET;
}
return status;
}
/**
* @brief rtc interrupt flag get
* @param flag
* this parameter can be one of the following values:
* - RTC_TS_FLAG: time second flag.
* - RTC_TA_FLAG: time alarm flag.
* - RTC_OVF_FLAG: overflow flag.
* @retval state of rtc flag
*/
flag_status rtc_interrupt_flag_get(uint16_t flag)
{
flag_status status = RESET;
if (((RTC->ctrll & flag) != (uint16_t)RESET) && ((RTC->ctrlh & flag) != (uint16_t)RESET))
{
status = SET;
}
else
{
status = RESET;
}
return status;
}
/**
* @brief rtc flag clear
* @param interrupt_flag
* this parameter can be any combination of the following values:
* - RTC_TS_FLAG: time second flag.
* - RTC_TA_FLAG: time alarm flag.
* - RTC_OVF_FLAG: overflow flag.
* - RTC_UPDF_FLAG: rtc update finish flag.
* @retval none
*/
void rtc_flag_clear(uint16_t flag)
{
RTC->ctrll = ~(flag | 0x10) | (RTC->ctrll_bit.cfgen << 4);
}
/**
* @brief rtc wait configuration finish
* @param none
* @retval none
*/
void rtc_wait_config_finish(void)
{
while (RTC->ctrll_bit.cfgf == 0);
}
/**
* @brief rtc wait update finish
* @param none
* @retval none
*/
void rtc_wait_update_finish(void)
{
while (RTC->ctrll_bit.updf == 0);
}
/**
* @}
*/
#endif
/**
* @}
*/
/**
* @}
*/

View File

@@ -0,0 +1,617 @@
/**
**************************************************************************
* @file at32f413_sdio.c
* @brief contains all the functions for the sdio 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 "at32f413_conf.h"
/** @addtogroup AT32F413_periph_driver
* @{
*/
/** @defgroup SDIO
* @brief SDIO driver modules
* @{
*/
#ifdef SDIO_MODULE_ENABLED
/** @defgroup SDIO_private_functions
* @{
*/
/**
* @brief reset the sdio register
* @param sdio_x: to select the sdio peripheral.
* this parameter can be one of the following values:
* SDIO1.
* @retval none
*/
void sdio_reset(sdio_type *sdio_x)
{
sdio_x->pwrctrl = 0x0;
sdio_x->clkctrl = 0x0;
sdio_x->argu = 0x0;
sdio_x->cmdctrl = 0x0;
sdio_x->dttmr = 0x0;
sdio_x->dtlen = 0x0;
sdio_x->dtctrl = 0x0;
sdio_x->inten = 0x0;
sdio_x->intclr = 0x004007FF;
}
/**
* @brief set the power status of the controller
* @param sdio_x: to select the sdio peripheral.
* this parameter can be one of the following values:
* SDIO1.
* @param power_state
* this parameter can be one of the following values:
* - SDIO_POWER_OFF
* - SDIO_POWER_ON
* @retval none
*/
void sdio_power_set(sdio_type *sdio_x, sdio_power_state_type power_state)
{
sdio_x->pwrctrl_bit.ps = power_state;
}
/**
* @brief get power status.
* @param sdio_x: to select the sdio peripheral.
* this parameter can be one of the following values:
* SDIO1.
* @retval sdio_power_state_type (SDIO_POWER_ON or SDIO_POWER_OFF)
*/
sdio_power_state_type sdio_power_status_get(sdio_type *sdio_x)
{
return (sdio_power_state_type)(sdio_x->pwrctrl_bit.ps);
}
/**
* @brief config sdio clock
* @param sdio_x: to select the sdio peripheral.
* this parameter can be one of the following values:
* SDIO1.
* @param clk_div: sdio clock divide factor(frequency = sdio_clk / [clk_psc + 2]).
* @param clk_edg
* this parameter can be one of the following values:
* - SDIO_CLOCK_EDGE_RISING
* - SDIO_CLOCK_EDGE_FALLING
* @retval none
*/
void sdio_clock_config(sdio_type *sdio_x, uint16_t clk_div, sdio_edge_phase_type clk_edg)
{
/* config clock edge */
sdio_x->clkctrl_bit.clkegs = clk_edg;
/* config clock divide [7:0] */
sdio_x->clkctrl_bit.clkdiv_l = (clk_div & 0xFF);
/* config clock divide [9:8] */
sdio_x->clkctrl_bit.clkdiv_h = ((clk_div & 0x300) >> 8);
}
/**
* @brief config sdio bus width
* @param sdio_x: to select the sdio peripheral.
* this parameter can be one of the following values:
* SDIO1.
* @param width
* this parameter can be one of the following values:
* - SDIO_BUS_WIDTH_D1
* - SDIO_BUS_WIDTH_D4
* - SDIO_BUS_WIDTH_D8
* @retval none
*/
void sdio_bus_width_config(sdio_type *sdio_x, sdio_bus_width_type width)
{
sdio_x->clkctrl_bit.busws = width;
}
/**
* @brief enable or disable clock divider bypss
* @param sdio_x: to select the sdio peripheral.
* this parameter can be one of the following values:
* SDIO1.
* @param new_state (TRUE or FALSE)
* @retval none
*/
void sdio_clock_bypass(sdio_type *sdio_x, confirm_state new_state)
{
sdio_x->clkctrl_bit.bypsen = new_state;
}
/**
* @brief enable or disable power saving mode, config sdio_ck clock output
* when the bus is idle.
* @param sdio_x: to select the sdio peripheral.
* this parameter can be one of the following values:
* SDIO1.
* @param new_state (TRUE or FALSE)
* @retval none
*/
void sdio_power_saving_mode_enable(sdio_type *sdio_x, confirm_state new_state)
{
sdio_x->clkctrl_bit.pwrsven = new_state;
}
/**
* @brief enable or disable hardware flow control.
* @param sdio_x: to select the sdio peripheral.
* this parameter can be one of the following values:
* SDIO1.
* @param new_state (TRUE or FALSE)
* @retval none
*/
void sdio_flow_control_enable(sdio_type *sdio_x, confirm_state new_state)
{
sdio_x->clkctrl_bit.hfcen = new_state;
}
/**
* @brief enable or disable sdio_ck output.
* @param sdio_x: to select the sdio peripheral.
* this parameter can be one of the following values:
* SDIO1.
* @param new_state (TRUE or FALSE)
* @retval none
*/
void sdio_clock_enable(sdio_type *sdio_x, confirm_state new_state)
{
sdio_x->clkctrl_bit.clkoen = new_state;
}
/**
* @brief enable or disable dma.
* @param sdio_x: to select the sdio peripheral.
* this parameter can be one of the following values:
* SDIO1.
* @param new_state (TRUE or FALSE)
* @retval none
*/
void sdio_dma_enable(sdio_type *sdio_x, confirm_state new_state)
{
sdio_x->dtctrl_bit.dmaen = new_state;
}
/**
* @brief config corresponding interrupt.
* @param sdio_x: to select the sdio peripheral.
* this parameter can be one of the following values:
* SDIO1.
* @param int_opt
* this parameter can be one of the following values:
* - SDIO_CMDFAIL_INT
* - SDIO_DTFAIL_INT
* - SDIO_CMDTIMEOUT_INT
* - SDIO_DTTIMEOUT_INT
* - SDIO_TXERRU_INT
* - SDIO_RXERRO_INT
* - SDIO_CMDRSPCMPL_INT
* - SDIO_CMDCMPL_INT
* - SDIO_DTCMP_INT
* - SDIO_SBITERR_INT
* - SDIO_DTBLKCMPL_INT
* - SDIO_DOCMD_INT
* - SDIO_DOTX_INT
* - SDIO_DORX_INT
* - SDIO_TXBUFH_INT
* - SDIO_RXBUFH_INT
* - SDIO_TXBUFF_INT
* - SDIO_RXBUFF_INT
* - SDIO_TXBUFE_INT
* - SDIO_RXBUFE_INT
* - SDIO_TXBUF_INT
* - SDIO_RXBUF_INT
* - SDIO_SDIOIF_INT
* @param new_state (TRUE or FALSE)
* @retval none
*/
void sdio_interrupt_enable(sdio_type *sdio_x, uint32_t int_opt, confirm_state new_state)
{
/* enable interrupt */
if(TRUE == new_state)
{
sdio_x->inten |= int_opt;
}
/* disable interrupt */
else
{
sdio_x->inten &= ~(int_opt);
}
}
/**
* @brief get sdio interrupt flag.
* @param sdio_x: to select the sdio peripheral.
* this parameter can be one of the following values:
* SDIO1.
* @param flag
* this parameter can be one of the following values:
* - SDIO_CMDFAIL_FLAG
* - SDIO_DTFAIL_FLAG
* - SDIO_CMDTIMEOUT_FLAG
* - SDIO_DTTIMEOUT_FLAG
* - SDIO_TXERRU_FLAG
* - SDIO_RXERRO_FLAG
* - SDIO_CMDRSPCMPL_FLAG
* - SDIO_CMDCMPL_FLAG
* - SDIO_DTCMPL_FLAG
* - SDIO_SBITERR_FLAG
* - SDIO_DTBLKCMPL_FLAG
* - SDIO_DOCMD_FLAG
* - SDIO_DOTX_FLAG
* - SDIO_DORX_FLAG
* - SDIO_TXBUFH_FLAG
* - SDIO_RXBUFH_FLAG
* - SDIO_TXBUFF_FLAG
* - SDIO_RXBUFF_FLAG
* - SDIO_TXBUFE_FLAG
* - SDIO_RXBUFE_FLAG
* - SDIO_TXBUF_FLAG
* - SDIO_RXBUF_FLAG
* - SDIO_SDIOIF_FLAG
* @retval flag_status (SET or RESET)
*/
flag_status sdio_interrupt_flag_get(sdio_type *sdio_x, uint32_t flag)
{
flag_status status = RESET;
if((sdio_x->inten & flag) && (sdio_x->sts & flag))
{
status = SET;
}
return status;
}
/**
* @brief get sdio flag.
* @param sdio_x: to select the sdio peripheral.
* this parameter can be one of the following values:
* SDIO1.
* @param flag
* this parameter can be one of the following values:
* - SDIO_CMDFAIL_FLAG
* - SDIO_DTFAIL_FLAG
* - SDIO_CMDTIMEOUT_FLAG
* - SDIO_DTTIMEOUT_FLAG
* - SDIO_TXERRU_FLAG
* - SDIO_RXERRO_FLAG
* - SDIO_CMDRSPCMPL_FLAG
* - SDIO_CMDCMPL_FLAG
* - SDIO_DTCMPL_FLAG
* - SDIO_SBITERR_FLAG
* - SDIO_DTBLKCMPL_FLAG
* - SDIO_DOCMD_FLAG
* - SDIO_DOTX_FLAG
* - SDIO_DORX_FLAG
* - SDIO_TXBUFH_FLAG
* - SDIO_RXBUFH_FLAG
* - SDIO_TXBUFF_FLAG
* - SDIO_RXBUFF_FLAG
* - SDIO_TXBUFE_FLAG
* - SDIO_RXBUFE_FLAG
* - SDIO_TXBUF_FLAG
* - SDIO_RXBUF_FLAG
* - SDIO_SDIOIF_FLAG
* @retval flag_status (SET or RESET)
*/
flag_status sdio_flag_get(sdio_type *sdio_x, uint32_t flag)
{
flag_status status = RESET;
if((sdio_x->sts & flag) == flag)
{
status = SET;
}
else
{
status = RESET;
}
return status;
}
/**
* @brief clear sdio flag.
* @param sdio_x: to select the sdio peripheral.
* this parameter can be one of the following values:
* SDIO1.
* @param int_opt
* this parameter can be any combination of the following values:
* - SDIO_CMDFAIL_FLAG
* - SDIO_DTFAIL_FLAG
* - SDIO_CMDTIMEOUT_FLAG
* - SDIO_DTTIMEOUT_FLAG
* - SDIO_TXERRU_FLAG
* - SDIO_RXERRO_FLAG
* - SDIO_CMDRSPCMPL_FLAG
* - SDIO_CMDCMPL_FLAG
* - SDIO_DTCMPL_FLAG
* - SDIO_SBITERR_FLAG
* - SDIO_DTBLKCMPL_FLAG
* - SDIO_SDIOIF_FLAG
* @retval none
*/
void sdio_flag_clear(sdio_type *sdio_x, uint32_t flag)
{
sdio_x->intclr = flag;
}
/**
* @brief config sdio command.
* @param sdio_x: to select the sdio peripheral.
* this parameter can be one of the following values:
* SDIO1.
* @param command_struct : pointer to a sdio_command_struct_type structure
* that contains the configuration information for the sdio command.
* @retval none
*/
void sdio_command_config(sdio_type *sdio_x, sdio_command_struct_type *command_struct)
{
/* disable command path state machine */
sdio_x->cmdctrl_bit.ccsmen = FALSE;
/* config command argument */
sdio_x->argu = command_struct->argument;
/* config command register */
sdio_x->cmdctrl_bit.cmdidx = command_struct->cmd_index;
sdio_x->cmdctrl_bit.rspwt = command_struct->rsp_type;
sdio_x->cmdctrl_bit.intwt = (command_struct->wait_type & 0x1); /* [1:0] -> [0] */
sdio_x->cmdctrl_bit.pndwt = (command_struct->wait_type & 0x2)>>1; /* [1:0] -> [1] */
}
/**
* @brief enable or disable command path state machine(CPSM).
* @param sdio_x: to select the sdio peripheral.
* this parameter can be one of the following values:
* SDIO1.
* @param new_state (TRUE or FALSE)
* @retval none
*/
void sdio_command_state_machine_enable(sdio_type *sdio_x, confirm_state new_state)
{
sdio_x->cmdctrl_bit.ccsmen = new_state;
}
/**
* @brief get command index of last command for which response received.
* @param sdio_x: to select the sdio peripheral.
* this parameter can be one of the following values:
* SDIO1.
* @param new_state (TRUE or FALSE)
* @retval uint8_t: command index
*/
uint8_t sdio_command_response_get(sdio_type *sdio_x)
{
return sdio_x->rspcmd_bit.rspcmd;
}
/**
* @brief get response received from the card for the last command.
* @param sdio_x: to select the sdio peripheral.
* this parameter can be one of the following values:
* SDIO1.
* @param reg_index
* this parameter can be one of the following values:
* - SDIO_RSP1_INDEX
* - SDIO_RSP2_INDEX
* - SDIO_RSP3_INDEX
* - SDIO_RSP4_INDEX
* @retval uint32_t: response register value
*/
uint32_t sdio_response_get(sdio_type *sdio_x, sdio_rsp_index_type reg_index)
{
uint32_t response_value = 0;
switch(reg_index)
{
case SDIO_RSP1_INDEX:
response_value = sdio_x->rsp1;
break;
case SDIO_RSP2_INDEX:
response_value = sdio_x->rsp2;
break;
case SDIO_RSP3_INDEX:
response_value = sdio_x->rsp3;
break;
case SDIO_RSP4_INDEX:
response_value = sdio_x->rsp4;
break;
default: break;
}
return response_value;
}
/**
* @brief config sdio data.
* @param sdio_x: to select the sdio peripheral.
* this parameter can be one of the following values:
* SDIO1.
* @param data_struct : pointer to a sdio_data_struct_type structure
* that contains the configuration information for the sdio data.
* @retval none
*/
void sdio_data_config(sdio_type *sdio_x, sdio_data_struct_type *data_struct)
{
/* disable data path state machine */
sdio_x->dtctrl_bit.tfren = FALSE;
/* config data block, transfer mode and transfer direction */
sdio_x->dtctrl_bit.blksize = data_struct->block_size;
sdio_x->dtctrl_bit.tfrdir = data_struct->transfer_direction;
sdio_x->dtctrl_bit.tfrmode = data_struct->transfer_mode;
/* config data length */
sdio_x->dtlen_bit.dtlen = data_struct->data_length;
/* config data transfer timeout */
sdio_x->dttmr_bit.timeout = data_struct->timeout;
}
/**
* @brief enable or disable data path state machine(DPSM).
* @param sdio_x: to select the sdio peripheral.
* this parameter can be one of the following values:
* SDIO1.
* @param new_state (TRUE or FALSE)
* @retval none
*/
void sdio_data_state_machine_enable(sdio_type *sdio_x, confirm_state new_state)
{
sdio_x->dtctrl_bit.tfren = new_state;
}
/**
* @brief get the number of remaining data bytes to be transferred.
* @param sdio_x: to select the sdio peripheral.
* this parameter can be one of the following values:
* SDIO1.
* @retval uint32_t: number of bytes
*/
uint32_t sdio_data_counter_get(sdio_type *sdio_x)
{
return sdio_x->dtcnt;
}
/**
* @brief read a word data from sdio fifo.
* @param sdio_x: to select the sdio peripheral.
* this parameter can be one of the following values:
* SDIO1.
* @retval uint32_t: data received
*/
uint32_t sdio_data_read(sdio_type *sdio_x)
{
return sdio_x->buf;
}
/**
* @brief get the number of words left to be written to or read from fifo..
* @param sdio_x: to select the sdio peripheral.
* this parameter can be one of the following values:
* SDIO1.
* @retval uint32_t: number of words
*/
uint32_t sdio_buffer_counter_get(sdio_type *sdio_x)
{
return sdio_x->bufcnt;
}
/**
* @brief write one word data to fifo.
* @param sdio_x: to select the sdio peripheral.
* this parameter can be one of the following values:
* SDIO1.
* @param data: data to be transferred.
* @retval none
*/
void sdio_data_write(sdio_type *sdio_x, uint32_t data)
{
sdio_x->buf = data;
}
/**
* @brief set the read wait mode.
* @param sdio_x: to select the sdio peripheral.
* this parameter can be one of the following values:
* SDIO1.
* @param mode
* this parameter can be one of the following values:
* - SDIO_READ_WAIT_CONTROLLED_BY_D2
* - SDIO_READ_WAIT_CONTROLLED_BY_CK
* @retval none
*/
void sdio_read_wait_mode_set(sdio_type *sdio_x, sdio_read_wait_mode_type mode)
{
sdio_x->dtctrl_bit.rdwtmode = mode;
}
/**
* @brief enable or disable to start sd i/o read wait operation.
* @param sdio_x: to select the sdio peripheral.
* this parameter can be one of the following values:
* SDIO1.
* @param new_state (TRUE or FALSE)
* @retval none
*/
void sdio_read_wait_start(sdio_type *sdio_x, confirm_state new_state)
{
sdio_x->dtctrl_bit.rdwtstart = new_state;
}
/**
* @brief enable or disable to stop sd i/o read wait operation.
* @param sdio_x: to select the sdio peripheral.
* this parameter can be one of the following values:
* SDIO1.
* @param new_state (TRUE or FALSE)
* @retval none
*/
void sdio_read_wait_stop(sdio_type *sdio_x, confirm_state new_state)
{
sdio_x->dtctrl_bit.rdwtstop = new_state;
}
/**
* @brief enable or disable the sd i/o function.
* @param sdio_x: to select the sdio peripheral.
* this parameter can be one of the following values:
* SDIO1.
* @param new_state (TRUE or FALSE)
* @retval none
*/
void sdio_io_function_enable(sdio_type *sdio_x, confirm_state new_state)
{
sdio_x->dtctrl_bit.ioen = new_state;
}
/**
* @brief enable or disable sd i/o suspend command sending.
* @param sdio_x: to select the sdio peripheral.
* this parameter can be one of the following values:
* SDIO1.
* @param new_state (TRUE or FALSE)
* @retval none
*/
void sdio_io_suspend_command_set(sdio_type *sdio_x, confirm_state new_state)
{
sdio_x->cmdctrl_bit.iosusp = new_state;
}
/**
* @}
*/
#endif
/**
* @}
*/
/**
* @}
*/

View File

@@ -0,0 +1,673 @@
/**
**************************************************************************
* @file at32f413_spi.c
* @brief contains all the functions for the spi 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 "at32f413_conf.h"
/** @addtogroup AT32F413_periph_driver
* @{
*/
/** @defgroup SPI
* @brief SPI driver modules
* @{
*/
#ifdef SPI_MODULE_ENABLED
/** @defgroup SPI_private_functions
* @{
*/
/**
* @brief spi reset by crm reset register
* @param spi_x: select the spi peripheral.
* this parameter can be one of the following values:
* SPI1, SPI2
* @retval none
*/
void spi_i2s_reset(spi_type *spi_x)
{
if(spi_x == SPI1)
{
crm_periph_reset(CRM_SPI1_PERIPH_RESET, TRUE);
crm_periph_reset(CRM_SPI1_PERIPH_RESET, FALSE);
}
else if(spi_x == SPI2)
{
crm_periph_reset(CRM_SPI2_PERIPH_RESET, TRUE);
crm_periph_reset(CRM_SPI2_PERIPH_RESET, FALSE);
}
}
/**
* @brief spi init config with its default value.
* @param spi_init_struct : pointer to a spi_init_type structure which will
* be initialized.
* @retval none
*/
void spi_default_para_init(spi_init_type* spi_init_struct)
{
spi_init_struct->transmission_mode = SPI_TRANSMIT_FULL_DUPLEX;
spi_init_struct->master_slave_mode = SPI_MODE_SLAVE;
spi_init_struct->mclk_freq_division = SPI_MCLK_DIV_2;
spi_init_struct->first_bit_transmission = SPI_FIRST_BIT_MSB;
spi_init_struct->frame_bit_num = SPI_FRAME_8BIT;
spi_init_struct->clock_polarity = SPI_CLOCK_POLARITY_LOW;
spi_init_struct->clock_phase = SPI_CLOCK_PHASE_1EDGE;
spi_init_struct->cs_mode_selection = SPI_CS_SOFTWARE_MODE;
}
/**
* @brief spi init config with its setting value.
* @param spi_x: select the spi peripheral.
* this parameter can be one of the following values:
* SPI1, SPI2
* @param spi_init_struct : pointer to a spi_init_type structure which will be initialized.
* @retval none
*/
void spi_init(spi_type* spi_x, spi_init_type* spi_init_struct)
{
spi_x->i2sctrl_bit.i2smsel = FALSE;
if(spi_init_struct->transmission_mode == SPI_TRANSMIT_FULL_DUPLEX)
{
spi_x->ctrl1_bit.slben = FALSE;
spi_x->ctrl1_bit.slbtd = FALSE;
spi_x->ctrl1_bit.ora = FALSE;
}
else if(spi_init_struct->transmission_mode == SPI_TRANSMIT_SIMPLEX_RX)
{
spi_x->ctrl1_bit.slben = FALSE;
spi_x->ctrl1_bit.slbtd = FALSE;
spi_x->ctrl1_bit.ora = TRUE;
}
else if(spi_init_struct->transmission_mode == SPI_TRANSMIT_HALF_DUPLEX_RX)
{
spi_x->ctrl1_bit.slben = TRUE;
spi_x->ctrl1_bit.slbtd = FALSE;
spi_x->ctrl1_bit.ora = FALSE;
}
else if(spi_init_struct->transmission_mode == SPI_TRANSMIT_HALF_DUPLEX_TX)
{
spi_x->ctrl1_bit.slben = TRUE;
spi_x->ctrl1_bit.slbtd = TRUE;
spi_x->ctrl1_bit.ora = FALSE;
}
spi_x->ctrl1_bit.swcsen = spi_init_struct->cs_mode_selection;
if((spi_init_struct->master_slave_mode == SPI_MODE_MASTER) && (spi_init_struct->cs_mode_selection == SPI_CS_SOFTWARE_MODE))
{
spi_x->ctrl1_bit.swcsil = TRUE;
}
else
{
spi_x->ctrl1_bit.swcsil = FALSE;
}
spi_x->ctrl1_bit.msten = spi_init_struct->master_slave_mode;
if(spi_init_struct->mclk_freq_division > SPI_MCLK_DIV_256)
{
spi_x->ctrl2_bit.mdiv_h = 1;
spi_x->ctrl1_bit.mdiv_l = spi_init_struct->mclk_freq_division & 0x7;
}
else
{
spi_x->ctrl2_bit.mdiv_h = 0;
spi_x->ctrl1_bit.mdiv_l = spi_init_struct->mclk_freq_division;
}
spi_x->ctrl1_bit.ltf = spi_init_struct->first_bit_transmission;
spi_x->ctrl1_bit.fbn = spi_init_struct->frame_bit_num;
spi_x->ctrl1_bit.clkpol = spi_init_struct->clock_polarity;
spi_x->ctrl1_bit.clkpha = spi_init_struct->clock_phase;
}
/**
* @brief spi next transmit crc for the spi peripheral.
* @param spi_x: select the spi peripheral.
* this parameter can be one of the following values:
* SPI1, SPI2
* @retval none
*/
void spi_crc_next_transmit(spi_type* spi_x)
{
spi_x->ctrl1_bit.ntc = TRUE;
}
/**
* @brief set the crc polynomial value for the spi peripheral.
* @param spi_x: select the spi peripheral.
* this parameter can be one of the following values:
* SPI1, SPI2
* @param crc_poly: crc polynomial value.
* @retval none
*/
void spi_crc_polynomial_set(spi_type* spi_x, uint16_t crc_poly)
{
spi_x->cpoly_bit.cpoly = crc_poly;
}
/**
* @brief return the crc polynomial register value for the spi peripheral.
* @param spi_x: select the spi peripheral.
* this parameter can be one of the following values:
* SPI1, SPI2
* @retval the select crc polynomial register value
*/
uint16_t spi_crc_polynomial_get(spi_type* spi_x)
{
return spi_x->cpoly_bit.cpoly;
}
/**
* @brief enable or disable the hardware crc calculation for the spi peripheral.
* @param spi_x: select the spi peripheral.
* this parameter can be one of the following values:
* SPI1, SPI2
* @param new_state: new state of crc calculation.
* this parameter can be: TRUE or FALSE.
* @retval none
*/
void spi_crc_enable(spi_type* spi_x, confirm_state new_state)
{
spi_x->ctrl1_bit.ccen = new_state;
}
/**
* @brief return the transmit or the receive crc value for the spi peripheral.
* @param spi_x: select the spi peripheral.
* this parameter can be one of the following values:
* SPI1, SPI2
* @param crc_direction: select transmit or receive crc value to be read
* - SPI_CRC_RX
* - SPI_CRC_TX
* @retval the select crc register value
*/
uint16_t spi_crc_value_get(spi_type* spi_x, spi_crc_direction_type crc_direction)
{
if(crc_direction == SPI_CRC_RX)
return spi_x->rcrc_bit.rcrc;
else
return spi_x->tcrc_bit.tcrc;
}
/**
* @brief enable or disable the hardware cs output for the spi peripheral.
* @param spi_x: select the spi peripheral.
* this parameter can be one of the following values:
* SPI1, SPI2
* @param new_state: new state of spi master cs output.
* this parameter can be: TRUE or FALSE.
* note:the bit only use in spi master mode
* @retval none
*/
void spi_hardware_cs_output_enable(spi_type* spi_x, confirm_state new_state)
{
spi_x->ctrl2_bit.hwcsoe = new_state;
}
/**
* @brief set the software cs internal level for the spi peripheral.
* @param spi_x: select the spi peripheral.
* this parameter can be one of the following values:
* SPI1, SPI2
* @param level: set the state of spi cs level.
* this parameter can be one of the following values:
* - SPI_SWCS_INTERNAL_LEVEL_LOW
* - SPI_SWCS_INTERNAL_LEVEL_HIGHT
* note:the bit only use when swcsen bit is set.
* note:when use this bit,io operation on the cs pin are invalid.
* @retval none
*/
void spi_software_cs_internal_level_set(spi_type* spi_x, spi_software_cs_level_type level)
{
spi_x->ctrl1_bit.swcsil = level;
}
/**
* @brief set the data frame bit num for the spi peripheral.
* @param spi_x: select the spi peripheral.
* this parameter can be one of the following values:
* SPI1, SPI2
* @param bit_num: set the data frame size
* - SPI_FRAME_8BIT
* - SPI_FRAME_16BIT
* @retval none
*/
void spi_frame_bit_num_set(spi_type* spi_x, spi_frame_bit_num_type bit_num)
{
spi_x->ctrl1_bit.fbn = bit_num;
}
/**
* @brief set the data transmission direction in single line bidirectiona half duplex mode of the spi peripheral.
* @param spi_x: select the spi peripheral.
* this parameter can be one of the following values:
* SPI1, SPI2
* @param direction: data transfer direction
* this parameter can be one of the following values:
* - SPI_HALF_DUPLEX_DIRECTION_RX
* - SPI_HALF_DUPLEX_DIRECTION_TX
* @retval none
*/
void spi_half_duplex_direction_set(spi_type* spi_x, spi_half_duplex_direction_type direction)
{
spi_x->ctrl1_bit.slbtd = direction;
}
/**
* @brief enable or disable spi.
* @param spi_x: select the spi peripheral.
* this parameter can be one of the following values:
* SPI1, SPI2
* @param new_state: new state of spi.
* this parameter can be: TRUE or FALSE.
* @retval none
*/
void spi_enable(spi_type* spi_x, confirm_state new_state)
{
spi_x->ctrl1_bit.spien = new_state;
}
/**
* @brief i2s init config with its default value.
* @param i2s_init_struct : pointer to a i2s_init_type structure which will
* be initialized.
* @retval none
*/
void i2s_default_para_init(i2s_init_type* i2s_init_struct)
{
i2s_init_struct->operation_mode = I2S_MODE_SLAVE_TX;
i2s_init_struct->audio_protocol = I2S_AUDIO_PROTOCOL_PHILLIPS;
i2s_init_struct->audio_sampling_freq = I2S_AUDIO_FREQUENCY_DEFAULT;
i2s_init_struct->data_channel_format = I2S_DATA_16BIT_CHANNEL_16BIT;
i2s_init_struct->clock_polarity = I2S_CLOCK_POLARITY_LOW;
i2s_init_struct->mclk_output_enable = FALSE;
}
/**
* @brief i2s init config with its setting value.
* @param spi_x: select the spi peripheral.
* this parameter can be one of the following values:
* SPI1, SPI2
* @param i2s_init_struct : pointer to a i2s_init_type structure which will be initialized.
* @retval none
*/
void i2s_init(spi_type* spi_x, i2s_init_type* i2s_init_struct)
{
crm_clocks_freq_type clocks_freq;
uint32_t i2s_sclk_index = 0;
uint32_t i2sdiv_index = 2, i2sodd_index = 0, frequency_index = 0;
/* i2s audio frequency config */
if(i2s_init_struct->audio_sampling_freq == I2S_AUDIO_FREQUENCY_DEFAULT)
{
i2sodd_index = 0;
i2sdiv_index = 2;
}
else
{
crm_clocks_freq_get(&clocks_freq);
i2s_sclk_index = clocks_freq.sclk_freq;
if((i2s_init_struct->audio_protocol == I2S_AUDIO_PROTOCOL_PCM_SHORT) || (i2s_init_struct->audio_protocol == I2S_AUDIO_PROTOCOL_PCM_LONG))
{
if(i2s_init_struct->mclk_output_enable == TRUE)
{
frequency_index = (((i2s_sclk_index / 128) * 10) / i2s_init_struct->audio_sampling_freq) + 5;
}
else
{
if(i2s_init_struct->data_channel_format == I2S_DATA_16BIT_CHANNEL_16BIT)
frequency_index = (((i2s_sclk_index / 16) * 10) / i2s_init_struct->audio_sampling_freq) + 5;
else
frequency_index = (((i2s_sclk_index / 32) * 10) / i2s_init_struct->audio_sampling_freq) + 5;
}
}
else
{
if(i2s_init_struct->mclk_output_enable == TRUE)
{
frequency_index = (((i2s_sclk_index / 256) * 10) / i2s_init_struct->audio_sampling_freq) + 5;
}
else
{
if(i2s_init_struct->data_channel_format == I2S_DATA_16BIT_CHANNEL_16BIT)
frequency_index = (((i2s_sclk_index / 32) * 10) / i2s_init_struct->audio_sampling_freq) + 5;
else
frequency_index = (((i2s_sclk_index / 64) * 10) / i2s_init_struct->audio_sampling_freq) + 5;
}
}
}
frequency_index = frequency_index / 10;
i2sodd_index = frequency_index & (uint16_t)0x0001;
i2sdiv_index = (frequency_index - i2sodd_index) / 2;
if((i2sdiv_index < 2) || (i2sdiv_index > 0x03FF))
{
i2sodd_index = 0;
i2sdiv_index = 2;
}
spi_x->i2sclk_bit.i2sodd = i2sodd_index;
if(i2sdiv_index > 0x00FF)
{
spi_x->i2sclk_bit.i2sdiv_h = (i2sdiv_index >> 8) & 0x0003;
spi_x->i2sclk_bit.i2sdiv_l = i2sdiv_index & 0x00FF;
}
else
{
spi_x->i2sclk_bit.i2sdiv_h = 0;
spi_x->i2sclk_bit.i2sdiv_l = i2sdiv_index;
}
/* i2s audio_protocol set*/
if(i2s_init_struct->audio_protocol == I2S_AUDIO_PROTOCOL_PCM_LONG)
{
spi_x->i2sctrl_bit.pcmfssel = 1;
spi_x->i2sctrl_bit.stdsel = 3;
}
else if(i2s_init_struct->audio_protocol == I2S_AUDIO_PROTOCOL_PCM_SHORT)
{
spi_x->i2sctrl_bit.pcmfssel = 0;
spi_x->i2sctrl_bit.stdsel = 3;
}
else if(i2s_init_struct->audio_protocol == I2S_AUDIO_PROTOCOL_LSB)
{
spi_x->i2sctrl_bit.pcmfssel = 0;
spi_x->i2sctrl_bit.stdsel = 2;
}
else if(i2s_init_struct->audio_protocol == I2S_AUDIO_PROTOCOL_MSB)
{
spi_x->i2sctrl_bit.pcmfssel = 0;
spi_x->i2sctrl_bit.stdsel = 1;
}
else if(i2s_init_struct->audio_protocol == I2S_AUDIO_PROTOCOL_PHILLIPS)
{
spi_x->i2sctrl_bit.pcmfssel = 0;
spi_x->i2sctrl_bit.stdsel = 0;
}
/* i2s data_channel_format set*/
if(i2s_init_struct->data_channel_format == I2S_DATA_16BIT_CHANNEL_16BIT)
{
spi_x->i2sctrl_bit.i2scbn = 0;
spi_x->i2sctrl_bit.i2sdbn = 0;
}
else if(i2s_init_struct->data_channel_format == I2S_DATA_16BIT_CHANNEL_32BIT)
{
spi_x->i2sctrl_bit.i2scbn = 1;
spi_x->i2sctrl_bit.i2sdbn = 0;
}
else if(i2s_init_struct->data_channel_format == I2S_DATA_24BIT_CHANNEL_32BIT)
{
spi_x->i2sctrl_bit.i2scbn = 1;
spi_x->i2sctrl_bit.i2sdbn = 1;
}
else if(i2s_init_struct->data_channel_format == I2S_DATA_32BIT_CHANNEL_32BIT)
{
spi_x->i2sctrl_bit.i2scbn = 1;
spi_x->i2sctrl_bit.i2sdbn = 2;
}
spi_x->i2sctrl_bit.i2sclkpol = i2s_init_struct->clock_polarity;
spi_x->i2sclk_bit.i2smclkoe = i2s_init_struct->mclk_output_enable;
spi_x->i2sctrl_bit.opersel = i2s_init_struct->operation_mode;
spi_x->i2sctrl_bit.i2smsel = TRUE;
}
/**
* @brief enable or disable i2s.
* @param spi_x: select the i2s peripheral.
* this parameter can be one of the following values:
* SPI1, SPI2
* @param new_state: new state of i2s.
* this parameter can be: TRUE or FALSE.
* @retval none
*/
void i2s_enable(spi_type* spi_x, confirm_state new_state)
{
spi_x->i2sctrl_bit.i2sen = new_state;
}
/**
* @brief enable or disable the specified spi/i2s interrupts.
* @param spi_x: select the spi/i2s peripheral.
* this parameter can be one of the following values:
* SPI1, SPI2
* @param spi_i2s_int: specifies the spi/i2s interrupt sources to be enabled or disabled.
* this parameter can be one of the following values:
* - SPI_I2S_ERROR_INT
* - SPI_I2S_RDBF_INT
* - SPI_I2S_TDBE_INT
* @param new_state: new state of the specified spi/i2s interrupts.
* this parameter can be: TRUE or FALSE.
* @retval none
*/
void spi_i2s_interrupt_enable(spi_type* spi_x, uint32_t spi_i2s_int, confirm_state new_state)
{
if(new_state != FALSE)
{
spi_x->ctrl2 |= spi_i2s_int;
}
else
{
spi_x->ctrl2 &= ~spi_i2s_int;
}
}
/**
* @brief enable or disable the spi/i2s dma transmitter mode.
* @param spi_x: select the spi/i2s peripheral.
* this parameter can be one of the following values:
* SPI1, SPI2
* @param new_state: new state of the dma request.
* this parameter can be: TRUE or FALSE.
* @retval none
*/
void spi_i2s_dma_transmitter_enable(spi_type* spi_x, confirm_state new_state)
{
spi_x->ctrl2_bit.dmaten = new_state;
}
/**
* @brief enable or disable the spi/i2s dma receiver mode.
* @param spi_x: select the spi/i2s peripheral.
* this parameter can be one of the following values:
* SPI1, SPI2
* @param new_state: new state of the dma request.
* this parameter can be: TRUE or FALSE.
* @retval none
*/
void spi_i2s_dma_receiver_enable(spi_type* spi_x, confirm_state new_state)
{
spi_x->ctrl2_bit.dmaren = new_state;
}
/**
* @brief spi/i2s data transmit
* @param spi_x: select the spi/i2s peripheral.
* this parameter can be one of the following values:
* SPI1, SPI2
* @param tx_data: the data to be transmit.
* this parameter can be:
* - (0x0000~0xFFFF)
* @retval none
*/
void spi_i2s_data_transmit(spi_type* spi_x, uint16_t tx_data)
{
spi_x->dt = tx_data;
}
/**
* @brief spi/i2s data receive
* @param spi_x: select the spi/i2s peripheral.
* this parameter can be one of the following values:
* SPI1, SPI2
* @retval the received data value
*/
uint16_t spi_i2s_data_receive(spi_type* spi_x)
{
return (uint16_t)spi_x->dt;
}
/**
* @brief get flag of the specified spi/i2s peripheral.
* @param spi_x: select the spi/i2s peripheral.
* this parameter can be one of the following values:
* SPI1, SPI2
* @param spi_i2s_flag: select the spi/i2s flag
* this parameter can be one of the following values:
* - SPI_I2S_RDBF_FLAG
* - SPI_I2S_TDBE_FLAG
* - I2S_ACS_FLAG (this flag only use in i2s mode)
* - I2S_TUERR_FLAG (this flag only use in i2s mode)
* - SPI_CCERR_FLAG (this flag only use in spi mode)
* - SPI_MMERR_FLAG (this flag only use in spi mode)
* - SPI_I2S_ROERR_FLAG
* - SPI_I2S_BF_FLAG
* @retval the new state of spi/i2s flag
*/
flag_status spi_i2s_flag_get(spi_type* spi_x, uint32_t spi_i2s_flag)
{
flag_status status = RESET;
if ((spi_x->sts & spi_i2s_flag) == RESET)
{
status = RESET;
}
else
{
status = SET;
}
return status;
}
/**
* @brief get interrupt flag of the specified spi/i2s peripheral.
* @param spi_x: select the spi/i2s peripheral.
* this parameter can be one of the following values:
* SPI1, SPI2
* @param spi_i2s_flag: select the spi/i2s flag
* this parameter can be one of the following values:
* - SPI_I2S_RDBF_FLAG
* - SPI_I2S_TDBE_FLAG
* - I2S_TUERR_FLAG (this flag only use in i2s mode)
* - SPI_CCERR_FLAG (this flag only use in spi mode)
* - SPI_MMERR_FLAG (this flag only use in spi mode)
* - SPI_I2S_ROERR_FLAG
* @retval the new state of spi/i2s flag
*/
flag_status spi_i2s_interrupt_flag_get(spi_type* spi_x, uint32_t spi_i2s_flag)
{
flag_status status = RESET;
switch(spi_i2s_flag)
{
case SPI_I2S_RDBF_FLAG:
if(spi_x->sts_bit.rdbf && spi_x->ctrl2_bit.rdbfie)
{
status = SET;
}
break;
case SPI_I2S_TDBE_FLAG:
if(spi_x->sts_bit.tdbe && spi_x->ctrl2_bit.tdbeie)
{
status = SET;
}
break;
case I2S_TUERR_FLAG:
if(spi_x->sts_bit.tuerr && spi_x->ctrl2_bit.errie)
{
status = SET;
}
break;
case SPI_CCERR_FLAG:
if(spi_x->sts_bit.ccerr && spi_x->ctrl2_bit.errie)
{
status = SET;
}
break;
case SPI_MMERR_FLAG:
if(spi_x->sts_bit.mmerr && spi_x->ctrl2_bit.errie)
{
status = SET;
}
break;
case SPI_I2S_ROERR_FLAG:
if(spi_x->sts_bit.roerr && spi_x->ctrl2_bit.errie)
{
status = SET;
}
break;
default:
break;
};
return status;
}
/**
* @brief clear flag of the specified spi/i2s peripheral.
* @param spi_x: select the spi/i2s peripheral.
* this parameter can be one of the following values:
* SPI1, SPI2
* @param spi_i2s_flag: select the spi/i2s flag
* this parameter can be one of the following values:
* - SPI_CCERR_FLAG
* - SPI_I2S_RDBF_FLAG
* - I2S_TUERR_FLAG
* - SPI_MMERR_FLAG
* - SPI_I2S_ROERR_FLAG
* @note
* SPI_I2S_TDBE_FLAG this flag is cleared when the tx buffer already contain data to be transmit.
* I2S_ACS_FLAG this flag cann't cleared by software,the flag indicate the channel side(not use in pcm standard mode).
* SPI_I2S_BF_FLAG this flag cann't cleared by software, it's set and cleared by hardware.
* @retval none
*/
void spi_i2s_flag_clear(spi_type* spi_x, uint32_t spi_i2s_flag)
{
if(spi_i2s_flag == SPI_CCERR_FLAG)
spi_x->sts = ~SPI_CCERR_FLAG;
else if(spi_i2s_flag == SPI_I2S_RDBF_FLAG)
UNUSED(spi_x->dt);
else if(spi_i2s_flag == I2S_TUERR_FLAG)
UNUSED(spi_x->sts);
else if(spi_i2s_flag == SPI_MMERR_FLAG)
{
UNUSED(spi_x->sts);
spi_x->ctrl1 = spi_x->ctrl1;
}
else if(spi_i2s_flag == SPI_I2S_ROERR_FLAG)
{
UNUSED(spi_x->dt);
UNUSED(spi_x->sts);
}
}
/**
* @}
*/
#endif
/**
* @}
*/
/**
* @}
*/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,700 @@
/**
**************************************************************************
* @file at32f413_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 "at32f413_conf.h"
/** @addtogroup AT32F413_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 or UART5.
* @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);
}
#if defined (AT32F413Rx) || defined (AT32F413Cx) || defined (AT32FEBKC8T7)
else if(usart_x == USART3)
{
crm_periph_reset(CRM_USART3_PERIPH_RESET, TRUE);
crm_periph_reset(CRM_USART3_PERIPH_RESET, FALSE);
}
#endif
#if defined (AT32F413Rx)
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);
}
#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 or UART5.
* @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)
{
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 or UART5.
* @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 or UART5.
* @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 or UART5.
* @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 or UART5.
* @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 and UART5.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2 or USART3.
* @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 and UART5.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2 or USART3.
* @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 or UART5.
* @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 or UART5.
* @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 or UART5.
* @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 or UART5.
* @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 or UART5.
* @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 or UART5.
* @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 or UART5.
* @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 or UART5.
* @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 or UART5.
* @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 or UART5.
* @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 or UART5.
* @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 and UART5.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2 or USART3.
* @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 and UART5.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2 or USART3.
* @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 and UART5.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2 or USART3.
* @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 and UART5.
* @param usart_x: select the usart or the uart peripheral.
* this parameter can be one of the following values:
* USART1, USART2 or USART3.
* @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 or UART5.
* @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 or UART5.
* @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 or UART5.
* @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 or 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 or UART5.
* @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.
* @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 or UART5.
* @param flag: specifies the flag to clear.
* this parameter can be any combination of the following values:
* - USART_CTSCF_FLAG: (not available for UART4 and UART5).
* - 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
/**
* @}
*/
/**
* @}
*/

View File

@@ -0,0 +1,591 @@
/**
**************************************************************************
* @file at32f413_usb.c
* @brief contains the functions for the usb 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.
*
**************************************************************************
*/
/** @addtogroup AT32F413_periph_driver
* @{
*/
/** @defgroup USB
* @brief USB driver modules
* @{
*/
#include "at32f413_conf.h"
#ifdef USB_MODULE_ENABLED
/** @defgroup USB_private_functions
* @{
*/
/**
* @brief usb packet buffer start address
*/
#define USB_ENDP_DESC_TABLE_OFFSET 0x40
uint32_t g_usb_packet_address = USB_PACKET_BUFFER_ADDRESS;
static uint16_t g_usb_offset_addr = USB_ENDP_DESC_TABLE_OFFSET;
/**
* @brief initialize usb peripheral controller register
* @param usbx: to select the usb peripheral.
* parameter as following values: USB
* @retval none
*/
void usb_dev_init(usbd_type *usbx)
{
/* clear usb core reset */
usbx->ctrl_bit.csrst = 0;
/* clear usb interrupt status */
usbx->intsts = 0;
/* set usb packet buffer descirption table address */
usbx->buftbl = USB_BUFFER_TABLE_ADDRESS;
/* enable usb core and set device address to 0 */
usbx->devaddr = 0x80;
usb_interrupt_enable(usbx, USB_SOF_INT | USB_RST_INT | USB_SP_INT | USB_WK_INT | USB_TC_INT, TRUE);
}
/**
* @brief connect usb device
* @param usbx: to select the usb peripheral.
* parameter as following values: USB
* @retval none
*/
void usb_connect(usbd_type *usbx)
{
/* enable usb phy */
usbx->ctrl_bit.disusb = 0;
}
/**
* @brief disconnect usb device
* @param usbx: to select the usb peripheral.
* parameter as following values: USB
* @retval none
*/
void usb_disconnect(usbd_type *usbx)
{
/* disable usb phy */
usbx->ctrl_bit.disusb = TRUE;
}
/**
* @brief mapping usb packet buffer area
* two mapping intervals are available for packet buffer area,
* and are select by the usbbufs in the crm misc1 register.
* when usbbufs is 0,sram size is 512 bytes, packet buffer start
* address is 0x40006000.when usbbufs is 1, sram size is fixed to
* 768~1280 bytes, and the packet buffer start address is fixed to
* 0x40007800,packet buffer size decided by whether can1 and can2 are
* enabled;when both can1 and can2 are disabled, usb packet buffer can be set to the
* maximum of 1280 bytes; when either can1 or can2 is enabled, usb packet buffer can be set to the
* maximum of 1024 bytes; when both CAN1 and CAN2 are enabled, usb packet buffer can be set to the
* maximum of 768 bytes.
* @param usbx: to select the usb peripheral.
* parameter as following values: USB
* @retval none
*/
void usb_usbbufs_enable(usbd_type *usbx, confirm_state state)
{
if(state == TRUE)
{
/* enable usbbufs */
g_usb_packet_address = USB_PACKET_BUFFER_ADDRESS_EX;
CRM->misc1_bit.usbbufs = TRUE;
}
else
{
/* disable usbbufs */
g_usb_packet_address = USB_PACKET_BUFFER_ADDRESS;
CRM->misc1_bit.usbbufs = FALSE;
}
UNUSED(usbx);
}
/**
* @brief open usb endpoint
* @param usbx: to select the usb peripheral.
* parameter as following values: USB
* @param ept_info: endpoint information structure
* @retval none
*/
void usb_ept_open(usbd_type *usbx, usb_ept_info *ept_info)
{
uint16_t type = 0;
/* set endpoint address */
USB_SET_EPT_ADDRESS(ept_info->eptn, ept_info->ept_address);
/* select endpoint transfer type */
if(ept_info->trans_type == EPT_CONTROL_TYPE)
{
type = USB_EPT_CONTROL;
}
else if(ept_info->trans_type == EPT_BULK_TYPE)
{
type = USB_EPT_BULK;
}
else if(ept_info->trans_type == EPT_INT_TYPE)
{
type = USB_EPT_INT;
}
else if(ept_info->trans_type == EPT_ISO_TYPE)
{
type = USB_EPT_ISO;
ept_info->is_double_buffer = TRUE;
}
/* configure endpoint transfer type (control, bulk, interrupt, isochronous) */
USB_SET_TRANS_TYPE(ept_info->eptn, type);
/* endpoint is in transfer */
if(ept_info->inout == DATA_TRANS_IN)
{
if(ept_info->is_double_buffer == 0)
{
/* set in endpoint tx offset address */
USB_SET_TX_ADDRESS(ept_info->eptn, ept_info->tx_addr);
/* clear in endpoint data toggle */
USB_CLEAR_TXDTS(ept_info->eptn);
/* set endpoint transmission status: nak */
USB_SET_TXSTS(ept_info->eptn, USB_TX_NAK);
}
else
{
/* set double buffer endpoint*/
USB_SET_EPT_DOUBLE_BUFFER(ept_info->eptn);
/* set in endpoint offset address0 and address1 */
USB_SET_DOUBLE_BUFF0_ADDRESS(ept_info->eptn, ept_info->tx_addr);
USB_SET_DOUBLE_BUFF1_ADDRESS(ept_info->eptn, ept_info->rx_addr);
/* clear in and out data toggle */
USB_CLEAR_TXDTS(ept_info->eptn);
USB_CLEAR_RXDTS(ept_info->eptn);
/* toggle rx data toggle flag */
USB_TOGGLE_RXDTS(ept_info->eptn);
/* set endpoint reception status: disable */
USB_SET_RXSTS(ept_info->eptn, USB_RX_DISABLE);
/* set endpoint transmision status: nak */
USB_SET_TXSTS(ept_info->eptn, USB_TX_NAK);
}
}
else
{
if(ept_info->is_double_buffer == 0)
{
/* set out endpoint rx offset address */
USB_SET_RX_ADDRESS(ept_info->eptn, ept_info->rx_addr);
/* clear out endpoint data toggle */
USB_CLEAR_RXDTS(ept_info->eptn);
/* set out endpoint max reception buffer size */
USB_SET_RXLEN(ept_info->eptn, ept_info->maxpacket);
/* set endpoint reception status: valid */
USB_SET_RXSTS(ept_info->eptn, USB_RX_VALID);
}
else
{
/* set double buffer endpoint */
USB_SET_EPT_DOUBLE_BUFFER(ept_info->eptn);
/* set out endpoint offset address0 and address1 */
USB_SET_DOUBLE_BUFF0_ADDRESS(ept_info->eptn, ept_info->tx_addr);
USB_SET_DOUBLE_BUFF1_ADDRESS(ept_info->eptn, ept_info->rx_addr);
/* set out endpoint max reception buffer size */
USB_SET_EPT_DOUBLE_BUF0_LEN(ept_info->eptn, ept_info->maxpacket, DATA_TRANS_OUT);
USB_SET_EPT_DOUBLE_BUF1_LEN(ept_info->eptn, ept_info->maxpacket, DATA_TRANS_OUT);
/* clear in and out data toggle */
USB_CLEAR_TXDTS(ept_info->eptn);
USB_CLEAR_RXDTS(ept_info->eptn);
/* toggle tx data toggle flag */
USB_TOGGLE_TXDTS(ept_info->eptn);
/* set endpoint reception status: valid */
USB_SET_RXSTS(ept_info->eptn, USB_RX_VALID);
/* set endpoint transmision status: disable */
USB_SET_TXSTS(ept_info->eptn, USB_TX_DISABLE);
}
}
UNUSED(usbx);
}
/**
* @brief close usb endpoint
* @param usbx: to select the usb peripheral.
* parameter as following values: USB
* @param ept_info: endpoint information structure
* @retval none
*/
void usb_ept_close(usbd_type *usbx, usb_ept_info *ept_info)
{
if(ept_info->is_double_buffer == 0)
{
if(ept_info->inout == DATA_TRANS_IN)
{
/*clear tx data toggle */
USB_CLEAR_TXDTS(ept_info->eptn);
/* set tx status: disable */
USB_SET_TXSTS(ept_info->eptn, USB_TX_DISABLE);
}
else
{
/*clear rx data toggle */
USB_CLEAR_RXDTS(ept_info->eptn);
/* set rx status: disable */
USB_SET_RXSTS(ept_info->eptn, USB_RX_DISABLE);
}
}
else
{
/* double buffer */
/*clear rx and tx data toggle */
USB_CLEAR_TXDTS(ept_info->eptn);
USB_CLEAR_RXDTS(ept_info->eptn);
if(ept_info->inout == DATA_TRANS_IN)
{
/* toggle tx */
USB_TOGGLE_TXDTS(ept_info->eptn);
/* set tx and rx status: disable */
USB_SET_TXSTS(ept_info->eptn, USB_TX_DISABLE);
USB_SET_RXSTS(ept_info->eptn, USB_RX_DISABLE);
}
else
{
/* toggle rx */
USB_TOGGLE_RXDTS(ept_info->eptn);
/* set tx and rx status: disable */
USB_SET_TXSTS(ept_info->eptn, USB_TX_DISABLE);
USB_SET_RXSTS(ept_info->eptn, USB_RX_DISABLE);
}
}
UNUSED(usbx);
}
/**
* @brief write data from user memory to usb buffer
* @param pusr_buf: point to user buffer
* @param offset_addr: endpoint tx offset address
* @param nbytes: number of bytes data write to usb buffer
* @retval none
*/
void usb_write_packet(uint8_t *pusr_buf, uint16_t offset_addr, uint16_t nbytes)
{
/* endpoint tx buffer address */
__IO uint16_t *d_addr = (__IO uint16_t *)(offset_addr * 2 + g_usb_packet_address);
uint32_t nhbytes = (nbytes + 1) >> 1;
uint32_t n_index;
uint16_t *pbuf = (uint16_t *)pusr_buf;
for(n_index = 0; n_index < nhbytes; n_index ++)
{
#if defined (__ICCARM__) && (__VER__ < 7000000)
*d_addr++ = *(__packed uint16_t *)pbuf;
#else
*d_addr++ = __UNALIGNED_UINT16_READ(pbuf);
#endif
d_addr ++;
pbuf ++;
}
}
/**
* @brief read data from usb buffer to user buffer
* @param pusr_buf: point to user buffer
* @param offset_addr: endpoint rx offset address
* @param nbytes: number of bytes data write to usb buffer
* @retval none
*/
void usb_read_packet(uint8_t *pusr_buf, uint16_t offset_addr, uint16_t nbytes)
{
__IO uint16_t *s_addr = (__IO uint16_t *)(offset_addr * 2 + g_usb_packet_address);
uint32_t nhbytes = (nbytes + 1) >> 1;
uint32_t n_index;
uint16_t *pbuf = (uint16_t *)pusr_buf;
for(n_index = 0; n_index < nhbytes; n_index ++)
{
#if defined (__ICCARM__) && (__VER__ < 7000000)
*(__packed uint16_t *)pbuf = *(__IO uint16_t *)s_addr ++;
#else
__UNALIGNED_UINT16_WRITE(pbuf, *(__IO uint16_t *)s_addr ++);
#endif
s_addr ++;
pbuf ++;
}
}
/**
* @brief usb interrupt enable
* @param usbx: to select the usb peripheral.
* parameter as following values: USB
* @param interrupt:
* this parameter can be any combination of the following values:
* - USB_LSOF_INT
* - USB_SOF_INT
* - USB_RST_INT
* - USB_SP_INT
* - USB_WK_INT
* - USB_BE_INT
* - USB_UCFOR_INT
* - USB_TC_INT
* @param new_state (TRUE or FALSE)
* @retval none
*/
void usb_interrupt_enable(usbd_type *usbx, uint16_t interrupt, confirm_state new_state)
{
if(new_state == TRUE)
{
usbx->ctrl |= interrupt;
}
else
{
usbx->ctrl &= ~interrupt;
}
}
/**
* @brief set the host assignment address
* @param usbx: to select the usb peripheral.
* parameter as following values: USB
* @param address: host assignment address
* @retval none
*/
void usb_set_address(usbd_type *usbx, uint8_t address)
{
usbx->devaddr_bit.addr = address;
usbx->devaddr_bit.cen = TRUE;
}
/**
* @brief set endpoint tx or rx status to stall
* @param usbx: to select the usb peripheral.
* parameter as following values: USB
* @param ept_info: endpoint information structure
* @retval none
*/
void usb_ept_stall(usbd_type *usbx, usb_ept_info *ept_info)
{
if(ept_info->inout == DATA_TRANS_IN)
{
USB_SET_TXSTS(ept_info->eptn, USB_TX_STALL)
}
else
{
USB_SET_RXSTS(ept_info->eptn, USB_RX_STALL)
}
UNUSED(usbx);
}
/**
* @brief usb device enter suspend mode
* @param usbx: to select the usb peripheral.
* parameter as following values: USB
* @retval none
*/
void usb_enter_suspend(usbd_type *usbx)
{
usbx->ctrl_bit.ssp = TRUE;
usbx->ctrl_bit.lpm = TRUE;
}
/**
* @brief usb device exit suspend mode
* @param usbx: to select the usb peripheral.
* parameter as following values: USB
* @retval none
*/
void usb_exit_suspend(usbd_type *usbx)
{
usbx->ctrl_bit.ssp = FALSE;
usbx->ctrl_bit.lpm = FALSE;
}
/**
* @brief usb remote wakeup set
* @param usbx: to select the usb peripheral.
* parameter as following values: USB
* @retval none
*/
void usb_remote_wkup_set(usbd_type *usbx)
{
usbx->ctrl_bit.gresume = TRUE;
}
/**
* @brief usb remote wakeup clear
* @param usbx: to select the usb peripheral.
* parameter as following values: USB
* @retval none
*/
void usb_remote_wkup_clear(usbd_type *usbx)
{
usbx->ctrl_bit.gresume = FALSE;
}
/**
* @brief usb auto malloc endpoint buffer
* @param mapacket: endpoint support max packet size
* @retval none
*/
uint16_t usb_buffer_malloc(uint16_t maxpacket)
{
uint16_t offset = g_usb_offset_addr;
g_usb_offset_addr += maxpacket;
return offset;
}
/**
* @brief free usb endpoint buffer
* @param none
* @retval none
*/
void usb_buffer_free(void)
{
g_usb_offset_addr = USB_ENDP_DESC_TABLE_OFFSET;
}
/**
* @brief get flag of usb.
* @param usbx: select the usb peripheral
* @param flag: select the usb flag
* this parameter can be one of the following values:
* - USB_INOUT_FLAG
* - USB_LSOF_FLAG
* - USB_SOF_FLAG
* - USB_RST_FLAG
* - USB_SP_FLAG
* - USB_WK_FLAG
* - USB_BE_FLAG
* - USB_UCFOR_FLAG
* - USB_TC_FLAG
* @retval none
*/
flag_status usb_flag_get(usbd_type *usbx, uint16_t flag)
{
flag_status status = RESET;
if((usbx->intsts & flag) == RESET)
{
status = RESET;
}
else
{
status = SET;
}
return status;
}
/**
* @brief get interrupt flag of usb.
* @param usbx: select the usb peripheral
* @param flag: select the usb flag
* this parameter can be one of the following values:
* - USB_LSOF_FLAG
* - USB_SOF_FLAG
* - USB_RST_FLAG
* - USB_SP_FLAG
* - USB_WK_FLAG
* - USB_BE_FLAG
* - USB_UCFOR_FLAG
* - USB_TC_FLAG
* @retval none
*/
flag_status usb_interrupt_flag_get(usbd_type *usbx, uint16_t flag)
{
flag_status status = RESET;
if(flag == USB_TC_FLAG)
{
if(usbx->intsts & USB_TC_FLAG)
status = SET;
}
else
{
if((usbx->intsts & flag) && (usbx->ctrl & flag))
{
status = SET;
}
}
return status;
}
/**
* @brief clear flag of usb.
* @param usbx: select the usb peripheral
* @param flag: select the usb flag
* this parameter can be one of the following values:
* - USB_INOUT_FLAG
* - USB_LSOF_FLAG
* - USB_SOF_FLAG
* - USB_RST_FLAG
* - USB_SP_FLAG
* - USB_WK_FLAG
* - USB_BE_FLAG
* - USB_UCFOR_FLAG
* - USB_TC_FLAG
* @retval none
*/
void usb_flag_clear(usbd_type *usbx, uint16_t flag)
{
usbx->intsts = ~flag;
}
/**
* @}
*/
#endif
/**
* @}
*/
/**
* @}
*/

View File

@@ -0,0 +1,143 @@
/**
**************************************************************************
* @file at32f413_wdt.c
* @brief contains all the functions for the wdt 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 "at32f413_conf.h"
/** @addtogroup AT32F413_periph_driver
* @{
*/
/** @defgroup WDT
* @brief WDT driver modules
* @{
*/
#ifdef WDT_MODULE_ENABLED
/** @defgroup WDT_private_functions
* @{
*/
/**
* @brief wdt enable ,the reload value will be sent to the counter
* @param none
* @retval none
*/
void wdt_enable(void)
{
WDT->cmd = WDT_CMD_ENABLE;
}
/**
* @brief reload wdt counter
* @param none
* @retval none
*/
void wdt_counter_reload(void)
{
WDT->cmd = WDT_CMD_RELOAD;
}
/**
* @brief set wdt counter reload value
* @param reload_value (0x0000~0x0FFF)
* @retval none
*/
void wdt_reload_value_set(uint16_t reload_value)
{
WDT->rld = reload_value;
}
/**
* @brief set wdt division divider
* @param division
* this parameter can be one of the following values:
* - WDT_CLK_DIV_4
* - WDT_CLK_DIV_8
* - WDT_CLK_DIV_16
* - WDT_CLK_DIV_32
* - WDT_CLK_DIV_64
* - WDT_CLK_DIV_128
* - WDT_CLK_DIV_256
* @retval none
*/
void wdt_divider_set(wdt_division_type division)
{
WDT->div_bit.div = division;
}
/**
* @brief enable or disable wdt cmd register write
* @param new_state (TRUE or FALSE)
* @retval none
*/
void wdt_register_write_enable( confirm_state new_state)
{
if(new_state == FALSE)
{
WDT->cmd = WDT_CMD_LOCK;
}
else
{
WDT->cmd = WDT_CMD_UNLOCK;
}
}
/**
* @brief get wdt flag
* @param wdt_flag
* this parameter can be one of the following values:
* - WDT_DIVF_UPDATE_FLAG: division value update complete flag.
* - WDT_RLDF_UPDATE_FLAG: reload value update complete flag.
* @retval state of wdt flag
*/
flag_status wdt_flag_get(uint16_t wdt_flag)
{
flag_status status = RESET;
if ((WDT->sts & wdt_flag) != (uint16_t)RESET)
{
status = SET;
}
else
{
status = RESET;
}
return status;
}
/**
* @}
*/
#endif
/**
* @}
*/
/**
* @}
*/

View File

@@ -0,0 +1,149 @@
/**
**************************************************************************
* @file at32f413_wwdt.c
* @brief contains all the functions for the wwdt 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 "at32f413_conf.h"
/** @addtogroup AT32F413_periph_driver
* @{
*/
/** @defgroup WWDT
* @brief WWDT driver modules
* @{
*/
#ifdef WWDT_MODULE_ENABLED
/** @defgroup WWDT_private_functions
* @{
*/
/**
* @brief wwdt reset by crm reset register
* @retval none
*/
void wwdt_reset(void)
{
crm_periph_reset(CRM_WWDT_PERIPH_RESET, TRUE);
crm_periph_reset(CRM_WWDT_PERIPH_RESET, FALSE);
}
/**
* @brief wwdt division set
* @param division
* this parameter can be one of the following values:
* - WWDT_PCLK1_DIV_4096 (wwdt counter clock = (pclk1/4096)/1)
* - WWDT_PCLK1_DIV_8192 (wwdt counter clock = (pclk1/4096)/2)
* - WWDT_PCLK1_DIV_16384 (wwdt counter clock = (pclk1/4096)/4)
* - WWDT_PCLK1_DIV_32768 (wwdt counter clock = (pclk1/4096)/8)
* @retval none
*/
void wwdt_divider_set(wwdt_division_type division)
{
WWDT->cfg_bit.div = division;
}
/**
* @brief wwdt reload counter interrupt flag clear
* @param none
* @retval none
*/
void wwdt_flag_clear(void)
{
WWDT->sts = 0;
}
/**
* @brief wwdt enable and the counter value load
* @param wwdt_cnt (0x40~0x7f)
* @retval none
*/
void wwdt_enable(uint8_t wwdt_cnt)
{
WWDT->ctrl = wwdt_cnt | WWDT_EN_BIT;
}
/**
* @brief wwdt reload counter interrupt enable
* @param none
* @retval none
*/
void wwdt_interrupt_enable(void)
{
WWDT->cfg_bit.rldien = TRUE;
}
/**
* @brief wwdt reload counter interrupt flag get
* @param none
* @retval state of reload counter interrupt flag
*/
flag_status wwdt_flag_get(void)
{
return (flag_status)WWDT->sts_bit.rldf;
}
/**
* @brief wwdt reload counter interrupt flag get
* @param none
* @retval state of reload counter interrupt flag
*/
flag_status wwdt_interrupt_flag_get(void)
{
return (flag_status)(WWDT->sts_bit.rldf && WWDT->cfg_bit.rldien);
}
/**
* @brief wwdt counter value set
* @param wwdt_cnt (0x40~0x7f)
* @retval none
*/
void wwdt_counter_set(uint8_t wwdt_cnt)
{
WWDT->ctrl_bit.cnt = wwdt_cnt;
}
/**
* @brief wwdt window counter value set
* @param window_cnt (0x40~0x7f)
* @retval none
*/
void wwdt_window_counter_set(uint8_t window_cnt)
{
WWDT->cfg_bit.win = window_cnt;
}
/**
* @}
*/
#endif
/**
* @}
*/
/**
* @}
*/