first commit

This commit is contained in:
YXZhu
2022-08-06 13:35:32 +08:00
commit 2240710d39
1025 changed files with 472118 additions and 0 deletions
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,242 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : ch32f10x_bkp.c
* Author : WCH
* Version : V1.0.0
* Date : 2019/10/15
* Description : This file provides all the BKP firmware functions.
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#include "ch32f10x_bkp.h"
#include "ch32f10x_rcc.h"
/* BKP registers bit address in the alias region */
#define BKP_OFFSET (BKP_BASE - PERIPH_BASE)
/* TPCTLR Register */
/* Alias word address of TPAL bit */
#define TPCTLR_OFFSET (BKP_OFFSET + 0x30)
#define TPAL_BitNumber 0x01
#define TPCTLR_TPAL_BB (PERIPH_BB_BASE + (TPCTLR_OFFSET * 32) + (TPAL_BitNumber * 4))
/* Alias word address of TPE bit */
#define TPE_BitNumber 0x00
#define TPCTLR_TPE_BB (PERIPH_BB_BASE + (TPCTLR_OFFSET * 32) + (TPE_BitNumber * 4))
/* TPCSR Register */
/* Alias word address of TPIE bit */
#define TPCSR_OFFSET (BKP_OFFSET + 0x34)
#define TPIE_BitNumber 0x02
#define TPCSR_TPIE_BB (PERIPH_BB_BASE + (TPCSR_OFFSET * 32) + (TPIE_BitNumber * 4))
/* Alias word address of TIF bit */
#define TIF_BitNumber 0x09
#define TPCSR_TIF_BB (PERIPH_BB_BASE + (TPCSR_OFFSET * 32) + (TIF_BitNumber * 4))
/* Alias word address of TEF bit */
#define TEF_BitNumber 0x08
#define TPCSR_TEF_BB (PERIPH_BB_BASE + (TPCSR_OFFSET * 32) + (TEF_BitNumber * 4))
/* BKP registers bit mask */
/* OCTLR register bit mask */
#define OCTLR_CAL_MASK ((uint16_t)0xFF80)
#define OCTLR_MASK ((uint16_t)0xFC7F)
/*********************************************************************
* @fn BKP_DeInit
*
* @brief Deinitializes the BKP peripheral registers to their default reset values.
*
* @return none
*/
void BKP_DeInit( void )
{
RCC_BackupResetCmd( ENABLE );
RCC_BackupResetCmd( DISABLE );
}
/*********************************************************************
* @fn BKP_TamperPinLevelConfig
*
* @brief Configures the Tamper Pin active level.
*
* @param BKP_TamperPinLevel: specifies the Tamper Pin active level.
* BKP_TamperPinLevel_High - Tamper pin active on high level.
* BKP_TamperPinLevel_Low - Tamper pin active on low level.
*
* @return none
*/
void BKP_TamperPinLevelConfig( uint16_t BKP_TamperPinLevel )
{
*( __IO uint32_t * ) TPCTLR_TPAL_BB = BKP_TamperPinLevel;
}
/*********************************************************************
* @fn BKP_TamperPinCmd
*
* @brief Enables or disables the Tamper Pin activation.
*
* @param NewState - ENABLE or DISABLE.
*
* @return none
*/
void BKP_TamperPinCmd( FunctionalState NewState )
{
*( __IO uint32_t * ) TPCTLR_TPE_BB = ( uint32_t )NewState;
}
/*********************************************************************
* @fn BKP_ITConfig
*
* @brief Enables or disables the Tamper Pin Interrupt.
*
* @param NewState - ENABLE or DISABLE.
*
* @return none
*/
void BKP_ITConfig( FunctionalState NewState )
{
*( __IO uint32_t * ) TPCSR_TPIE_BB = ( uint32_t )NewState;
}
/*********************************************************************
* @fn BKP_RTCOutputConfig
*
* @brief Select the RTC output source to output on the Tamper pin.
*
* @param BKP_RTCOutputSource - specifies the RTC output source.
* BKP_RTCOutputSource_None - no RTC output on the Tamper pin.
* BKP_RTCOutputSource_CalibClock - output the RTC clock with
* frequency divided by 64 on the Tamper pin.
* BKP_RTCOutputSource_Alarm - output the RTC Alarm pulse signal
* on the Tamper pin.
* BKP_RTCOutputSource_Second - output the RTC Second pulse
* signal on the Tamper pin.
*
* @return none
*/
void BKP_RTCOutputConfig( uint16_t BKP_RTCOutputSource )
{
uint16_t tmpreg = 0;
tmpreg = BKP->OCTLR;
tmpreg &= OCTLR_MASK;
tmpreg |= BKP_RTCOutputSource;
BKP->OCTLR = tmpreg;
}
/*********************************************************************
* @fn BKP_SetRTCCalibrationValue
*
* @brief Sets RTC Clock Calibration value.
*
* @param CalibrationValue - specifies the RTC Clock Calibration value.
* This parameter must be a number between 0 and 0x1F.
*
* @return none
*/
void BKP_SetRTCCalibrationValue( uint8_t CalibrationValue )
{
uint16_t tmpreg = 0;
tmpreg = BKP->OCTLR;
tmpreg &= OCTLR_CAL_MASK;
tmpreg |= CalibrationValue;
BKP->OCTLR = tmpreg;
}
/*********************************************************************
* @fn BKP_WriteBackupRegister
*
* @brief Writes user data to the specified Data Backup Register.
*
* @param BKP_DR - specifies the Data Backup Register.
* Data - data to write.
*
* @return none
*/
void BKP_WriteBackupRegister( uint16_t BKP_DR, uint16_t Data )
{
__IO uint32_t tmp = 0;
tmp = ( uint32_t )BKP_BASE;
tmp += BKP_DR;
*( __IO uint32_t * ) tmp = Data;
}
/*********************************************************************
* @fn BKP_ReadBackupRegister
*
* @brief Reads data from the specified Data Backup Register.
*
* @param BKP_DR - specifies the Data Backup Register.
* This parameter can be BKP_DRx where x=[1, 42].
*
* @return none
*/
uint16_t BKP_ReadBackupRegister( uint16_t BKP_DR )
{
__IO uint32_t tmp = 0;
tmp = ( uint32_t )BKP_BASE;
tmp += BKP_DR;
return ( *( __IO uint16_t * ) tmp );
}
/*********************************************************************
* @fn BKP_GetFlagStatus
*
* @brief Checks whether the Tamper Pin Event flag is set or not.
*
* @return FlagStatus - SET or RESET.
*/
FlagStatus BKP_GetFlagStatus( void )
{
return ( FlagStatus )( *( __IO uint32_t * ) TPCSR_TEF_BB );
}
/*********************************************************************
* @fn BKP_ClearFlag
*
* @brief Clears Tamper Pin Event pending flag.
*
* @return none
*/
void BKP_ClearFlag( void )
{
BKP->TPCSR |= BKP_CTE;
}
/*********************************************************************
* @fn BKP_GetITStatus
*
* @brief Checks whether the Tamper Pin Interrupt has occurred or not.
*
* @return ITStatus - SET or RESET.
*/
ITStatus BKP_GetITStatus( void )
{
return ( ITStatus )( *( __IO uint32_t * ) TPCSR_TIF_BB );
}
/*********************************************************************
* @fn BKP_ClearITPendingBit
*
* @brief Clears Tamper Pin Interrupt pending bit.
*
* @return none
*/
void BKP_ClearITPendingBit( void )
{
BKP->TPCSR |= BKP_CTI;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,107 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : ch32f10x_crc.c
* Author : WCH
* Version : V1.0.0
* Date : 2019/10/15
* Description : This file provides all the CRC firmware functions.
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#include "ch32f10x_crc.h"
/*********************************************************************
* @fn CRC_ResetDR
*
* @brief Resets the CRC Data register (DR).
*
* @return none
*/
void CRC_ResetDR( void )
{
CRC->CTLR = CRC_CTLR_RESET;
}
/*********************************************************************
* @fn CRC_CalcCRC
*
* @brief Computes the 32-bit CRC of a given data word(32-bit).
*
* @param Data - data word(32-bit) to compute its CRC.
*
* @return 32-bit CRC.
*/
uint32_t CRC_CalcCRC( uint32_t Data )
{
CRC->DATAR = Data;
return ( CRC->DATAR );
}
/*********************************************************************
* @fn CRC_CalcBlockCRC
*
* @brief Computes 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.
* BufferLength - length of the buffer to be computed.
*
* @return 32-bit CRC.
*/
uint32_t CRC_CalcBlockCRC( uint32_t pBuffer[], uint32_t BufferLength )
{
uint32_t index = 0;
for( index = 0; index < BufferLength; index++ )
{
CRC->DATAR = pBuffer[index];
}
return ( CRC->DATAR );
}
/*********************************************************************
* @fn CRC_GetCRC
*
* @brief Returns the current CRC value.
*
* @return 32-bit CRC.
*/
uint32_t CRC_GetCRC( void )
{
return ( CRC->IDATAR );
}
/*********************************************************************
* @fn CRC_SetIDRegister
*
* @brief Stores a 8-bit data in the Independent Data(ID) register.
*
* @param IDValue - 8-bit value to be stored in the ID register.
*
* @return none
*/
void CRC_SetIDRegister( uint8_t IDValue )
{
CRC->IDATAR = IDValue;
}
/*********************************************************************
* @fn CRC_GetIDRegister
*
* @brief Returns the 8-bit data stored in the Independent Data(ID) register.
*
* @return 8-bit value of the ID register.
*/
uint8_t CRC_GetIDRegister( void )
{
return ( CRC->IDATAR );
}
@@ -0,0 +1,253 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : ch32f10x_dac.c
* Author : WCH
* Version : V1.0.0
* Date : 2019/10/15
* Description : This file provides all the DAC firmware functions.
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* SPDX-License-Identifier: Apache-2.0
****************************************************************************************/
#include "ch32f10x_dac.h"
#include "ch32f10x_rcc.h"
/* CTLR register Mask */
#define CTLR_CLEAR_MASK ((uint32_t)0x00000FFE)
/* DAC Dual Channels SWTR masks */
#define DUAL_SWTR_SET ((uint32_t)0x00000003)
#define DUAL_SWTR_RESET ((uint32_t)0xFFFFFFFC)
/* DHR registers offsets */
#define DHR12R1_OFFSET ((uint32_t)0x00000008)
#define DHR12R2_OFFSET ((uint32_t)0x00000014)
#define DHR12RD_OFFSET ((uint32_t)0x00000020)
/* DOR register offset */
#define DOR_OFFSET ((uint32_t)0x0000002C)
/*********************************************************************
* @fn DAC_DeInit
*
* @brief Deinitializes the DAC peripheral registers to their default reset values.
*
* @return none
*/
void DAC_DeInit( void )
{
RCC_APB1PeriphResetCmd( RCC_APB1Periph_DAC, ENABLE );
RCC_APB1PeriphResetCmd( RCC_APB1Periph_DAC, DISABLE );
}
/*********************************************************************
* @fn DAC_Init
*
* @brief Initializes the DAC peripheral according to the specified parameters in
* the DAC_InitStruct.
*
* @param DAC_Channel - the selected DAC channel.
* DAC_Channel_1 - DAC Channel1 selected
* DAC_Channel_2 - DAC Channel2 selected
* DAC_InitStruct - pointer to a DAC_InitTypeDef structure.
*
* @return none
*/
void DAC_Init( uint32_t DAC_Channel, DAC_InitTypeDef *DAC_InitStruct )
{
uint32_t tmpreg1 = 0, tmpreg2 = 0;
tmpreg1 = DAC->CTLR;
tmpreg1 &= ~( CTLR_CLEAR_MASK << DAC_Channel );
tmpreg2 = ( DAC_InitStruct->DAC_Trigger | DAC_InitStruct->DAC_WaveGeneration |
DAC_InitStruct->DAC_LFSRUnmask_TriangleAmplitude | DAC_InitStruct->DAC_OutputBuffer );
tmpreg1 |= tmpreg2 << DAC_Channel;
DAC->CTLR = tmpreg1;
}
/*********************************************************************
* @fn DAC_StructInit
*
* @brief Fills each DAC_InitStruct member with its default value.
*
* @param DAC_InitStruct - pointer to a DAC_InitTypeDef structure which will be initialized.
*
* @return none
*/
void DAC_StructInit( DAC_InitTypeDef *DAC_InitStruct )
{
DAC_InitStruct->DAC_Trigger = DAC_Trigger_None;
DAC_InitStruct->DAC_WaveGeneration = DAC_WaveGeneration_None;
DAC_InitStruct->DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;
DAC_InitStruct->DAC_OutputBuffer = DAC_OutputBuffer_Enable;
}
/*********************************************************************
* @fn DAC_Cmd
*
* @brief Enables or disables the specified DAC channel.
*
* @param DAC_Channel - the selected DAC channel.
* DAC_Channel_1 - DAC Channel1 selected
* DAC_Channel_2 - DAC Channel2 selected
* NewState - new state of the DAC channel(ENABLE or DISABLE).
*
* @return none
*/
void DAC_Cmd( uint32_t DAC_Channel, FunctionalState NewState )
{
if( NewState != DISABLE )
{
DAC->CTLR |= ( DAC_EN1 << DAC_Channel );
}
else
{
DAC->CTLR &= ~( DAC_EN1 << DAC_Channel );
}
}
/*********************************************************************
* @fn DAC_DMACmd
*
* @brief Enables or disables the specified DAC channel DMA request.
*
* @param DAC_Channel - the selected DAC channel.
* DAC_Channel_1 - DAC Channel1 selected
* DAC_Channel_2 - DAC Channel2 selected
* NewState - new state of the DAC channel(ENABLE or DISABLE).
*
* @return none
*/
void DAC_DMACmd( uint32_t DAC_Channel, FunctionalState NewState )
{
if( NewState != DISABLE )
{
DAC->CTLR |= ( DAC_DMAEN1 << DAC_Channel );
}
else
{
DAC->CTLR &= ~( DAC_DMAEN1 << DAC_Channel );
}
}
/*********************************************************************
* @fn DAC_SoftwareTriggerCmd
*
* @brief Enables or disables the selected DAC channel software trigger.
*
* @param DAC_Channel - the selected DAC channel.
* DAC_Channel_1 - DAC Channel1 selected
* DAC_Channel_2 - DAC Channel2 selected
* NewState - new state of the DAC channel(ENABLE or DISABLE).
*
* @return none
*/
void DAC_SoftwareTriggerCmd( uint32_t DAC_Channel, FunctionalState NewState )
{
if( NewState != DISABLE )
{
DAC->SWTR |= ( uint32_t )DAC_SWTRIG1 << ( DAC_Channel >> 4 );
}
else
{
DAC->SWTR &= ~( ( uint32_t )DAC_SWTRIG1 << ( DAC_Channel >> 4 ) );
}
}
/*********************************************************************
* @fn DAC_WaveGenerationCmd
*
* @brief Enables or disables the selected DAC channel wave generation.
*
* @param DAC_Channel - the selected DAC channel.
* DAC_Channel_1 - DAC Channel1 selected
* DAC_Channel_2 - DAC Channel2 selected
* DAC_Wave - Specifies the wave type to enable or disable.
* DAC_Wave_Noise - noise wave generation
* DAC_Wave_Triangle - triangle wave generation
* NewState - new state of the DAC channel(ENABLE or DISABLE).
*
* @return none
*/
void DAC_WaveGenerationCmd( uint32_t DAC_Channel, uint32_t DAC_Wave, FunctionalState NewState )
{
if( NewState != DISABLE )
{
DAC->CTLR |= DAC_Wave << DAC_Channel;
}
else
{
DAC->CTLR &= ~( DAC_Wave << DAC_Channel );
}
}
/*********************************************************************
* @fn DAC_SetChannel1Data
*
* @brief Set the specified data holding register value for DAC channel1.
*
* @param DAC_Align - Specifies the data alignment for DAC channel1.
* DAC_Align_8b_R - 8bit right data alignment selected
* DAC_Align_12b_L - 12bit left data alignment selected
* DAC_Align_12b_R - 12bit right data alignment selected
* Data - Data to be loaded in the selected data holding register.
*
* @return none
*/
void DAC_SetChannel1Data( uint32_t DAC_Align, uint16_t Data )
{
__IO uint32_t tmp = 0;
tmp = ( uint32_t )DAC_BASE;
tmp += DHR12R1_OFFSET + DAC_Align;
*( __IO uint32_t * ) tmp = Data;
}
/*********************************************************************
* @fn DAC_SetChannel2Data
*
* @brief Set the specified data holding register value for DAC channel2.
*
* @param DAC_Align - Specifies the data alignment for DAC channel1.
* DAC_Align_8b_R - 8bit right data alignment selected
* DAC_Align_12b_L - 12bit left data alignment selected
* DAC_Align_12b_R - 12bit right data alignment selected
* Data - Data to be loaded in the selected data holding register.
*
* @return none
*/
void DAC_SetChannel2Data( uint32_t DAC_Align, uint16_t Data )
{
__IO uint32_t tmp = 0;
tmp = ( uint32_t )DAC_BASE;
tmp += DHR12R2_OFFSET + DAC_Align;
*( __IO uint32_t * )tmp = Data;
}
/*********************************************************************
* @fn DAC_GetDataOutputValue
*
* @brief Returns the last data output value of the selected DAC channel.
*
* @param DAC_Channel - the selected DAC channel.
* DAC_Channel_1 - DAC Channel1 selected
* DAC_Channel_2 - DAC Channel2 selected
*
* @return none
*/
uint16_t DAC_GetDataOutputValue( uint32_t DAC_Channel )
{
__IO uint32_t tmp = 0;
tmp = ( uint32_t ) DAC_BASE ;
tmp += DOR_OFFSET + ( ( uint32_t )DAC_Channel >> 2 );
return ( uint16_t )( *( __IO uint32_t * ) tmp );
}
@@ -0,0 +1,92 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : ch32f10x_dbgmcu.c
* Author : WCH
* Version : V1.0.0
* Date : 2019/10/15
* Description : This file provides all the DBGMCU firmware functions.
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* SPDX-License-Identifier: Apache-2.0
****************************************************************************************/
#include "ch32f10x_dbgmcu.h"
#define IDCODE_DEVID_MASK ((uint32_t)0x00000FFF)
/*********************************************************************
* @fn DBGMCU_GetREVID
*
* @brief Returns the device identifier.
*
* @return Revision identifier.
*/
uint32_t DBGMCU_GetREVID( void )
{
return( DBGMCU->IDCODE >> 16 );
}
/*********************************************************************
* @fn DBGMCU_GetDEVID
*
* @brief Returns the device identifier.
*
* @return Device identifier.
*/
uint32_t DBGMCU_GetDEVID( void )
{
return( DBGMCU->IDCODE & IDCODE_DEVID_MASK );
}
/*********************************************************************
* @fn DBGMCU_Config
*
* @brief Configures the specified peripheral and low power mode behavior
* when the MCU under Debug mode.
*
* @param DBGMCU_Periph - specifies the peripheral and low power mode.
* DBGMCU_SLEEP - Keep debugger connection during SLEEP mode
* DBGMCU_STOP - Keep debugger connection during STOP mode
* DBGMCU_STANDBY - Keep debugger connection during STANDBY mode
* DBGMCU_IWDG_STOP - Debug IWDG stopped when Core is halted
* DBGMCU_WWDG_STOP - Debug WWDG stopped when Core is halted
* DBGMCU_TIM1_STOP - TIM1 counter stopped when Core is halted
* DBGMCU_TIM2_STOP - TIM2 counter stopped when Core is halted
* DBGMCU_TIM3_STOP - TIM3 counter stopped when Core is halted
* DBGMCU_TIM4_STOP - TIM4 counter stopped when Core is halted
* DBGMCU_CAN1_STOP -Debug CAN2 stopped when Core is halted
* DBGMCU_I2C1_SMBUS_TIMEOUT - I2C1 SMBUS timeout mode stopped when Core is halted
* DBGMCU_I2C2_SMBUS_TIMEOUT - I2C2 SMBUS timeout mode stopped when Core is halted
* DBGMCU_TIM5_STOP - TIM5 counter stopped when Core is halted
* DBGMCU_TIM6_STOP - TIM6 counter stopped when Core is halted
* DBGMCU_TIM7_STOP - TIM7 counter stopped when Core is halted
* DBGMCU_TIM8_STOP - TIM8 counter stopped when Core is halted
* DBGMCU_CAN2_STOP - Debug CAN2 stopped when Core is halted
* DBGMCU_TIM15_STOP - TIM15 counter stopped when Core is halted
* DBGMCU_TIM16_STOP - TIM16 counter stopped when Core is halted
* DBGMCU_TIM17_STOP - TIM17 counter stopped when Core is halted
* DBGMCU_TIM9_STOP - TIM9 counter stopped when Core is halted
* DBGMCU_TIM10_STOP - TIM10 counter stopped when Core is halted
* DBGMCU_TIM11_STOP - TIM11 counter stopped when Core is halted
* DBGMCU_TIM12_STOP - TIM12 counter stopped when Core is halted
* DBGMCU_TIM13_STOP - TIM13 counter stopped when Core is halted
* DBGMCU_TIM14_STOP - TIM14 counter stopped when Core is halted
* NewState - ENABLE or DISABLE.
*
* @return none
*/
void DBGMCU_Config( uint32_t DBGMCU_Periph, FunctionalState NewState )
{
if( NewState != DISABLE )
{
DBGMCU->CFGR |= DBGMCU_Periph;
}
else
{
DBGMCU->CFGR &= ~DBGMCU_Periph;
}
}
@@ -0,0 +1,555 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : ch32f10x_dma.c
* Author : WCH
* Version : V1.0.0
* Date : 2019/10/15
* Description : This file provides all the DMA firmware functions.
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#include "ch32f10x_dma.h"
#include "ch32f10x_rcc.h"
/* DMA1 Channelx interrupt pending bit masks */
#define DMA1_Channel1_IT_Mask ((uint32_t)(DMA_GIF1 | DMA_TCIF1 | DMA_HTIF1 | DMA_TEIF1))
#define DMA1_Channel2_IT_Mask ((uint32_t)(DMA_GIF2 | DMA_TCIF2 | DMA_HTIF2 | DMA_TEIF2))
#define DMA1_Channel3_IT_Mask ((uint32_t)(DMA_GIF3 | DMA_TCIF3 | DMA_HTIF3 | DMA_TEIF3))
#define DMA1_Channel4_IT_Mask ((uint32_t)(DMA_GIF4 | DMA_TCIF4 | DMA_HTIF4 | DMA_TEIF4))
#define DMA1_Channel5_IT_Mask ((uint32_t)(DMA_GIF5 | DMA_TCIF5 | DMA_HTIF5 | DMA_TEIF5))
#define DMA1_Channel6_IT_Mask ((uint32_t)(DMA_GIF6 | DMA_TCIF6 | DMA_HTIF6 | DMA_TEIF6))
#define DMA1_Channel7_IT_Mask ((uint32_t)(DMA_GIF7 | DMA_TCIF7 | DMA_HTIF7 | DMA_TEIF7))
/* DMA2 Channelx interrupt pending bit masks */
#define DMA2_Channel1_IT_Mask ((uint32_t)(DMA_GIF1 | DMA_TCIF1 | DMA_HTIF1 | DMA_TEIF1))
#define DMA2_Channel2_IT_Mask ((uint32_t)(DMA_GIF2 | DMA_TCIF2 | DMA_HTIF2 | DMA_TEIF2))
#define DMA2_Channel3_IT_Mask ((uint32_t)(DMA_GIF3 | DMA_TCIF3 | DMA_HTIF3 | DMA_TEIF3))
#define DMA2_Channel4_IT_Mask ((uint32_t)(DMA_GIF4 | DMA_TCIF4 | DMA_HTIF4 | DMA_TEIF4))
#define DMA2_Channel5_IT_Mask ((uint32_t)(DMA_GIF5 | DMA_TCIF5 | DMA_HTIF5 | DMA_TEIF5))
/* DMA2 FLAG mask */
#define FLAG_Mask ((uint32_t)0x10000000)
/* DMA registers Masks */
#define CFGR_CLEAR_Mask ((uint32_t)0xFFFF800F)
/*********************************************************************
* @fn DMA_DeInit
*
* @brief Deinitializes the DMAy Channelx registers to their default
* reset values.
*
* @param DMAy_Channelx - here y can be 1 or 2 to select the DMA and x can be
* 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel.
*
* @return none
*/
void DMA_DeInit( DMA_Channel_TypeDef *DMAy_Channelx )
{
DMAy_Channelx->CFGR &= ( uint16_t )( ~DMA_CFGR1_EN );
DMAy_Channelx->CFGR = 0;
DMAy_Channelx->CNTR = 0;
DMAy_Channelx->PADDR = 0;
DMAy_Channelx->MADDR = 0;
if( DMAy_Channelx == DMA1_Channel1 )
{
DMA1->INTFCR |= DMA1_Channel1_IT_Mask;
}
else if( DMAy_Channelx == DMA1_Channel2 )
{
DMA1->INTFCR |= DMA1_Channel2_IT_Mask;
}
else if( DMAy_Channelx == DMA1_Channel3 )
{
DMA1->INTFCR |= DMA1_Channel3_IT_Mask;
}
else if( DMAy_Channelx == DMA1_Channel4 )
{
DMA1->INTFCR |= DMA1_Channel4_IT_Mask;
}
else if( DMAy_Channelx == DMA1_Channel5 )
{
DMA1->INTFCR |= DMA1_Channel5_IT_Mask;
}
else if( DMAy_Channelx == DMA1_Channel6 )
{
DMA1->INTFCR |= DMA1_Channel6_IT_Mask;
}
else if( DMAy_Channelx == DMA1_Channel7 )
{
DMA1->INTFCR |= DMA1_Channel7_IT_Mask;
}
else if( DMAy_Channelx == DMA2_Channel1 )
{
DMA2->INTFCR |= DMA2_Channel1_IT_Mask;
}
else if( DMAy_Channelx == DMA2_Channel2 )
{
DMA2->INTFCR |= DMA2_Channel2_IT_Mask;
}
else if( DMAy_Channelx == DMA2_Channel3 )
{
DMA2->INTFCR |= DMA2_Channel3_IT_Mask;
}
else if( DMAy_Channelx == DMA2_Channel4 )
{
DMA2->INTFCR |= DMA2_Channel4_IT_Mask;
}
else
{
if( DMAy_Channelx == DMA2_Channel5 )
{
DMA2->INTFCR |= DMA2_Channel5_IT_Mask;
}
}
}
/*********************************************************************
* @fn DMA_Init
*
* @brief Initializes the DMAy Channelx according to the specified
* parameters in the DMA_InitStruct.
*
* @param DMAy_Channelx - here y can be 1 or 2 to select the DMA and x can be
* 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel.
* DMA_InitStruct - pointer to a DMA_InitTypeDef structure that contains
* contains the configuration information for the specified DMA Channel.
*
* @return none
*/
void DMA_Init( DMA_Channel_TypeDef *DMAy_Channelx, DMA_InitTypeDef *DMA_InitStruct )
{
uint32_t tmpreg = 0;
tmpreg = DMAy_Channelx->CFGR;
tmpreg &= CFGR_CLEAR_Mask;
tmpreg |= DMA_InitStruct->DMA_DIR | DMA_InitStruct->DMA_Mode |
DMA_InitStruct->DMA_PeripheralInc | DMA_InitStruct->DMA_MemoryInc |
DMA_InitStruct->DMA_PeripheralDataSize | DMA_InitStruct->DMA_MemoryDataSize |
DMA_InitStruct->DMA_Priority | DMA_InitStruct->DMA_M2M;
DMAy_Channelx->CFGR = tmpreg;
DMAy_Channelx->CNTR = DMA_InitStruct->DMA_BufferSize;
DMAy_Channelx->PADDR = DMA_InitStruct->DMA_PeripheralBaseAddr;
DMAy_Channelx->MADDR = DMA_InitStruct->DMA_MemoryBaseAddr;
}
/*********************************************************************
* @fn DMA_StructInit
*
* @brief Fills each DMA_InitStruct member with its default value.
*
* @param DMA_InitStruct - pointer to a DMA_InitTypeDef structure which will
* 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the be initialized.
*
* @return none
*/
void DMA_StructInit( DMA_InitTypeDef *DMA_InitStruct )
{
DMA_InitStruct->DMA_PeripheralBaseAddr = 0;
DMA_InitStruct->DMA_MemoryBaseAddr = 0;
DMA_InitStruct->DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStruct->DMA_BufferSize = 0;
DMA_InitStruct->DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStruct->DMA_MemoryInc = DMA_MemoryInc_Disable;
DMA_InitStruct->DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStruct->DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStruct->DMA_Mode = DMA_Mode_Normal;
DMA_InitStruct->DMA_Priority = DMA_Priority_Low;
DMA_InitStruct->DMA_M2M = DMA_M2M_Disable;
}
/*********************************************************************
* @fn DMA_Cmd
*
* @brief Enables or disables the specified DMAy Channelx.
*
* @param DMAy_Channelx - here y can be 1 or 2 to select the DMA and x can be
* 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel.
* NewState - new state of the DMAy Channelx(ENABLE or DISABLE).
*
* @return none
*/
void DMA_Cmd( DMA_Channel_TypeDef *DMAy_Channelx, FunctionalState NewState )
{
if( NewState != DISABLE )
{
DMAy_Channelx->CFGR |= DMA_CFGR1_EN;
}
else
{
DMAy_Channelx->CFGR &= ( uint16_t )( ~DMA_CFGR1_EN );
}
}
/*********************************************************************
* @fn DMA_ITConfig
*
* @brief Enables or disables the specified DMAy Channelx interrupts.
*
* @param DMAy_Channelx - here y can be 1 or 2 to select the DMA and x can be
* 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel.
* DMA_IT - specifies the DMA interrupts sources to be enabled
* or disabled.
* DMA_IT_TC - Transfer complete interrupt mask
* DMA_IT_HT - Half transfer interrupt mask
* DMA_IT_TE - Transfer error interrupt mask
* NewState - new state of the DMAy Channelx(ENABLE or DISABLE).
*
* @return none
*/
void DMA_ITConfig( DMA_Channel_TypeDef *DMAy_Channelx, uint32_t DMA_IT, FunctionalState NewState )
{
if( NewState != DISABLE )
{
DMAy_Channelx->CFGR |= DMA_IT;
}
else
{
DMAy_Channelx->CFGR &= ~DMA_IT;
}
}
/*********************************************************************
* @fn DMA_SetCurrDataCounter
*
* @brief Sets the number of data units in the current DMAy Channelx transfer.
*
* @param DMAy_Channelx - here y can be 1 or 2 to select the DMA and x can be
* 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel.
* DataNumber - The number of data units in the current DMAy Channelx
* transfer.
*
* @return none
*/
void DMA_SetCurrDataCounter( DMA_Channel_TypeDef *DMAy_Channelx, uint16_t DataNumber )
{
DMAy_Channelx->CNTR = DataNumber;
}
/*********************************************************************
* @fn DMA_GetCurrDataCounter
*
* @brief Returns the number of remaining data units in the current
* DMAy Channelx transfer.
*
* @param DMAy_Channelx - here y can be 1 or 2 to select the DMA and x can be
* 1 to 7 for DMA1 and 1 to 5 for DMA2 to select the DMA Channel.
*
* @return DataNumber - The number of remaining data units in the current
* DMAy Channelx transfer.
*/
uint16_t DMA_GetCurrDataCounter( DMA_Channel_TypeDef *DMAy_Channelx )
{
return ( ( uint16_t )( DMAy_Channelx->CNTR ) );
}
/*********************************************************************
* @fn DMA_GetFlagStatus
*
* @brief Checks whether the specified DMAy Channelx flag is set or not.
*
* @param DMAy_FLAG - specifies the flag to check.
* DMA1_FLAG_GL1 - DMA1 Channel1 global flag.
* DMA1_FLAG_TC1 - DMA1 Channel1 transfer complete flag.
* DMA1_FLAG_HT1 - DMA1 Channel1 half transfer flag.
* DMA1_FLAG_TE1 - DMA1 Channel1 transfer error flag.
* DMA1_FLAG_GL2 - DMA1 Channel2 global flag.
* DMA1_FLAG_TC2 - DMA1 Channel2 transfer complete flag.
* DMA1_FLAG_HT2 - DMA1 Channel2 half transfer flag.
* DMA1_FLAG_TE2 - DMA1 Channel2 transfer error flag.
* DMA1_FLAG_GL3 - DMA1 Channel3 global flag.
* DMA1_FLAG_TC3 - DMA1 Channel3 transfer complete flag.
* DMA1_FLAG_HT3 - DMA1 Channel3 half transfer flag.
* DMA1_FLAG_TE3 - DMA1 Channel3 transfer error flag.
* DMA1_FLAG_GL4 - DMA1 Channel4 global flag.
* DMA1_FLAG_TC4 - DMA1 Channel4 transfer complete flag.
* DMA1_FLAG_HT4 - DMA1 Channel4 half transfer flag.
* DMA1_FLAG_TE4 - DMA1 Channel4 transfer error flag.
* DMA1_FLAG_GL5 - DMA1 Channel5 global flag.
* DMA1_FLAG_TC5 - DMA1 Channel5 transfer complete flag.
* DMA1_FLAG_HT5 - DMA1 Channel5 half transfer flag.
* DMA1_FLAG_TE5 - DMA1 Channel5 transfer error flag.
* DMA1_FLAG_GL6 - DMA1 Channel6 global flag.
* DMA1_FLAG_TC6 - DMA1 Channel6 transfer complete flag.
* DMA1_FLAG_HT6 - DMA1 Channel6 half transfer flag.
* DMA1_FLAG_TE6 - DMA1 Channel6 transfer error flag.
* DMA1_FLAG_GL7 - DMA1 Channel7 global flag.
* DMA1_FLAG_TC7 - DMA1 Channel7 transfer complete flag.
* DMA1_FLAG_HT7 - DMA1 Channel7 half transfer flag.
* DMA1_FLAG_TE7 - DMA1 Channel7 transfer error flag.
* DMA2_FLAG_GL1 - DMA2 Channel1 global flag.
* DMA2_FLAG_TC1 - DMA2 Channel1 transfer complete flag.
* DMA2_FLAG_HT1 - DMA2 Channel1 half transfer flag.
* DMA2_FLAG_TE1 - DMA2 Channel1 transfer error flag.
* DMA2_FLAG_GL2 - DMA2 Channel2 global flag.
* DMA2_FLAG_TC2 - DMA2 Channel2 transfer complete flag.
* DMA2_FLAG_HT2 - DMA2 Channel2 half transfer flag.
* DMA2_FLAG_TE2 - DMA2 Channel2 transfer error flag.
* DMA2_FLAG_GL3 - DMA2 Channel3 global flag.
* DMA2_FLAG_TC3 - DMA2 Channel3 transfer complete flag.
* DMA2_FLAG_HT3 - DMA2 Channel3 half transfer flag.
* DMA2_FLAG_TE3 - DMA2 Channel3 transfer error flag.
* DMA2_FLAG_GL4 - DMA2 Channel4 global flag.
* DMA2_FLAG_TC4 - DMA2 Channel4 transfer complete flag.
* DMA2_FLAG_HT4 - DMA2 Channel4 half transfer flag.
* DMA2_FLAG_TE4 - DMA2 Channel4 transfer error flag.
* DMA2_FLAG_GL5 - DMA2 Channel5 global flag.
* DMA2_FLAG_TC5 - DMA2 Channel5 transfer complete flag.
* DMA2_FLAG_HT5 - DMA2 Channel5 half transfer flag.
* DMA2_FLAG_TE5 - DMA2 Channel5 transfer error flag.
*
* @return The new state of DMAy_FLAG (SET or RESET).
*/
FlagStatus DMA_GetFlagStatus( uint32_t DMAy_FLAG )
{
FlagStatus bitstatus = RESET;
uint32_t tmpreg = 0;
if( ( DMAy_FLAG & FLAG_Mask ) != ( uint32_t )RESET )
{
tmpreg = DMA2->INTFR ;
}
else
{
tmpreg = DMA1->INTFR ;
}
if( ( tmpreg & DMAy_FLAG ) != ( uint32_t )RESET )
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
/*********************************************************************
* @fn DMA_ClearFlag
*
* @brief Clears the DMAy Channelx's pending flags.
*
* @param DMAy_FLAG - specifies the flag to check.
* DMA1_FLAG_GL1 - DMA1 Channel1 global flag.
* DMA1_FLAG_TC1 - DMA1 Channel1 transfer complete flag.
* DMA1_FLAG_HT1 - DMA1 Channel1 half transfer flag.
* DMA1_FLAG_TE1 - DMA1 Channel1 transfer error flag.
* DMA1_FLAG_GL2 - DMA1 Channel2 global flag.
* DMA1_FLAG_TC2 - DMA1 Channel2 transfer complete flag.
* DMA1_FLAG_HT2 - DMA1 Channel2 half transfer flag.
* DMA1_FLAG_TE2 - DMA1 Channel2 transfer error flag.
* DMA1_FLAG_GL3 - DMA1 Channel3 global flag.
* DMA1_FLAG_TC3 - DMA1 Channel3 transfer complete flag.
* DMA1_FLAG_HT3 - DMA1 Channel3 half transfer flag.
* DMA1_FLAG_TE3 - DMA1 Channel3 transfer error flag.
* DMA1_FLAG_GL4 - DMA1 Channel4 global flag.
* DMA1_FLAG_TC4 - DMA1 Channel4 transfer complete flag.
* DMA1_FLAG_HT4 - DMA1 Channel4 half transfer flag.
* DMA1_FLAG_TE4 - DMA1 Channel4 transfer error flag.
* DMA1_FLAG_GL5 - DMA1 Channel5 global flag.
* DMA1_FLAG_TC5 - DMA1 Channel5 transfer complete flag.
* DMA1_FLAG_HT5 - DMA1 Channel5 half transfer flag.
* DMA1_FLAG_TE5 - DMA1 Channel5 transfer error flag.
* DMA1_FLAG_GL6 - DMA1 Channel6 global flag.
* DMA1_FLAG_TC6 - DMA1 Channel6 transfer complete flag.
* DMA1_FLAG_HT6 - DMA1 Channel6 half transfer flag.
* DMA1_FLAG_TE6 - DMA1 Channel6 transfer error flag.
* DMA1_FLAG_GL7 - DMA1 Channel7 global flag.
* DMA1_FLAG_TC7 - DMA1 Channel7 transfer complete flag.
* DMA1_FLAG_HT7 - DMA1 Channel7 half transfer flag.
* DMA1_FLAG_TE7 - DMA1 Channel7 transfer error flag.
* DMA2_FLAG_GL1 - DMA2 Channel1 global flag.
* DMA2_FLAG_TC1 - DMA2 Channel1 transfer complete flag.
* DMA2_FLAG_HT1 - DMA2 Channel1 half transfer flag.
* DMA2_FLAG_TE1 - DMA2 Channel1 transfer error flag.
* DMA2_FLAG_GL2 - DMA2 Channel2 global flag.
* DMA2_FLAG_TC2 - DMA2 Channel2 transfer complete flag.
* DMA2_FLAG_HT2 - DMA2 Channel2 half transfer flag.
* DMA2_FLAG_TE2 - DMA2 Channel2 transfer error flag.
* DMA2_FLAG_GL3 - DMA2 Channel3 global flag.
* DMA2_FLAG_TC3 - DMA2 Channel3 transfer complete flag.
* DMA2_FLAG_HT3 - DMA2 Channel3 half transfer flag.
* DMA2_FLAG_TE3 - DMA2 Channel3 transfer error flag.
* DMA2_FLAG_GL4 - DMA2 Channel4 global flag.
* DMA2_FLAG_TC4 - DMA2 Channel4 transfer complete flag.
* DMA2_FLAG_HT4 - DMA2 Channel4 half transfer flag.
* DMA2_FLAG_TE4 - DMA2 Channel4 transfer error flag.
* DMA2_FLAG_GL5 - DMA2 Channel5 global flag.
* DMA2_FLAG_TC5 - DMA2 Channel5 transfer complete flag.
* DMA2_FLAG_HT5 - DMA2 Channel5 half transfer flag.
* DMA2_FLAG_TE5 - DMA2 Channel5 transfer error flag.
*
* @return none
*/
void DMA_ClearFlag( uint32_t DMAy_FLAG )
{
if( ( DMAy_FLAG & FLAG_Mask ) != ( uint32_t )RESET )
{
DMA2->INTFCR = DMAy_FLAG;
}
else
{
DMA1->INTFCR = DMAy_FLAG;
}
}
/*********************************************************************
* @fn DMA_GetITStatus
*
* @brief Checks whether the specified DMAy Channelx interrupt has
* occurred or not.
*
* @param DMAy_IT - specifies the DMAy interrupt source to check.
* DMA1_IT_GL1 - DMA1 Channel1 global flag.
* DMA1_IT_TC1 - DMA1 Channel1 transfer complete flag.
* DMA1_IT_HT1 - DMA1 Channel1 half transfer flag.
* DMA1_IT_TE1 - DMA1 Channel1 transfer error flag.
* DMA1_IT_GL2 - DMA1 Channel2 global flag.
* DMA1_IT_TC2 - DMA1 Channel2 transfer complete flag.
* DMA1_IT_HT2 - DMA1 Channel2 half transfer flag.
* DMA1_IT_TE2 - DMA1 Channel2 transfer error flag.
* DMA1_IT_GL3 - DMA1 Channel3 global flag.
* DMA1_IT_TC3 - DMA1 Channel3 transfer complete flag.
* DMA1_IT_HT3 - DMA1 Channel3 half transfer flag.
* DMA1_IT_TE3 - DMA1 Channel3 transfer error flag.
* DMA1_IT_GL4 - DMA1 Channel4 global flag.
* DMA1_IT_TC4 - DMA1 Channel4 transfer complete flag.
* DMA1_IT_HT4 - DMA1 Channel4 half transfer flag.
* DMA1_IT_TE4 - DMA1 Channel4 transfer error flag.
* DMA1_IT_GL5 - DMA1 Channel5 global flag.
* DMA1_IT_TC5 - DMA1 Channel5 transfer complete flag.
* DMA1_IT_HT5 - DMA1 Channel5 half transfer flag.
* DMA1_IT_TE5 - DMA1 Channel5 transfer error flag.
* DMA1_IT_GL6 - DMA1 Channel6 global flag.
* DMA1_IT_TC6 - DMA1 Channel6 transfer complete flag.
* DMA1_IT_HT6 - DMA1 Channel6 half transfer flag.
* DMA1_IT_TE6 - DMA1 Channel6 transfer error flag.
* DMA1_IT_GL7 - DMA1 Channel7 global flag.
* DMA1_IT_TC7 - DMA1 Channel7 transfer complete flag.
* DMA1_IT_HT7 - DMA1 Channel7 half transfer flag.
* DMA1_IT_TE7 - DMA1 Channel7 transfer error flag.
* DMA2_IT_GL1 - DMA2 Channel1 global flag.
* DMA2_IT_TC1 - DMA2 Channel1 transfer complete flag.
* DMA2_IT_HT1 - DMA2 Channel1 half transfer flag.
* DMA2_IT_TE1 - DMA2 Channel1 transfer error flag.
* DMA2_IT_GL2 - DMA2 Channel2 global flag.
* DMA2_IT_TC2 - DMA2 Channel2 transfer complete flag.
* DMA2_IT_HT2 - DMA2 Channel2 half transfer flag.
* DMA2_IT_TE2 - DMA2 Channel2 transfer error flag.
* DMA2_IT_GL3 - DMA2 Channel3 global flag.
* DMA2_IT_TC3 - DMA2 Channel3 transfer complete flag.
* DMA2_IT_HT3 - DMA2 Channel3 half transfer flag.
* DMA2_IT_TE3 - DMA2 Channel3 transfer error flag.
* DMA2_IT_GL4 - DMA2 Channel4 global flag.
* DMA2_IT_TC4 - DMA2 Channel4 transfer complete flag.
* DMA2_IT_HT4 - DMA2 Channel4 half transfer flag.
* DMA2_IT_TE4 - DMA2 Channel4 transfer error flag.
* DMA2_IT_GL5 - DMA2 Channel5 global flag.
* DMA2_IT_TC5 - DMA2 Channel5 transfer complete flag.
* DMA2_IT_HT5 - DMA2 Channel5 half transfer flag.
* DMA2_IT_TE5 - DMA2 Channel5 transfer error flag.
*
* @return The new state of DMAy_IT (SET or RESET).
*/
ITStatus DMA_GetITStatus( uint32_t DMAy_IT )
{
ITStatus bitstatus = RESET;
uint32_t tmpreg = 0;
if( ( DMAy_IT & FLAG_Mask ) != ( uint32_t )RESET )
{
tmpreg = DMA2->INTFR;
}
else
{
tmpreg = DMA1->INTFR;
}
if( ( tmpreg & DMAy_IT ) != ( uint32_t )RESET )
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
/*********************************************************************
* @fn DMA_ClearITPendingBit
*
* @brief Clears the DMAy Channelx's interrupt pending bits.
*
* @param DMAy_IT - specifies the DMAy interrupt source to check.
* DMA1_IT_GL1 - DMA1 Channel1 global flag.
* DMA1_IT_TC1 - DMA1 Channel1 transfer complete flag.
* DMA1_IT_HT1 - DMA1 Channel1 half transfer flag.
* DMA1_IT_TE1 - DMA1 Channel1 transfer error flag.
* DMA1_IT_GL2 - DMA1 Channel2 global flag.
* DMA1_IT_TC2 - DMA1 Channel2 transfer complete flag.
* DMA1_IT_HT2 - DMA1 Channel2 half transfer flag.
* DMA1_IT_TE2 - DMA1 Channel2 transfer error flag.
* DMA1_IT_GL3 - DMA1 Channel3 global flag.
* DMA1_IT_TC3 - DMA1 Channel3 transfer complete flag.
* DMA1_IT_HT3 - DMA1 Channel3 half transfer flag.
* DMA1_IT_TE3 - DMA1 Channel3 transfer error flag.
* DMA1_IT_GL4 - DMA1 Channel4 global flag.
* DMA1_IT_TC4 - DMA1 Channel4 transfer complete flag.
* DMA1_IT_HT4 - DMA1 Channel4 half transfer flag.
* DMA1_IT_TE4 - DMA1 Channel4 transfer error flag.
* DMA1_IT_GL5 - DMA1 Channel5 global flag.
* DMA1_IT_TC5 - DMA1 Channel5 transfer complete flag.
* DMA1_IT_HT5 - DMA1 Channel5 half transfer flag.
* DMA1_IT_TE5 - DMA1 Channel5 transfer error flag.
* DMA1_IT_GL6 - DMA1 Channel6 global flag.
* DMA1_IT_TC6 - DMA1 Channel6 transfer complete flag.
* DMA1_IT_HT6 - DMA1 Channel6 half transfer flag.
* DMA1_IT_TE6 - DMA1 Channel6 transfer error flag.
* DMA1_IT_GL7 - DMA1 Channel7 global flag.
* DMA1_IT_TC7 - DMA1 Channel7 transfer complete flag.
* DMA1_IT_HT7 - DMA1 Channel7 half transfer flag.
* DMA1_IT_TE7 - DMA1 Channel7 transfer error flag.
* DMA2_IT_GL1 - DMA2 Channel1 global flag.
* DMA2_IT_TC1 - DMA2 Channel1 transfer complete flag.
* DMA2_IT_HT1 - DMA2 Channel1 half transfer flag.
* DMA2_IT_TE1 - DMA2 Channel1 transfer error flag.
* DMA2_IT_GL2 - DMA2 Channel2 global flag.
* DMA2_IT_TC2 - DMA2 Channel2 transfer complete flag.
* DMA2_IT_HT2 - DMA2 Channel2 half transfer flag.
* DMA2_IT_TE2 - DMA2 Channel2 transfer error flag.
* DMA2_IT_GL3 - DMA2 Channel3 global flag.
* DMA2_IT_TC3 - DMA2 Channel3 transfer complete flag.
* DMA2_IT_HT3 - DMA2 Channel3 half transfer flag.
* DMA2_IT_TE3 - DMA2 Channel3 transfer error flag.
* DMA2_IT_GL4 - DMA2 Channel4 global flag.
* DMA2_IT_TC4 - DMA2 Channel4 transfer complete flag.
* DMA2_IT_HT4 - DMA2 Channel4 half transfer flag.
* DMA2_IT_TE4 - DMA2 Channel4 transfer error flag.
* DMA2_IT_GL5 - DMA2 Channel5 global flag.
* DMA2_IT_TC5 - DMA2 Channel5 transfer complete flag.
* DMA2_IT_HT5 - DMA2 Channel5 half transfer flag.
* DMA2_IT_TE5 - DMA2 Channel5 transfer error flag.
*
* @return none
*/
void DMA_ClearITPendingBit( uint32_t DMAy_IT )
{
if( ( DMAy_IT & FLAG_Mask ) != ( uint32_t )RESET )
{
DMA2->INTFCR = DMAy_IT;
}
else
{
DMA1->INTFCR = DMAy_IT;
}
}
@@ -0,0 +1,182 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : ch32f10x_exti.c
* Author : WCH
* Version : V1.0.0
* Date : 2019/10/15
* Description : This file provides all the EXTI firmware functions.
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* SPDX-License-Identifier: Apache-2.0
***************************************************************************************/
#include "ch32f10x_exti.h"
/* No interrupt selected */
#define EXTI_LINENONE ((uint32_t)0x00000)
/*********************************************************************
* @fn EXTI_DeInit
*
* @brief Deinitializes the EXTI peripheral registers to their default
* reset values.
*
* @return none.
*/
void EXTI_DeInit( void )
{
EXTI->INTENR = 0x00000000;
EXTI->EVENR = 0x00000000;
EXTI->RTENR = 0x00000000;
EXTI->FTENR = 0x00000000;
EXTI->INTFR = 0x000FFFFF;
}
/*********************************************************************
* @fn EXTI_Init
*
* @brief Initializes the EXTI peripheral according to the specified
* parameters in the EXTI_InitStruct.
*
* @param EXTI_InitStruct: pointer to a EXTI_InitTypeDef structure
*
* @return none.
*/
void EXTI_Init( EXTI_InitTypeDef *EXTI_InitStruct )
{
uint32_t tmp = 0;
tmp = ( uint32_t )EXTI_BASE;
if( EXTI_InitStruct->EXTI_LineCmd != DISABLE )
{
EXTI->INTENR &= ~EXTI_InitStruct->EXTI_Line;
EXTI->EVENR &= ~EXTI_InitStruct->EXTI_Line;
tmp += EXTI_InitStruct->EXTI_Mode;
*( __IO uint32_t * ) tmp |= EXTI_InitStruct->EXTI_Line;
EXTI->RTENR &= ~EXTI_InitStruct->EXTI_Line;
EXTI->FTENR &= ~EXTI_InitStruct->EXTI_Line;
if( EXTI_InitStruct->EXTI_Trigger == EXTI_Trigger_Rising_Falling )
{
EXTI->RTENR |= EXTI_InitStruct->EXTI_Line;
EXTI->FTENR |= EXTI_InitStruct->EXTI_Line;
}
else
{
tmp = ( uint32_t )EXTI_BASE;
tmp += EXTI_InitStruct->EXTI_Trigger;
*( __IO uint32_t * ) tmp |= EXTI_InitStruct->EXTI_Line;
}
}
else
{
tmp += EXTI_InitStruct->EXTI_Mode;
*( __IO uint32_t * ) tmp &= ~EXTI_InitStruct->EXTI_Line;
}
}
/*********************************************************************
* @fn EXTI_StructInit
*
* @brief Fills each EXTI_InitStruct member with its reset value.
*
* @param EXTI_InitStruct - pointer to a EXTI_InitTypeDef structure
*
* @return none.
*/
void EXTI_StructInit( EXTI_InitTypeDef *EXTI_InitStruct )
{
EXTI_InitStruct->EXTI_Line = EXTI_LINENONE;
EXTI_InitStruct->EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct->EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStruct->EXTI_LineCmd = DISABLE;
}
/*********************************************************************
* @fn EXTI_GenerateSWInterrupt
*
* @brief Generates a Software interrupt.
*
* @param EXTI_Line - specifies the EXTI lines to be enabled or disabled.
*
* @return none.
*/
void EXTI_GenerateSWInterrupt( uint32_t EXTI_Line )
{
EXTI->SWIEVR |= EXTI_Line;
}
/*********************************************************************
* @fn EXTI_GetFlagStatus
*
* @brief Checks whether the specified EXTI line flag is set or not.
*
* @param EXTI_Line - specifies the EXTI lines to be enabled or disabled.
*
* @return The new state of EXTI_Line (SET or RESET).
*/
FlagStatus EXTI_GetFlagStatus( uint32_t EXTI_Line )
{
FlagStatus bitstatus = RESET;
if( ( EXTI->INTFR & EXTI_Line ) != ( uint32_t )RESET )
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
/*********************************************************************
* @fn EXTI_ClearFlag
*
* @brief Clears the EXTI's line pending flags.
*
* @param EXTI_Line - specifies the EXTI lines to be enabled or disabled.
*
* @return None
*/
void EXTI_ClearFlag( uint32_t EXTI_Line )
{
EXTI->INTFR = EXTI_Line;
}
/*********************************************************************
* @fn EXTI_GetITStatus
*
* @brief Checks whether the specified EXTI line is asserted or not.
*
* @param EXTI_Line - specifies the EXTI lines to be enabled or disabled.
*
* @return The new state of EXTI_Line (SET or RESET).
*/
ITStatus EXTI_GetITStatus( uint32_t EXTI_Line )
{
ITStatus bitstatus = RESET;
uint32_t enablestatus = 0;
enablestatus = EXTI->INTENR & EXTI_Line;
if( ( ( EXTI->INTFR & EXTI_Line ) != ( uint32_t )RESET ) && ( enablestatus != ( uint32_t )RESET ) )
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
/*********************************************************************
* @fn EXTI_ClearITPendingBit
*
* @brief Clears the EXTI's line pending bits.
*
* @param EXTI_Line - specifies the EXTI lines to be enabled or disabled.
*
* @return none
*/
void EXTI_ClearITPendingBit( uint32_t EXTI_Line )
{
EXTI->INTFR = EXTI_Line;
}
@@ -0,0 +1,979 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : ch32f10x_flash.c
* Author : WCH
* Version : V1.0.0
* Date : 2019/10/15
* Description : This file provides all the FLASH firmware functions.
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* SPDX-License-Identifier: Apache-2.0
***************************************************************************************/
#include "ch32f10x_flash.h"
/* Flash Access Control Register bits */
#define ACR_LATENCY_Mask ((uint32_t)0x00000038)
#define ACR_HLFCYA_Mask ((uint32_t)0xFFFFFFF7)
#define ACR_PRFTBE_Mask ((uint32_t)0xFFFFFFEF)
/* Flash Access Control Register bits */
#define ACR_PRFTBS_Mask ((uint32_t)0x00000020)
/* Flash Control Register bits */
#define CR_PG_Set ((uint32_t)0x00000001)
#define CR_PG_Reset ((uint32_t)0x00001FFE)
#define CR_PER_Set ((uint32_t)0x00000002)
#define CR_PER_Reset ((uint32_t)0x00001FFD)
#define CR_MER_Set ((uint32_t)0x00000004)
#define CR_MER_Reset ((uint32_t)0x00001FFB)
#define CR_OPTPG_Set ((uint32_t)0x00000010)
#define CR_OPTPG_Reset ((uint32_t)0x00001FEF)
#define CR_OPTER_Set ((uint32_t)0x00000020)
#define CR_OPTER_Reset ((uint32_t)0x00001FDF)
#define CR_STRT_Set ((uint32_t)0x00000040)
#define CR_LOCK_Set ((uint32_t)0x00000080)
#define CR_PAGE_PG ((uint32_t)0x00010000)
#define CR_PAGE_ER ((uint32_t)0x00020000)
#define CR_BUF_LOAD ((uint32_t)0x00040000)
#define CR_BUF_RST ((uint32_t)0x00080000)
/* FLASH Status Register bits */
#define SR_BSY ((uint32_t)0x00000001)
#define SR_PGERR ((uint32_t)0x00000004)
#define SR_WRPRTERR ((uint32_t)0x00000010)
#define SR_EOP ((uint32_t)0x00000020)
/* FLASH Mask */
#define RDPRT_Mask ((uint32_t)0x00000002)
#define WRP0_Mask ((uint32_t)0x000000FF)
#define WRP1_Mask ((uint32_t)0x0000FF00)
#define WRP2_Mask ((uint32_t)0x00FF0000)
#define WRP3_Mask ((uint32_t)0xFF000000)
#define OB_USER_BFB2 ((uint16_t)0x0008)
/* FLASH Keys */
#define RDP_Key ((uint16_t)0x00A5)
#define FLASH_KEY1 ((uint32_t)0x45670123)
#define FLASH_KEY2 ((uint32_t)0xCDEF89AB)
/* FLASH BANK address */
#define FLASH_BANK1_END_ADDRESS ((uint32_t)0x807FFFF)
/* Delay definition */
#define EraseTimeout ((uint32_t)0x000B0000)
#define ProgramTimeout ((uint32_t)0x00002000)
/* Flash Program Vaild Address */
#define ValidAddrStart (FLASH_BASE)
#define ValidAddrEnd (FLASH_BASE + 0x10000)
/********************************************************************************
* @fn FLASH_SetLatency
*
* @brief Sets the code latency value.
*
* @param FLASH_Latency - specifies the FLASH Latency value.
* FLASH_Latency_0 - FLASH Zero Latency cycle
* FLASH_Latency_1 - FLASH One Latency cycle
* FLASH_Latency_2 - FLASH Two Latency cycles
*
* @return None
*/
void FLASH_SetLatency( uint32_t FLASH_Latency )
{
uint32_t tmpreg = 0;
tmpreg = FLASH->ACTLR;
tmpreg &= ACR_LATENCY_Mask;
tmpreg |= FLASH_Latency;
FLASH->ACTLR = tmpreg;
}
/********************************************************************************
* @fn FLASH_HalfCycleAccessCmd
*
* @brief Enables or disables the Half cycle flash access.
*
* @param FLASH_HalfCycleAccess - specifies the FLASH Half cycle Access mode.
* FLASH_HalfCycleAccess_Enable - FLASH Half Cycle Enable
* FLASH_HalfCycleAccess_Disable - FLASH Half Cycle Disable
*
* @return None
*/
void FLASH_HalfCycleAccessCmd( uint32_t FLASH_HalfCycleAccess )
{
FLASH->ACTLR &= ACR_HLFCYA_Mask;
FLASH->ACTLR |= FLASH_HalfCycleAccess;
}
/********************************************************************************
* @fn FLASH_PrefetchBufferCmd
*
* @brief Enables or disables the Prefetch Buffer.
*
* @param FLASH_PrefetchBuffer - specifies the Prefetch buffer status.
* FLASH_PrefetchBuffer_Enable - FLASH Prefetch Buffer Enable
* FLASH_PrefetchBuffer_Disable - FLASH Prefetch Buffer Disable
*
* @return None
*/
void FLASH_PrefetchBufferCmd( uint32_t FLASH_PrefetchBuffer )
{
FLASH->ACTLR &= ACR_PRFTBE_Mask;
FLASH->ACTLR |= FLASH_PrefetchBuffer;
}
/********************************************************************************
* @fn FLASH_Unlock
*
* @brief Unlocks the FLASH Program Erase Controller.
*
* @return None
*/
void FLASH_Unlock( void )
{
/* Authorize the FPEC of Bank1 Access */
FLASH->KEYR = FLASH_KEY1;
FLASH->KEYR = FLASH_KEY2;
}
/********************************************************************************
* @fn FLASH_UnlockBank1
*
* @brief Unlocks the FLASH Bank1 Program Erase Controller.
* equivalent to FLASH_Unlock function.
*
* @return None
*/
void FLASH_UnlockBank1( void )
{
FLASH->KEYR = FLASH_KEY1;
FLASH->KEYR = FLASH_KEY2;
}
/********************************************************************************
* @fn FLASH_Lock
*
* @brief Locks the FLASH Program Erase Controller.
*
* @return None
*/
void FLASH_Lock( void )
{
FLASH->CTLR |= CR_LOCK_Set;
}
/********************************************************************************
* @fn FLASH_LockBank1
*
* @brief Locks the FLASH Bank1 Program Erase Controller.
*
* @return None
*/
void FLASH_LockBank1( void )
{
FLASH->CTLR |= CR_LOCK_Set;
}
/********************************************************************************
* @fn FLASH_ErasePage
*
* @brief Erases a specified FLASH page.
*
* @param Page_Address - The page address to be erased.
*
* @return FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
* FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
*/
FLASH_Status FLASH_ErasePage( uint32_t Page_Address )
{
FLASH_Status status = FLASH_COMPLETE;
status = FLASH_WaitForLastOperation( EraseTimeout );
if( status == FLASH_COMPLETE )
{
FLASH->CTLR |= CR_PER_Set;
FLASH->ADDR = Page_Address;
FLASH->CTLR |= CR_STRT_Set;
status = FLASH_WaitForLastOperation( EraseTimeout );
FLASH->CTLR &= CR_PER_Reset;
}
*( __IO uint32_t * )0x40022034 = *( __IO uint32_t * )( Page_Address ^ 0x00000100 );
return status;
}
/********************************************************************************
* @fn FLASH_EraseAllPages
*
* @brief Erases all FLASH pages.
*
* @return FLASH Status - The returned value can be:FLASH_BUSY, FLASH_ERROR_PG,
* FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
*/
FLASH_Status FLASH_EraseAllPages( void )
{
FLASH_Status status = FLASH_COMPLETE;
status = FLASH_WaitForLastOperation( EraseTimeout );
if( status == FLASH_COMPLETE )
{
FLASH->CTLR |= CR_MER_Set;
FLASH->CTLR |= CR_STRT_Set;
status = FLASH_WaitForLastOperation( EraseTimeout );
FLASH->CTLR &= CR_MER_Reset;
}
return status;
}
/********************************************************************************
* @fn FLASH_EraseAllBank1Pages
*
* @brief Erases all Bank1 FLASH pages.
*
* @return FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
* FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
*/
FLASH_Status FLASH_EraseAllBank1Pages( void )
{
FLASH_Status status = FLASH_COMPLETE;
status = FLASH_WaitForLastBank1Operation( EraseTimeout );
if( status == FLASH_COMPLETE )
{
FLASH->CTLR |= CR_MER_Set;
FLASH->CTLR |= CR_STRT_Set;
status = FLASH_WaitForLastBank1Operation( EraseTimeout );
FLASH->CTLR &= CR_MER_Reset;
}
return status;
}
/********************************************************************************
* @fn FLASH_EraseOptionBytes
*
* @brief Erases the FLASH option bytes.
*
* @return FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
* FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
*/
FLASH_Status FLASH_EraseOptionBytes( void )
{
uint16_t rdptmp = RDP_Key;
FLASH_Status status = FLASH_COMPLETE;
if( FLASH_GetReadOutProtectionStatus() != RESET )
{
rdptmp = 0x00;
}
status = FLASH_WaitForLastOperation( EraseTimeout );
if( status == FLASH_COMPLETE )
{
FLASH->OBKEYR = FLASH_KEY1;
FLASH->OBKEYR = FLASH_KEY2;
FLASH->CTLR |= CR_OPTER_Set;
FLASH->CTLR |= CR_STRT_Set;
status = FLASH_WaitForLastOperation( EraseTimeout );
if( status == FLASH_COMPLETE )
{
FLASH->CTLR &= CR_OPTER_Reset;
FLASH->CTLR |= CR_OPTPG_Set;
OB->RDPR = ( uint16_t )rdptmp;
status = FLASH_WaitForLastOperation( ProgramTimeout );
if( status != FLASH_TIMEOUT )
{
FLASH->CTLR &= CR_OPTPG_Reset;
}
}
else
{
if( status != FLASH_TIMEOUT )
{
FLASH->CTLR &= CR_OPTPG_Reset;
}
}
}
return status;
}
/*********************************************************************
* @fn FLASH_ProgramWord
*
* @brief Programs a word at a specified address.
*
* @param Address - specifies the address to be programmed.
* Data - specifies the data to be programmed.
*
* @return FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
* FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
*/
FLASH_Status FLASH_ProgramWord( uint32_t Address, uint32_t Data )
{
FLASH_Status status = FLASH_COMPLETE;
__IO uint32_t tmp = 0;
status = FLASH_WaitForLastOperation( ProgramTimeout );
if( status == FLASH_COMPLETE )
{
FLASH->CTLR |= CR_PG_Set;
*( __IO uint16_t * )Address = ( uint16_t )Data;
status = FLASH_WaitForLastOperation( ProgramTimeout );
if( status == FLASH_COMPLETE )
{
tmp = Address + 2;
*( __IO uint16_t * ) tmp = Data >> 16;
status = FLASH_WaitForLastOperation( ProgramTimeout );
FLASH->CTLR &= CR_PG_Reset;
}
else
{
FLASH->CTLR &= CR_PG_Reset;
}
}
*( __IO uint32_t * )0x40022034 = *( __IO uint32_t * )( Address ^ 0x00000100 );
return status;
}
/*********************************************************************
* @fn FLASH_ProgramHalfWord
*
* @brief Programs a half word at a specified address.
*
* @param Address - specifies the address to be programmed.
* Data - specifies the data to be programmed.
*
* @return FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
* FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
*/
FLASH_Status FLASH_ProgramHalfWord( uint32_t Address, uint16_t Data )
{
FLASH_Status status = FLASH_COMPLETE;
status = FLASH_WaitForLastOperation( ProgramTimeout );
if( status == FLASH_COMPLETE )
{
FLASH->CTLR |= CR_PG_Set;
*( __IO uint16_t * )Address = Data;
status = FLASH_WaitForLastOperation( ProgramTimeout );
FLASH->CTLR &= CR_PG_Reset;
}
//*( __IO uint32_t * )0x40022034 = *( __IO uint32_t * )( Address ^ 0x00000100 );
return status;
}
/*********************************************************************
* @fn FLASH_ProgramOptionByteData
*
* @brief Programs a half word at a specified Option Byte Data address.
*
* @param Address - specifies the address to be programmed.
* Data - specifies the data to be programmed.
*
* @return FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
* FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
*/
FLASH_Status FLASH_ProgramOptionByteData( uint32_t Address, uint8_t Data )
{
FLASH_Status status = FLASH_COMPLETE;
status = FLASH_WaitForLastOperation( ProgramTimeout );
if( status == FLASH_COMPLETE )
{
FLASH->OBKEYR = FLASH_KEY1;
FLASH->OBKEYR = FLASH_KEY2;
FLASH->CTLR |= CR_OPTPG_Set;
*( __IO uint16_t * )Address = Data;
status = FLASH_WaitForLastOperation( ProgramTimeout );
if( status != FLASH_TIMEOUT )
{
FLASH->CTLR &= CR_OPTPG_Reset;
}
}
*( __IO uint32_t * )0x40022034 = *( __IO uint32_t * )( Address ^ 0x00000100 );
return status;
}
/*********************************************************************
* @fn FLASH_EnableWriteProtection
*
* @brief Write protects the desired sectors
*
* @param FLASH_Sectors - specifies the address of the pages to be write protected.
*
* @return FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
* FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
*/
FLASH_Status FLASH_EnableWriteProtection( uint32_t FLASH_Pages )
{
uint16_t WRP0_Data = 0xFFFF, WRP1_Data = 0xFFFF, WRP2_Data = 0xFFFF, WRP3_Data = 0xFFFF;
FLASH_Status status = FLASH_COMPLETE;
FLASH_Pages = ( uint32_t )( ~FLASH_Pages );
WRP0_Data = ( uint16_t )( FLASH_Pages & WRP0_Mask );
WRP1_Data = ( uint16_t )( ( FLASH_Pages & WRP1_Mask ) >> 8 );
WRP2_Data = ( uint16_t )( ( FLASH_Pages & WRP2_Mask ) >> 16 );
WRP3_Data = ( uint16_t )( ( FLASH_Pages & WRP3_Mask ) >> 24 );
status = FLASH_WaitForLastOperation( ProgramTimeout );
if( status == FLASH_COMPLETE )
{
FLASH->OBKEYR = FLASH_KEY1;
FLASH->OBKEYR = FLASH_KEY2;
FLASH->CTLR |= CR_OPTPG_Set;
if( WRP0_Data != 0xFF )
{
OB->WRPR0 = WRP0_Data;
status = FLASH_WaitForLastOperation( ProgramTimeout );
}
if( ( status == FLASH_COMPLETE ) && ( WRP1_Data != 0xFF ) )
{
OB->WRPR1 = WRP1_Data;
status = FLASH_WaitForLastOperation( ProgramTimeout );
}
if( ( status == FLASH_COMPLETE ) && ( WRP2_Data != 0xFF ) )
{
OB->WRPR2 = WRP2_Data;
status = FLASH_WaitForLastOperation( ProgramTimeout );
}
if( ( status == FLASH_COMPLETE ) && ( WRP3_Data != 0xFF ) )
{
OB->WRPR3 = WRP3_Data;
status = FLASH_WaitForLastOperation( ProgramTimeout );
}
if( status != FLASH_TIMEOUT )
{
FLASH->CTLR &= CR_OPTPG_Reset;
}
}
return status;
}
/*********************************************************************
* @fn FLASH_ReadOutProtection
*
* @brief Enables or disables the read out protection.
*
* @param Newstate - new state of the ReadOut Protection(ENABLE or DISABLE).
*
* @return FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
* FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
*/
FLASH_Status FLASH_ReadOutProtection( FunctionalState NewState )
{
FLASH_Status status = FLASH_COMPLETE;
status = FLASH_WaitForLastOperation( EraseTimeout );
if( status == FLASH_COMPLETE )
{
FLASH->OBKEYR = FLASH_KEY1;
FLASH->OBKEYR = FLASH_KEY2;
FLASH->CTLR |= CR_OPTER_Set;
FLASH->CTLR |= CR_STRT_Set;
status = FLASH_WaitForLastOperation( EraseTimeout );
if( status == FLASH_COMPLETE )
{
FLASH->CTLR &= CR_OPTER_Reset;
FLASH->CTLR |= CR_OPTPG_Set;
if( NewState != DISABLE )
{
OB->RDPR = 0x00;
}
else
{
OB->RDPR = RDP_Key;
}
status = FLASH_WaitForLastOperation( EraseTimeout );
if( status != FLASH_TIMEOUT )
{
FLASH->CTLR &= CR_OPTPG_Reset;
}
}
else
{
if( status != FLASH_TIMEOUT )
{
FLASH->CTLR &= CR_OPTER_Reset;
}
}
}
return status;
}
/*********************************************************************
* @fn FLASH_UserOptionByteConfig
*
* @brief Programs the FLASH User Option Byte - IWDG_SW / RST_STOP / RST_STDBY.
*
* @param OB_IWDG - Selects the IWDG mode
* OB_IWDG_SW - Software IWDG selected
* OB_IWDG_HW - Hardware IWDG selected
* OB_STOP - Reset event when entering STOP mode.
* OB_STOP_NoRST - No reset generated when entering in STOP
* OB_STOP_RST - Reset generated when entering in STOP
* OB_STDBY - Reset event when entering Standby mode.
* OB_STDBY_NoRST - No reset generated when entering in STANDBY
* OB_STDBY_RST - Reset generated when entering in STANDBY
*
* @return FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
* FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
*/
FLASH_Status FLASH_UserOptionByteConfig( uint16_t OB_IWDG, uint16_t OB_STOP, uint16_t OB_STDBY )
{
FLASH_Status status = FLASH_COMPLETE;
FLASH->OBKEYR = FLASH_KEY1;
FLASH->OBKEYR = FLASH_KEY2;
status = FLASH_WaitForLastOperation( ProgramTimeout );
if( status == FLASH_COMPLETE )
{
FLASH->CTLR |= CR_OPTPG_Set;
OB->USER = OB_IWDG | ( uint16_t )( OB_STOP | ( uint16_t )( OB_STDBY | ( ( uint16_t )0xF8 ) ) );
status = FLASH_WaitForLastOperation( ProgramTimeout );
if( status != FLASH_TIMEOUT )
{
FLASH->CTLR &= CR_OPTPG_Reset;
}
}
return status;
}
/*********************************************************************
* @fn FLASH_GetUserOptionByte
*
* @brief Returns the FLASH User Option Bytes values.
*
* @return The FLASH User Option Bytes values:IWDG_SW(Bit0), RST_STOP(Bit1)
* and RST_STDBY(Bit2).
*/
uint32_t FLASH_GetUserOptionByte( void )
{
return ( uint32_t )( FLASH->OBR >> 2 );
}
/*********************************************************************
* @fn FLASH_GetWriteProtectionOptionByte
*
* @brief Returns the FLASH Write Protection Option Bytes Register value.
*
* @return The FLASH Write Protection Option Bytes Register value.
*/
uint32_t FLASH_GetWriteProtectionOptionByte( void )
{
return ( uint32_t )( FLASH->WPR );
}
/*********************************************************************
* @fn FLASH_GetReadOutProtectionStatus
*
* @brief Checks whether the FLASH Read Out Protection Status is set or not.
*
* @return FLASH ReadOut Protection Status(SET or RESET)
*/
FlagStatus FLASH_GetReadOutProtectionStatus( void )
{
FlagStatus readoutstatus = RESET;
if( ( FLASH->OBR & RDPRT_Mask ) != ( uint32_t )RESET )
{
readoutstatus = SET;
}
else
{
readoutstatus = RESET;
}
return readoutstatus;
}
/*********************************************************************
* @fn FLASH_GetPrefetchBufferStatus
*
* @brief Checks whether the FLASH Prefetch Buffer status is set or not.
*
* @return FLASH ReadOut Protection Status(SET or RESET)
*/
FlagStatus FLASH_GetPrefetchBufferStatus( void )
{
FlagStatus bitstatus = RESET;
if( ( FLASH->ACTLR & ACR_PRFTBS_Mask ) != ( uint32_t )RESET )
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
/*********************************************************************
* @fn FLASH_ITConfig
*
* @brief Enables or disables the specified FLASH interrupts.
*
* @param FLASH_IT - specifies the FLASH interrupt sources to be enabled or disabled.
* FLASH_IT_ERROR - FLASH Error Interrupt
* FLASH_IT_EOP - FLASH end of operation Interrupt
* NewState - new state of the specified Flash interrupts(ENABLE or DISABLE).
*
* @return FLASH Prefetch Buffer Status (SET or RESET).
*/
void FLASH_ITConfig( uint32_t FLASH_IT, FunctionalState NewState )
{
if( NewState != DISABLE )
{
FLASH->CTLR |= FLASH_IT;
}
else
{
FLASH->CTLR &= ~( uint32_t )FLASH_IT;
}
}
/*********************************************************************
* @fn FLASH_GetFlagStatus
*
* @brief Checks whether the specified FLASH flag is set or not.
*
* @param FLASH_FLAG - specifies the FLASH flag to check.
* FLASH_FLAG_BSY - FLASH Busy flag
* FLASH_FLAG_PGERR - FLASH Program error flag
* FLASH_FLAG_WRPRTERR - FLASH Write protected error flag
* FLASH_FLAG_EOP - FLASH End of Operation flag
* FLASH_FLAG_OPTERR - FLASH Option Byte error flag
*
* @return The new state of FLASH_FLAG (SET or RESET).
*/
FlagStatus FLASH_GetFlagStatus( uint32_t FLASH_FLAG )
{
FlagStatus bitstatus = RESET;
if( FLASH_FLAG == FLASH_FLAG_OPTERR )
{
if( ( FLASH->OBR & FLASH_FLAG_OPTERR ) != ( uint32_t )RESET )
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
}
else
{
if( ( FLASH->STATR & FLASH_FLAG ) != ( uint32_t )RESET )
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
}
return bitstatus;
}
/*********************************************************************
* @fn FLASH_ClearFlag
*
* @brief Clears the FLASH's pending flags.
*
* @param FLASH_FLAG - specifies the FLASH flags to clear.
* FLASH_FLAG_PGERR - FLASH Program error flag
* FLASH_FLAG_WRPRTERR - FLASH Write protected error flag
* FLASH_FLAG_EOP - FLASH End of Operation flag
*
* @return none
*/
void FLASH_ClearFlag( uint32_t FLASH_FLAG )
{
FLASH->STATR = FLASH_FLAG;
}
/*********************************************************************
* @fn FLASH_GetStatus
*
* @brief Returns the FLASH Status.
*
* @return FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
* FLASH_ERROR_WRP or FLASH_COMPLETE.
*/
FLASH_Status FLASH_GetStatus( void )
{
FLASH_Status flashstatus = FLASH_COMPLETE;
if( ( FLASH->STATR & FLASH_FLAG_BSY ) == FLASH_FLAG_BSY )
{
flashstatus = FLASH_BUSY;
}
else
{
if( ( FLASH->STATR & FLASH_FLAG_PGERR ) != 0 )
{
flashstatus = FLASH_ERROR_PG;
}
else
{
if( ( FLASH->STATR & FLASH_FLAG_WRPRTERR ) != 0 )
{
flashstatus = FLASH_ERROR_WRP;
}
else
{
flashstatus = FLASH_COMPLETE;
}
}
}
return flashstatus;
}
/*********************************************************************
* @fn FLASH_GetBank1Status
*
* @brief Returns the FLASH Bank1 Status.
*
* @return FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
* FLASH_ERROR_WRP or FLASH_COMPLETE.
*/
FLASH_Status FLASH_GetBank1Status( void )
{
FLASH_Status flashstatus = FLASH_COMPLETE;
if( ( FLASH->STATR & FLASH_FLAG_BANK1_BSY ) == FLASH_FLAG_BSY )
{
flashstatus = FLASH_BUSY;
}
else
{
if( ( FLASH->STATR & FLASH_FLAG_BANK1_PGERR ) != 0 )
{
flashstatus = FLASH_ERROR_PG;
}
else
{
if( ( FLASH->STATR & FLASH_FLAG_BANK1_WRPRTERR ) != 0 )
{
flashstatus = FLASH_ERROR_WRP;
}
else
{
flashstatus = FLASH_COMPLETE;
}
}
}
return flashstatus;
}
/*********************************************************************
* @fn FLASH_WaitForLastOperation
*
* @brief Waits for a Flash operation to complete or a TIMEOUT to occur.
*
* @param Timeout - FLASH programming Timeout
*
* @return FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
* FLASH_ERROR_WRP or FLASH_COMPLETE.
*/
FLASH_Status FLASH_WaitForLastOperation( uint32_t Timeout )
{
FLASH_Status status = FLASH_COMPLETE;
status = FLASH_GetBank1Status();
while( ( status == FLASH_BUSY ) && ( Timeout != 0x00 ) )
{
status = FLASH_GetBank1Status();
Timeout--;
}
if( Timeout == 0x00 )
{
status = FLASH_TIMEOUT;
}
return status;
}
/*********************************************************************
* @fn FLASH_WaitForLastBank1Operation
*
* @brief Waits for a Flash operation on Bank1 to complete or a TIMEOUT to occur.
*
* @param Timeout - FLASH programming Timeout
*
* @return FLASH Status - The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
* FLASH_ERROR_WRP or FLASH_COMPLETE.
*/
FLASH_Status FLASH_WaitForLastBank1Operation( uint32_t Timeout )
{
FLASH_Status status = FLASH_COMPLETE;
status = FLASH_GetBank1Status();
while( ( status == FLASH_FLAG_BANK1_BSY ) && ( Timeout != 0x00 ) )
{
status = FLASH_GetBank1Status();
Timeout--;
}
if( Timeout == 0x00 )
{
status = FLASH_TIMEOUT;
}
return status;
}
/*********************************************************************
* @fn FLASH_Unlock_Fast
*
* @brief Unlocks the Fast Program Erase Mode.
*
* @return none
*/
void FLASH_Unlock_Fast( void )
{
/* Authorize the FPEC of Bank1 Access */
FLASH->KEYR = FLASH_KEY1;
FLASH->KEYR = FLASH_KEY2;
/* Fast program mode unlock */
FLASH->MODEKEYR = FLASH_KEY1;
FLASH->MODEKEYR = FLASH_KEY2;
}
/*********************************************************************
* @fn FLASH_Lock_Fast
*
* @brief Locks the Fast Program Erase Mode.
*
* @return none
*/
void FLASH_Lock_Fast( void )
{
FLASH->CTLR |= CR_LOCK_Set;
}
/*********************************************************************
* @fn FLASH_Unlock_Fast
*
* @brief Unlocks the Fast Program Erase Mode.
*
* @return none
*/
void FLASH_BufReset( void )
{
FLASH->CTLR |= CR_PAGE_PG;
FLASH->CTLR |= CR_BUF_RST;
while( FLASH->STATR & SR_BSY );
FLASH->CTLR &= ~CR_PAGE_PG;
}
/*********************************************************************
* @fn FLASH_BufLoad
*
* @brief Flash Buffer load(128 bit).
*
* @param Address - specifies the address to be programmed.
* Data0 - specifies the data0 to be programmed.
* Data1 - specifies the data1 to be programmed.
* Data2 - specifies the data2 to be programmed.
* Data3 - specifies the data3 to be programmed.
*
* @return none
*/
void FLASH_BufLoad( uint32_t Address, uint32_t Data0, uint32_t Data1, uint32_t Data2, uint32_t Data3 )
{
if( ( Address >= ValidAddrStart ) && ( Address < ValidAddrEnd ) )
{
FLASH->CTLR |= CR_PAGE_PG;
*( __IO uint32_t * )( Address + 0x00 ) = Data0;
*( __IO uint32_t * )( Address + 0x04 ) = Data1;
*( __IO uint32_t * )( Address + 0x08 ) = Data2;
*( __IO uint32_t * )( Address + 0x0C ) = Data3;
FLASH->CTLR |= CR_BUF_LOAD;
while( FLASH->STATR & SR_BSY );
FLASH->CTLR &= ~CR_PAGE_PG;
*( __IO uint32_t * )0x40022034 = *( __IO uint32_t * )( Address ^ 0x00000100 );
}
}
/*********************************************************************
* @fn FLASH_ErasePage_Fast
*
* @brief Erases a specified FLASH page (1page = 256Byte).
*
* @param Page_Address - The page address to be erased.
*
* @return none
*/
void FLASH_ErasePage_Fast( uint32_t Page_Address )
{
if( ( Page_Address >= ValidAddrStart ) && ( Page_Address < ValidAddrEnd ) )
{
FLASH->CTLR |= CR_PAGE_ER;
FLASH->ADDR = Page_Address;
FLASH->CTLR |= CR_STRT_Set;
while( FLASH->STATR & SR_BSY );
FLASH->CTLR &= ~CR_PAGE_ER;
*( __IO uint32_t * )0x40022034 = *( __IO uint32_t * )( Page_Address ^ 0x00000100 );
}
}
/*********************************************************************
* @fn FLASH_ProgramPage_Fast
*
* @brief Program a specified FLASH page (1page = 256Byte).
*
* @param Page_Address - The page address to be programed.
*
* @return none
*/
void FLASH_ProgramPage_Fast( uint32_t Page_Address )
{
if( ( Page_Address >= ValidAddrStart ) && ( Page_Address < ValidAddrEnd ) )
{
FLASH->CTLR |= CR_PAGE_PG;
FLASH->ADDR = Page_Address;
FLASH->CTLR |= CR_STRT_Set;
while( FLASH->STATR & SR_BSY );
FLASH->CTLR &= ~CR_PAGE_PG;
*( __IO uint32_t * )0x40022034 = *( __IO uint32_t * )( Page_Address ^ 0x00000100 );
}
}
@@ -0,0 +1,534 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : ch32f10x_gpio.c
* Author : WCH
* Version : V1.0.0
* Date : 2019/10/15
* Description : This file provides all the GPIO firmware functions.
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#include "ch32f10x_gpio.h"
#include "ch32f10x_rcc.h"
/* RCC registers bit address in the alias region */
#define AFIO_OFFSET (AFIO_BASE - PERIPH_BASE)
/* ECR Register */
/* Alias word address of EVOE bit */
#define ECR_OFFSET (AFIO_OFFSET + 0x00)
#define EVOE_BitNumber ((uint8_t)0x07)
#define ECR_EVOE_BB (PERIPH_BB_BASE + (ECR_OFFSET * 32) + (EVOE_BitNumber * 4))
/* PCFR1 Register */
/* Alias word address of MII_RMII_SEL bit */
#define PCFR1_OFFSET (AFIO_OFFSET + 0x04)
#define MII_RMII_SEL_BitNumber ((u8)0x17)
#define PCFR1_MII_RMII_SEL_BB (PERIPH_BB_BASE + (PCFR1_OFFSET * 32) + (MII_RMII_SEL_BitNumber * 4))
#define ECR_PORTPINCONFIG_MASK ((uint16_t)0xFF80)
#define LSB_MASK ((uint16_t)0xFFFF)
#define DBGAFR_POSITION_MASK ((uint32_t)0x000F0000)
#define DBGAFR_SWJCFG_MASK ((uint32_t)0xF0FFFFFF)
#define DBGAFR_LOCATION_MASK ((uint32_t)0x00200000)
#define DBGAFR_NUMBITS_MASK ((uint32_t)0x00100000)
/*********************************************************************
* @fn GPIO_DeInit
*
* @brief Deinitializes the GPIOx peripheral registers to their default
* reset values.
*
* @param GPIOx - where x can be (A..G) to select the GPIO peripheral.
*
* @return none
*/
void GPIO_DeInit( GPIO_TypeDef *GPIOx )
{
if( GPIOx == GPIOA )
{
RCC_APB2PeriphResetCmd( RCC_APB2Periph_GPIOA, ENABLE );
RCC_APB2PeriphResetCmd( RCC_APB2Periph_GPIOA, DISABLE );
}
else if( GPIOx == GPIOB )
{
RCC_APB2PeriphResetCmd( RCC_APB2Periph_GPIOB, ENABLE );
RCC_APB2PeriphResetCmd( RCC_APB2Periph_GPIOB, DISABLE );
}
else if( GPIOx == GPIOC )
{
RCC_APB2PeriphResetCmd( RCC_APB2Periph_GPIOC, ENABLE );
RCC_APB2PeriphResetCmd( RCC_APB2Periph_GPIOC, DISABLE );
}
else if( GPIOx == GPIOD )
{
RCC_APB2PeriphResetCmd( RCC_APB2Periph_GPIOD, ENABLE );
RCC_APB2PeriphResetCmd( RCC_APB2Periph_GPIOD, DISABLE );
}
else if( GPIOx == GPIOE )
{
RCC_APB2PeriphResetCmd( RCC_APB2Periph_GPIOE, ENABLE );
RCC_APB2PeriphResetCmd( RCC_APB2Periph_GPIOE, DISABLE );
}
else if( GPIOx == GPIOF )
{
RCC_APB2PeriphResetCmd( RCC_APB2Periph_GPIOF, ENABLE );
RCC_APB2PeriphResetCmd( RCC_APB2Periph_GPIOF, DISABLE );
}
else
{
if( GPIOx == GPIOG )
{
RCC_APB2PeriphResetCmd( RCC_APB2Periph_GPIOG, ENABLE );
RCC_APB2PeriphResetCmd( RCC_APB2Periph_GPIOG, DISABLE );
}
}
}
/*********************************************************************
* @fn GPIO_AFIODeInit
*
* @brief Deinitializes the Alternate Functions (remap, event control
* and EXTI configuration) registers to their default reset values.
*
* @return none
*/
void GPIO_AFIODeInit( void )
{
RCC_APB2PeriphResetCmd( RCC_APB2Periph_AFIO, ENABLE );
RCC_APB2PeriphResetCmd( RCC_APB2Periph_AFIO, DISABLE );
}
/*********************************************************************
* @fn GPIO_Init
*
* @brief GPIOx - where x can be (A..G) to select the GPIO peripheral.
*
* @param GPIO_InitStruct - pointer to a GPIO_InitTypeDef structure that
* contains the configuration information for the specified GPIO peripheral.
*
* @return none
*/
void GPIO_Init( GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_InitStruct )
{
uint32_t currentmode = 0x00, currentpin = 0x00, pinpos = 0x00, pos = 0x00;
uint32_t tmpreg = 0x00, pinmask = 0x00;
currentmode = ( ( uint32_t )GPIO_InitStruct->GPIO_Mode ) & ( ( uint32_t )0x0F );
if( ( ( ( uint32_t )GPIO_InitStruct->GPIO_Mode ) & ( ( uint32_t )0x10 ) ) != 0x00 )
{
currentmode |= ( uint32_t )GPIO_InitStruct->GPIO_Speed;
}
if( ( ( uint32_t )GPIO_InitStruct->GPIO_Pin & ( ( uint32_t )0x00FF ) ) != 0x00 )
{
tmpreg = GPIOx->CFGLR;
for( pinpos = 0x00; pinpos < 0x08; pinpos++ )
{
pos = ( ( uint32_t )0x01 ) << pinpos;
currentpin = ( GPIO_InitStruct->GPIO_Pin ) & pos;
if( currentpin == pos )
{
pos = pinpos << 2;
pinmask = ( ( uint32_t )0x0F ) << pos;
tmpreg &= ~pinmask;
tmpreg |= ( currentmode << pos );
if( GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD )
{
GPIOx->BCR = ( ( ( uint32_t )0x01 ) << pinpos );
}
else
{
if( GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU )
{
GPIOx->BSHR = ( ( ( uint32_t )0x01 ) << pinpos );
}
}
}
}
GPIOx->CFGLR = tmpreg;
}
if( GPIO_InitStruct->GPIO_Pin > 0x00FF )
{
tmpreg = GPIOx->CFGHR;
for( pinpos = 0x00; pinpos < 0x08; pinpos++ )
{
pos = ( ( ( uint32_t )0x01 ) << ( pinpos + 0x08 ) );
currentpin = ( ( GPIO_InitStruct->GPIO_Pin ) & pos );
if( currentpin == pos )
{
pos = pinpos << 2;
pinmask = ( ( uint32_t )0x0F ) << pos;
tmpreg &= ~pinmask;
tmpreg |= ( currentmode << pos );
if( GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD )
{
GPIOx->BCR = ( ( ( uint32_t )0x01 ) << ( pinpos + 0x08 ) );
}
if( GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU )
{
GPIOx->BSHR = ( ( ( uint32_t )0x01 ) << ( pinpos + 0x08 ) );
}
}
}
GPIOx->CFGHR = tmpreg;
}
}
/*********************************************************************
* @fn GPIO_StructInit
*
* @brief Fills each GPIO_InitStruct member with its default
*
* @param GPIO_InitStruct - pointer to a GPIO_InitTypeDef structure
* which will be initialized.
*
* @return none
*/
void GPIO_StructInit( GPIO_InitTypeDef *GPIO_InitStruct )
{
GPIO_InitStruct->GPIO_Pin = GPIO_Pin_All;
GPIO_InitStruct->GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStruct->GPIO_Mode = GPIO_Mode_IN_FLOATING;
}
/*********************************************************************
* @fn GPIO_ReadInputDataBit
*
* @brief GPIOx - where x can be (A..G) to select the GPIO peripheral.
*
* @param GPIO_Pin - specifies the port bit to read.
* This parameter can be GPIO_Pin_x where x can be (0..15).
*
* @return The input port pin value.
*/
uint8_t GPIO_ReadInputDataBit( GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin )
{
uint8_t bitstatus = 0x00;
if( ( GPIOx->INDR & GPIO_Pin ) != ( uint32_t )Bit_RESET )
{
bitstatus = ( uint8_t )Bit_SET;
}
else
{
bitstatus = ( uint8_t )Bit_RESET;
}
return bitstatus;
}
/*********************************************************************
* @fn GPIO_ReadInputData
*
* @brief Reads the specified GPIO input data port.
*
* @param GPIOx: where x can be (A..G) to select the GPIO peripheral.
*
* @return The input port pin value.
*/
uint16_t GPIO_ReadInputData( GPIO_TypeDef *GPIOx )
{
return ( ( uint16_t )GPIOx->INDR );
}
/*********************************************************************
* @fn GPIO_ReadOutputDataBit
*
* @brief Reads the specified output data port bit.
*
* @param GPIOx - where x can be (A..G) to select the GPIO peripheral.
* GPIO_Pin - specifies the port bit to read.
* This parameter can be GPIO_Pin_x where x can be (0..15).
*
* @return none
*/
uint8_t GPIO_ReadOutputDataBit( GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin )
{
uint8_t bitstatus = 0x00;
if( ( GPIOx->OUTDR & GPIO_Pin ) != ( uint32_t )Bit_RESET )
{
bitstatus = ( uint8_t )Bit_SET;
}
else
{
bitstatus = ( uint8_t )Bit_RESET;
}
return bitstatus;
}
/*********************************************************************
* @fn GPIO_ReadOutputData
*
* @brief Reads the specified GPIO output data port.
*
* @param GPIOx - where x can be (A..G) to select the GPIO peripheral.
*
* @return GPIO output port pin value.
*/
uint16_t GPIO_ReadOutputData( GPIO_TypeDef *GPIOx )
{
return ( ( uint16_t )GPIOx->OUTDR );
}
/*********************************************************************
* @fn GPIO_SetBits
*
* @brief Sets the selected data port bits.
*
* @param GPIOx - where x can be (A..G) to select the GPIO peripheral.
* GPIO_Pin - specifies the port bits to be written.
* This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
*
* @return none
*/
void GPIO_SetBits( GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin )
{
GPIOx->BSHR = GPIO_Pin;
}
/*********************************************************************
* @fn GPIO_ResetBits
*
* @brief Clears the selected data port bits.
*
* @param GPIOx - where x can be (A..G) to select the GPIO peripheral.
* GPIO_Pin - specifies the port bits to be written.
* This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
*
* @return none
*/
void GPIO_ResetBits( GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin )
{
GPIOx->BCR = GPIO_Pin;
}
/*********************************************************************
* @fn GPIO_WriteBit
*
* @brief Sets or clears the selected data port bit.
*
* @param GPIO_Pin - specifies the port bit to be written.
* This parameter can be one of GPIO_Pin_x where x can be (0..15).
* BitVal - specifies the value to be written to the selected bit.
* Bit_SetL - to clear the port pin.
* Bit_SetH - to set the port pin.
*
* @return none
*/
void GPIO_WriteBit( GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, BitAction BitVal )
{
if( BitVal != Bit_RESET )
{
GPIOx->BSHR = GPIO_Pin;
}
else
{
GPIOx->BCR = GPIO_Pin;
}
}
/*********************************************************************
* @fn GPIO_Write
*
* @brief Writes data to the specified GPIO data port.
*
* @param GPIOx - where x can be (A..G) to select the GPIO peripheral.
* PortVal - specifies the value to be written to the port output data register.
*
* @return none
*/
void GPIO_Write( GPIO_TypeDef *GPIOx, uint16_t PortVal )
{
GPIOx->OUTDR = PortVal;
}
/*********************************************************************
* @fn GPIO_PinLockConfig
*
* @brief Locks GPIO Pins configuration registers.
*
* @param GPIOx - where x can be (A..G) to select the GPIO peripheral.
* GPIO_Pin - specifies the port bit to be written.
* This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
*
* @return none
*/
void GPIO_PinLockConfig( GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin )
{
uint32_t tmp = 0x00010000;
tmp |= GPIO_Pin;
GPIOx->LCKR = tmp;
GPIOx->LCKR = GPIO_Pin;
GPIOx->LCKR = tmp;
tmp = GPIOx->LCKR;
tmp = GPIOx->LCKR;
}
/*********************************************************************
* @fn GPIO_EventOutputConfig
*
* @brief Selects the GPIO pin used as Event output.
*
* @param GPIO_PortSource - selects the GPIO port to be used as source
* for Event output.
* This parameter can be GPIO_PortSourceGPIOx where x can be (A..E).
* GPIO_PinSource - specifies the pin for the Event output.
* This parameter can be GPIO_PinSourcex where x can be (0..15).
*
* @return none
*/
void GPIO_EventOutputConfig( uint8_t GPIO_PortSource, uint8_t GPIO_PinSource )
{
uint32_t tmpreg = 0x00;
tmpreg = AFIO->ECR;
tmpreg &= ECR_PORTPINCONFIG_MASK;
tmpreg |= ( uint32_t )GPIO_PortSource << 0x04;
tmpreg |= GPIO_PinSource;
AFIO->ECR = tmpreg;
}
/*********************************************************************
* @fn GPIO_EventOutputCmd
*
* @brief Enables or disables the Event Output.
*
* @param NewState - ENABLE or DISABLE.
*
* @return none
*/
void GPIO_EventOutputCmd( FunctionalState NewState )
{
*( __IO uint32_t * ) ECR_EVOE_BB = ( uint32_t )NewState;
}
/*********************************************************************
* @fn GPIO_PinRemapConfig
*
* @brief Changes the mapping of the specified pin.
*
* @param GPIO_Remap - selects the pin to remap.
* GPIO_Remap_SPI1 - SPI1 Alternate Function mapping
* GPIO_Remap_I2C1 - I2C1 Alternate Function mapping
* GPIO_Remap_USART1 - USART1 Alternate Function mapping
* GPIO_Remap_USART2 - USART2 Alternate Function mapping
* GPIO_PartialRemap_USART3 - USART3 Partial Alternate Function mapping
* GPIO_FullRemap_USART3 - USART3 Full Alternate Function mapping
* GPIO_PartialRemap_TIM1 - TIM1 Partial Alternate Function mapping
* GPIO_FullRemap_TIM1 - TIM1 Full Alternate Function mapping
* GPIO_PartialRemap1_TIM2 - TIM2 Partial1 Alternate Function mapping
* GPIO_PartialRemap2_TIM2 - TIM2 Partial2 Alternate Function mapping
* GPIO_FullRemap_TIM2 - TIM2 Full Alternate Function mapping
* GPIO_PartialRemap_TIM3 - TIM3 Partial Alternate Function mapping
* GPIO_FullRemap_TIM3 - TIM3 Full Alternate Function mapping
* GPIO_Remap_TIM4 - TIM4 Alternate Function mapping
* GPIO_Remap1_CAN1 - CAN1 Alternate Function mapping
* GPIO_Remap2_CAN1 - CAN1 Alternate Function mapping
* GPIO_Remap_PD01 - PD01 Alternate Function mapping
* GPIO_Remap_ADC1_ETRGINJ - ADC1 External Trigger Injected Conversion remapping
* GPIO_Remap_ADC1_ETRGREG - ADC1 External Trigger Regular Conversion remapping
* GPIO_Remap_SWJ_NoJTRST - Full SWJ Enabled (JTAG-DP + SW-DP) but without JTRST
* GPIO_Remap_SWJ_JTAGDisable - JTAG-DP Disabled and SW-DP Enabled
* GPIO_Remap_SWJ_Disable - Full SWJ Disabled (JTAG-DP + SW-DP)
* GPIO_Remap_TIM2ITR1_PTP_SOF - Ethernet PTP output or USB OTG SOF (Start of Frame) connected
* connected to TIM2 Internal Trigger 1 for calibration (only for Connectivity line devices).If the
* is enabled the TIM2 ITR1 is connected to Ethernet PTP output. When Reset TIM2 ITR1 is connected
* to USB OTG SOF output.
* GPIO_Remap_TIM1_DMA: TIM1 DMA requests mapping (only for Value line devices)
* GPIO_Remap_TIM67_DAC_DMA: TIM6/TIM7 and DAC DMA requests remapping (only for High density Value line devices)
* GPIO_Remap_MISC: Miscellaneous Remap (DMA2 Channel5 Position and DAC Trigger remapping,
* only for High density Value line devices)
* NewState: ENABLE or DISABLE.
*
* @return none
*/
void GPIO_PinRemapConfig( uint32_t GPIO_Remap, FunctionalState NewState )
{
uint32_t tmp = 0x00, tmp1 = 0x00, tmpreg = 0x00, tmpmask = 0x00;
if( ( GPIO_Remap & 0x80000000 ) == 0x80000000 )
{
tmpreg = AFIO->PCFR2;
}
else
{
tmpreg = AFIO->PCFR1;
}
tmpmask = ( GPIO_Remap & DBGAFR_POSITION_MASK ) >> 0x10;
tmp = GPIO_Remap & LSB_MASK;
if( ( GPIO_Remap & ( DBGAFR_LOCATION_MASK | DBGAFR_NUMBITS_MASK ) ) == ( DBGAFR_LOCATION_MASK | DBGAFR_NUMBITS_MASK ) )
{
tmpreg &= DBGAFR_SWJCFG_MASK;
AFIO->PCFR1 &= DBGAFR_SWJCFG_MASK;
}
else if( ( GPIO_Remap & DBGAFR_NUMBITS_MASK ) == DBGAFR_NUMBITS_MASK )
{
tmp1 = ( ( uint32_t )0x03 ) << tmpmask;
tmpreg &= ~tmp1;
tmpreg |= ~DBGAFR_SWJCFG_MASK;
}
else
{
tmpreg &= ~( tmp << ( ( GPIO_Remap >> 0x15 ) * 0x10 ) );
tmpreg |= ~DBGAFR_SWJCFG_MASK;
}
if( NewState != DISABLE )
{
tmpreg |= ( tmp << ( ( GPIO_Remap >> 0x15 ) * 0x10 ) );
}
if( ( GPIO_Remap & 0x80000000 ) == 0x80000000 )
{
AFIO->PCFR2 = tmpreg;
}
else
{
AFIO->PCFR1 = tmpreg;
}
}
/*********************************************************************
* @fn GPIO_EXTILineConfig
*
* @brief Selects the GPIO pin used as EXTI Line.
*
* @param GPIO_PortSource - selects the GPIO port to be used as source for EXTI lines.
* This parameter can be GPIO_PortSourceGPIOx where x can be (A..G).
* GPIO_PinSource - specifies the EXTI line to be configured.
* This parameter can be GPIO_PinSourcex where x can be (0..15).
*
* @return none
*/
void GPIO_EXTILineConfig( uint8_t GPIO_PortSource, uint8_t GPIO_PinSource )
{
uint32_t tmp = 0x00;
tmp = ( ( uint32_t )0x0F ) << ( 0x04 * ( GPIO_PinSource & ( uint8_t )0x03 ) );
AFIO->EXTICR[GPIO_PinSource >> 0x02] &= ~tmp;
AFIO->EXTICR[GPIO_PinSource >> 0x02] |= ( ( ( uint32_t )GPIO_PortSource ) << ( 0x04 * ( GPIO_PinSource & ( uint8_t )0x03 ) ) );
}
@@ -0,0 +1,985 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : ch32f10x_i2c.c
* Author : WCH
* Version : V1.0.0
* Date : 2019/10/15
* Description : This file provides all the I2C firmware functions.
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#include "ch32f10x_i2c.h"
#include "ch32f10x_rcc.h"
/* I2C SPE mask */
#define CTLR1_PE_Set ((uint16_t)0x0001)
#define CTLR1_PE_Reset ((uint16_t)0xFFFE)
/* I2C START mask */
#define CTLR1_START_Set ((uint16_t)0x0100)
#define CTLR1_START_Reset ((uint16_t)0xFEFF)
/* I2C STOP mask */
#define CTLR1_STOP_Set ((uint16_t)0x0200)
#define CTLR1_STOP_Reset ((uint16_t)0xFDFF)
/* I2C ACK mask */
#define CTLR1_ACK_Set ((uint16_t)0x0400)
#define CTLR1_ACK_Reset ((uint16_t)0xFBFF)
/* I2C ENGC mask */
#define CTLR1_ENGC_Set ((uint16_t)0x0040)
#define CTLR1_ENGC_Reset ((uint16_t)0xFFBF)
/* I2C SWRST mask */
#define CTLR1_SWRST_Set ((uint16_t)0x8000)
#define CTLR1_SWRST_Reset ((uint16_t)0x7FFF)
/* I2C PEC mask */
#define CTLR1_PEC_Set ((uint16_t)0x1000)
#define CTLR1_PEC_Reset ((uint16_t)0xEFFF)
/* I2C ENPEC mask */
#define CTLR1_ENPEC_Set ((uint16_t)0x0020)
#define CTLR1_ENPEC_Reset ((uint16_t)0xFFDF)
/* I2C ENARP mask */
#define CTLR1_ENARP_Set ((uint16_t)0x0010)
#define CTLR1_ENARP_Reset ((uint16_t)0xFFEF)
/* I2C NOSTRETCH mask */
#define CTLR1_NOSTRETCH_Set ((uint16_t)0x0080)
#define CTLR1_NOSTRETCH_Reset ((uint16_t)0xFF7F)
/* I2C registers Masks */
#define CTLR1_CLEAR_Mask ((uint16_t)0xFBF5)
/* I2C DMAEN mask */
#define CTLR2_DMAEN_Set ((uint16_t)0x0800)
#define CTLR2_DMAEN_Reset ((uint16_t)0xF7FF)
/* I2C LAST mask */
#define CTLR2_LAST_Set ((uint16_t)0x1000)
#define CTLR2_LAST_Reset ((uint16_t)0xEFFF)
/* I2C FREQ mask */
#define CTLR2_FREQ_Reset ((uint16_t)0xFFC0)
/* I2C ADD0 mask */
#define OADDR1_ADD0_Set ((uint16_t)0x0001)
#define OADDR1_ADD0_Reset ((uint16_t)0xFFFE)
/* I2C ENDUAL mask */
#define OADDR2_ENDUAL_Set ((uint16_t)0x0001)
#define OADDR2_ENDUAL_Reset ((uint16_t)0xFFFE)
/* I2C ADD2 mask */
#define OADDR2_ADD2_Reset ((uint16_t)0xFF01)
/* I2C F/S mask */
#define CKCFGR_FS_Set ((uint16_t)0x8000)
/* I2C CCR mask */
#define CKCFGR_CCR_Set ((uint16_t)0x0FFF)
/* I2C FLAG mask */
#define FLAG_Mask ((uint32_t)0x00FFFFFF)
/* I2C Interrupt Enable mask */
#define ITEN_Mask ((uint32_t)0x07000000)
/*********************************************************************
* @fn I2C_DeInit
*
* @brief Deinitializes the I2Cx peripheral registers to their default
* reset values.
*
* @param I2Cx - where x can be 1 or 2 to select the I2C peripheral.
*
* @return none
*/
void I2C_DeInit( I2C_TypeDef *I2Cx )
{
if( I2Cx == I2C1 )
{
RCC_APB1PeriphResetCmd( RCC_APB1Periph_I2C1, ENABLE );
RCC_APB1PeriphResetCmd( RCC_APB1Periph_I2C1, DISABLE );
}
else
{
RCC_APB1PeriphResetCmd( RCC_APB1Periph_I2C2, ENABLE );
RCC_APB1PeriphResetCmd( RCC_APB1Periph_I2C2, DISABLE );
}
}
/*********************************************************************
* @fn I2C_Init
*
* @brief Initializes the I2Cx peripheral according to the specified
* parameters in the I2C_InitStruct.
* @param I2Cx - where x can be 1 or 2 to select the I2C peripheral.
* I2C_InitStruct - pointer to a I2C_InitTypeDef structure that
* contains the configuration information for the specified I2C peripheral.
*
* @return none
*/
void I2C_Init( I2C_TypeDef *I2Cx, I2C_InitTypeDef *I2C_InitStruct )
{
uint16_t tmpreg = 0, freqrange = 0;
uint16_t result = 0x04;
uint32_t pclk1 = 8000000;
RCC_ClocksTypeDef rcc_clocks;
tmpreg = I2Cx->CTLR2;
tmpreg &= CTLR2_FREQ_Reset;
RCC_GetClocksFreq( &rcc_clocks );
pclk1 = rcc_clocks.PCLK1_Frequency;
freqrange = ( uint16_t )( pclk1 / 1000000 );
tmpreg |= freqrange;
I2Cx->CTLR2 = tmpreg;
I2Cx->CTLR1 &= CTLR1_PE_Reset;
tmpreg = 0;
if( I2C_InitStruct->I2C_ClockSpeed <= 100000 )
{
result = ( uint16_t )( pclk1 / ( I2C_InitStruct->I2C_ClockSpeed << 1 ) );
if( result < 0x04 )
{
result = 0x04;
}
tmpreg |= result;
I2Cx->RTR = freqrange + 1;
}
else
{
if( I2C_InitStruct->I2C_DutyCycle == I2C_DutyCycle_2 )
{
result = ( uint16_t )( pclk1 / ( I2C_InitStruct->I2C_ClockSpeed * 3 ) );
}
else
{
result = ( uint16_t )( pclk1 / ( I2C_InitStruct->I2C_ClockSpeed * 25 ) );
result |= I2C_DutyCycle_16_9;
}
if( ( result & CKCFGR_CCR_Set ) == 0 )
{
result |= ( uint16_t )0x0001;
}
tmpreg |= ( uint16_t )( result | CKCFGR_FS_Set );
I2Cx->RTR = ( uint16_t )( ( ( freqrange * ( uint16_t )300 ) / ( uint16_t )1000 ) + ( uint16_t )1 );
}
I2Cx->CKCFGR = tmpreg;
I2Cx->CTLR1 |= CTLR1_PE_Set;
tmpreg = I2Cx->CTLR1;
tmpreg &= CTLR1_CLEAR_Mask;
tmpreg |= ( uint16_t )( ( uint32_t )I2C_InitStruct->I2C_Mode | I2C_InitStruct->I2C_Ack );
I2Cx->CTLR1 = tmpreg;
I2Cx->OADDR1 = ( I2C_InitStruct->I2C_AcknowledgedAddress | I2C_InitStruct->I2C_OwnAddress1 );
}
/*********************************************************************
* @fn I2C_StructInit
*
* @brief Fills each I2C_InitStruct member with its default value.
*
* @param I2C_InitStruct - pointer to an I2C_InitTypeDef structure which
* will be initialized.
*
* @return none
*/
void I2C_StructInit( I2C_InitTypeDef *I2C_InitStruct )
{
I2C_InitStruct->I2C_ClockSpeed = 5000;
I2C_InitStruct->I2C_Mode = I2C_Mode_I2C;
I2C_InitStruct->I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStruct->I2C_OwnAddress1 = 0;
I2C_InitStruct->I2C_Ack = I2C_Ack_Disable;
I2C_InitStruct->I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
}
/*********************************************************************
* @fn I2C_Cmd
*
* @brief Enables or disables the specified I2C peripheral.
*
* @param I2Cx - where x can be 1 or 2 to select the I2C peripheral.
* NewState - ENABLE or DISABLE.
*
* @return none
*/
void I2C_Cmd( I2C_TypeDef *I2Cx, FunctionalState NewState )
{
if( NewState != DISABLE )
{
I2Cx->CTLR1 |= CTLR1_PE_Set;
}
else
{
I2Cx->CTLR1 &= CTLR1_PE_Reset;
}
}
/*********************************************************************
* @fn I2C_DMACmd
*
* @brief Enables or disables the specified I2C DMA requests.
*
* @param I2Cx - where x can be 1 or 2 to select the I2C peripheral.
* NewState - ENABLE or DISABLE.
*
* @return none
*/
void I2C_DMACmd( I2C_TypeDef *I2Cx, FunctionalState NewState )
{
if( NewState != DISABLE )
{
I2Cx->CTLR2 |= CTLR2_DMAEN_Set;
}
else
{
I2Cx->CTLR2 &= CTLR2_DMAEN_Reset;
}
}
/*********************************************************************
* @fn I2C_DMALastTransferCmd
*
* @brief Specifies if the next DMA transfer will be the last one.
*
* @param I2Cx - where x can be 1 or 2 to select the I2C peripheral.
* NewState - ENABLE or DISABLE.
*
* @return none
*/
void I2C_DMALastTransferCmd( I2C_TypeDef *I2Cx, FunctionalState NewState )
{
if( NewState != DISABLE )
{
I2Cx->CTLR2 |= CTLR2_LAST_Set;
}
else
{
I2Cx->CTLR2 &= CTLR2_LAST_Reset;
}
}
/*********************************************************************
* @fn I2C_GenerateSTART
*
* @brief Generates I2Cx communication START condition.
*
* @param I2Cx - where x can be 1 or 2 to select the I2C peripheral.
* NewState - ENABLE or DISABLE.
*
* @return none
*/
void I2C_GenerateSTART( I2C_TypeDef *I2Cx, FunctionalState NewState )
{
if( NewState != DISABLE )
{
I2Cx->CTLR1 |= CTLR1_START_Set;
}
else
{
I2Cx->CTLR1 &= CTLR1_START_Reset;
}
}
/*********************************************************************
* @fn I2C_GenerateSTOP
*
* @brief Generates I2Cx communication STOP condition.
*
* @param I2Cx - where x can be 1 or 2 to select the I2C peripheral.
* NewState - ENABLE or DISABLE.
*
* @return none
*/
void I2C_GenerateSTOP( I2C_TypeDef *I2Cx, FunctionalState NewState )
{
if( NewState != DISABLE )
{
I2Cx->CTLR1 |= CTLR1_STOP_Set;
}
else
{
I2Cx->CTLR1 &= CTLR1_STOP_Reset;
}
}
/*********************************************************************
* @fn I2C_AcknowledgeConfig
*
* @brief Enables or disables the specified I2C acknowledge feature.
*
* @param I2Cx - where x can be 1 or 2 to select the I2C peripheral.
* NewState - ENABLE or DISABLE.
*
* @return none
*/
void I2C_AcknowledgeConfig( I2C_TypeDef *I2Cx, FunctionalState NewState )
{
if( NewState != DISABLE )
{
I2Cx->CTLR1 |= CTLR1_ACK_Set;
}
else
{
I2Cx->CTLR1 &= CTLR1_ACK_Reset;
}
}
/*********************************************************************
* @fn I2C_OwnAddress2Config
*
* @brief Configures the specified I2C own address2.
*
* @param I2Cx - where x can be 1 or 2 to select the I2C peripheral.
* Address - specifies the 7bit I2C own address2.
*
* @return none
*/
void I2C_OwnAddress2Config( I2C_TypeDef *I2Cx, uint8_t Address )
{
uint16_t tmpreg = 0;
tmpreg = I2Cx->OADDR2;
tmpreg &= OADDR2_ADD2_Reset;
tmpreg |= ( uint16_t )( ( uint16_t )Address & ( uint16_t )0x00FE );
I2Cx->OADDR2 = tmpreg;
}
/*********************************************************************
* @fn I2C_DualAddressCmd
*
* @brief Enables or disables the specified I2C dual addressing mode.
*
* @param I2Cx - where x can be 1 or 2 to select the I2C peripheral.
* NewState - ENABLE or DISABLE.
*
* @return none
*/
void I2C_DualAddressCmd( I2C_TypeDef *I2Cx, FunctionalState NewState )
{
if( NewState != DISABLE )
{
I2Cx->OADDR2 |= OADDR2_ENDUAL_Set;
}
else
{
I2Cx->OADDR2 &= OADDR2_ENDUAL_Reset;
}
}
/*********************************************************************
* @fn I2C_GeneralCallCmd
*
* @brief Enables or disables the specified I2C general call feature.
*
* @param I2Cx - where x can be 1 or 2 to select the I2C peripheral.
* NewState - ENABLE or DISABLE.
*
* @return none
*/
void I2C_GeneralCallCmd( I2C_TypeDef *I2Cx, FunctionalState NewState )
{
if( NewState != DISABLE )
{
I2Cx->CTLR1 |= CTLR1_ENGC_Set;
}
else
{
I2Cx->CTLR1 &= CTLR1_ENGC_Reset;
}
}
/*********************************************************************
* @fn I2C_ITConfig
*
* @brief Enables or disables the specified I2C interrupts.
*
* @param I2Cx - where x can be 1 or 2 to select the I2C peripheral.
* I2C_IT - specifies the I2C interrupts sources to be enabled or disabled.
* I2C_IT_BUF - Buffer interrupt mask.
* I2C_IT_EVT - Event interrupt mask.
* I2C_IT_ERR - Error interrupt mask.
* NewState - ENABLE or DISABLE.
*
* @return none
*/
void I2C_ITConfig( I2C_TypeDef *I2Cx, uint16_t I2C_IT, FunctionalState NewState )
{
if( NewState != DISABLE )
{
I2Cx->CTLR2 |= I2C_IT;
}
else
{
I2Cx->CTLR2 &= ( uint16_t )~I2C_IT;
}
}
/*********************************************************************
* @fn I2C_SendData
*
* @brief Sends a data byte through the I2Cx peripheral.
*
* @param I2Cx - where x can be 1 or 2 to select the I2C peripheral.
* Data - Byte to be transmitted.
*
* @return none
*/
void I2C_SendData( I2C_TypeDef *I2Cx, uint8_t Data )
{
I2Cx->DATAR = Data;
}
/*********************************************************************
* @fn I2C_ReceiveData
*
* @brief Returns the most recent received data by the I2Cx peripheral.
*
* @param I2Cx - where x can be 1 or 2 to select the I2C peripheral.
*
* @return The value of the received data.
*/
uint8_t I2C_ReceiveData( I2C_TypeDef *I2Cx )
{
return ( uint8_t )I2Cx->DATAR;
}
/*********************************************************************
* @fn I2C_Send7bitAddress
*
* @brief Transmits the address byte to select the slave device.
*
* @param I2Cx - where x can be 1 or 2 to select the I2C peripheral.
* Address - specifies the slave address which will be transmitted.
* I2C_Direction - specifies whether the I2C device will be a
* Transmitter or a Receiver.
* I2C_Direction_Transmitter - Transmitter mode.
* I2C_Direction_Receiver - Receiver mode.
*
* @return none
*/
void I2C_Send7bitAddress( I2C_TypeDef *I2Cx, uint8_t Address, uint8_t I2C_Direction )
{
if( I2C_Direction != I2C_Direction_Transmitter )
{
Address |= OADDR1_ADD0_Set;
}
else
{
Address &= OADDR1_ADD0_Reset;
}
I2Cx->DATAR = Address;
}
/*********************************************************************
* @fn I2C_ReadRegister
*
* @brief Reads the specified I2C register and returns its value.
*
* @param I2Cx - where x can be 1 or 2 to select the I2C peripheral.
* I2C_Register - specifies the register to read.
* I2C_Register_CTLR1.
* I2C_Register_CTLR2.
* I2C_Register_OADDR1.
* I2C_Register_OADDR2.
* I2C_Register_DATAR.
* I2C_Register_STAR1.
* I2C_Register_STAR2.
* I2C_Register_CKCFGR.
* I2C_Register_RTR.
*
* @return none
*/
uint16_t I2C_ReadRegister( I2C_TypeDef *I2Cx, uint8_t I2C_Register )
{
__IO uint32_t tmp = 0;
tmp = ( uint32_t ) I2Cx;
tmp += I2C_Register;
return ( *( __IO uint16_t * ) tmp );
}
/*********************************************************************
* @fn I2C_SoftwareResetCmd
*
* @brief Enables or disables the specified I2C software reset.
*
* @param I2Cx - where x can be 1 or 2 to select the I2C peripheral.
* NewState - ENABLE or DISABLE.
*
* @return none
*/
void I2C_SoftwareResetCmd( I2C_TypeDef *I2Cx, FunctionalState NewState )
{
if( NewState != DISABLE )
{
I2Cx->CTLR1 |= CTLR1_SWRST_Set;
}
else
{
I2Cx->CTLR1 &= CTLR1_SWRST_Reset;
}
}
/*********************************************************************
* @fn I2C_NACKPositionConfig
*
* @brief Selects the specified I2C NACK position in master receiver mode.
*
* @param I2Cx - where x can be 1 or 2 to select the I2C peripheral.
* I2C_NACKPosition - specifies the NACK position.
* I2C_NACKPosition_Next - indicates that the next byte will be
* the last received byte.
* I2C_NACKPosition_Current - indicates that current byte is the
* last received byte.
*
* @return none
*/
void I2C_NACKPositionConfig( I2C_TypeDef *I2Cx, uint16_t I2C_NACKPosition )
{
if( I2C_NACKPosition == I2C_NACKPosition_Next )
{
I2Cx->CTLR1 |= I2C_NACKPosition_Next;
}
else
{
I2Cx->CTLR1 &= I2C_NACKPosition_Current;
}
}
/*********************************************************************
* @fn I2C_SMBusAlertConfig
*
* @brief Drives the SMBusAlert pin high or low for the specified I2C.
*
* @param I2Cx - where x can be 1 or 2 to select the I2C peripheral.
* I2C_SMBusAlert - specifies SMBAlert pin level.
* I2C_SMBusAlert_Low - SMBAlert pin driven low.
* I2C_SMBusAlert_High - SMBAlert pin driven high.
*
* @return none
*/
void I2C_SMBusAlertConfig( I2C_TypeDef *I2Cx, uint16_t I2C_SMBusAlert )
{
if( I2C_SMBusAlert == I2C_SMBusAlert_Low )
{
I2Cx->CTLR1 |= I2C_SMBusAlert_Low;
}
else
{
I2Cx->CTLR1 &= I2C_SMBusAlert_High;
}
}
/*********************************************************************
* @fn I2C_TransmitPEC
*
* @brief Enables or disables the specified I2C PEC transfer.
*
* @param I2Cx - where x can be 1 or 2 to select the I2C peripheral.
* NewState - ENABLE or DISABLE.
*
* @return none
*/
void I2C_TransmitPEC( I2C_TypeDef *I2Cx, FunctionalState NewState )
{
if( NewState != DISABLE )
{
I2Cx->CTLR1 |= CTLR1_PEC_Set;
}
else
{
I2Cx->CTLR1 &= CTLR1_PEC_Reset;
}
}
/*********************************************************************
* @fn I2C_PECPositionConfig
*
* @brief Selects the specified I2C PEC position.
*
* @param I2Cx - where x can be 1 or 2 to select the I2C peripheral.
* I2C_PECPosition - specifies the PEC position.
* I2C_PECPosition_Next - indicates that the next byte is PEC.
* I2C_PECPosition_Current - indicates that current byte is PEC.
*
* @return none
*/
void I2C_PECPositionConfig( I2C_TypeDef *I2Cx, uint16_t I2C_PECPosition )
{
if( I2C_PECPosition == I2C_PECPosition_Next )
{
I2Cx->CTLR1 |= I2C_PECPosition_Next;
}
else
{
I2Cx->CTLR1 &= I2C_PECPosition_Current;
}
}
/*********************************************************************
* @fn I2C_CalculatePEC
*
* @brief Enables or disables the PEC value calculation of the transferred bytes.
*
* @param I2Cx- where x can be 1 or 2 to select the I2C peripheral.
* NewState - ENABLE or DISABLE.
*
* @return none
*/
void I2C_CalculatePEC( I2C_TypeDef *I2Cx, FunctionalState NewState )
{
if( NewState != DISABLE )
{
I2Cx->CTLR1 |= CTLR1_ENPEC_Set;
}
else
{
I2Cx->CTLR1 &= CTLR1_ENPEC_Reset;
}
}
/*********************************************************************
* @fn I2C_GetPEC
*
* @brief Returns the PEC value for the specified I2C.
*
* @param I2Cx - where x can be 1 or 2 to select the I2C peripheral.
*
* @return The PEC value.
*/
uint8_t I2C_GetPEC( I2C_TypeDef *I2Cx )
{
return ( ( I2Cx->STAR2 ) >> 8 );
}
/*********************************************************************
* @fn I2C_ARPCmd
*
* @brief Enables or disables the specified I2C ARP.
*
* @param I2Cx - where x can be 1 or 2 to select the I2C peripheral.
* NewState - ENABLE or DISABLE.
*
* @return The PEC value.
*/
void I2C_ARPCmd( I2C_TypeDef *I2Cx, FunctionalState NewState )
{
if( NewState != DISABLE )
{
I2Cx->CTLR1 |= CTLR1_ENARP_Set;
}
else
{
I2Cx->CTLR1 &= CTLR1_ENARP_Reset;
}
}
/*********************************************************************
* @fn I2C_StretchClockCmd
*
* @brief Enables or disables the specified I2C Clock stretching.
*
* @param I2Cx - where x can be 1 or 2 to select the I2C peripheral.
* NewState - ENABLE or DISABLE.
*
* @return none
*/
void I2C_StretchClockCmd( I2C_TypeDef *I2Cx, FunctionalState NewState )
{
if( NewState == DISABLE )
{
I2Cx->CTLR1 |= CTLR1_NOSTRETCH_Set;
}
else
{
I2Cx->CTLR1 &= CTLR1_NOSTRETCH_Reset;
}
}
/*********************************************************************
* @fn I2C_FastModeDutyCycleConfig
*
* @brief Selects the specified I2C fast mode duty cycle.
*
* @param I2Cx - where x can be 1 or 2 to select the I2C peripheral.
* I2C_DutyCycle - specifies the fast mode duty cycle.
* I2C_DutyCycle_2 - I2C fast mode Tlow/Thigh = 2.
* I2C_DutyCycle_16_9 - I2C fast mode Tlow/Thigh = 16/9.
*
* @return none
*/
void I2C_FastModeDutyCycleConfig( I2C_TypeDef *I2Cx, uint16_t I2C_DutyCycle )
{
if( I2C_DutyCycle != I2C_DutyCycle_16_9 )
{
I2Cx->CKCFGR &= I2C_DutyCycle_2;
}
else
{
I2Cx->CKCFGR |= I2C_DutyCycle_16_9;
}
}
/*********************************************************************
* @fn I2C_CheckEvent
*
* @brief Checks whether the last I2Cx Event is equal to the one passed
* as parameter.
*
* @param I2Cx- where x can be 1 or 2 to select the I2C peripheral.
* I2C_EVENT: specifies the event to be checked.
* I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED - EV1.
* I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED - EV1.
* I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED - EV1.
* I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED - EV1.
* I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED - EV1.
* I2C_EVENT_SLAVE_BYTE_RECEIVED - EV2.
* (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_DUALF) - EV2.
* (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_FLAG_GENCALL) - EV2.
* I2C_EVENT_SLAVE_BYTE_TRANSMITTED - EV3.
* (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_DUALF) - EV3.
* (I2C_EVENT_SLAVE_BYTE_TRANSMITTED | I2C_FLAG_GENCALL) - EV3.
* I2C_EVENT_SLAVE_ACK_FAILURE - EV3_2.
* I2C_EVENT_SLAVE_STOP_DETECTED - EV4.
* I2C_EVENT_MASTER_MODE_SELECT - EV5.
* I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED - EV6.
* I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED - EV6.
* I2C_EVENT_MASTER_BYTE_RECEIVED - EV7.
* I2C_EVENT_MASTER_BYTE_TRANSMITTING - EV8.
* I2C_EVENT_MASTER_BYTE_TRANSMITTED - EV8_2.
* I2C_EVENT_MASTER_MODE_ADDRESS10 - EV9.
*
* @return ErrorStatus - SUCCESS or ERROR.
*/
ErrorStatus I2C_CheckEvent( I2C_TypeDef *I2Cx, uint32_t I2C_EVENT )
{
uint32_t lastevent = 0;
uint32_t flag1 = 0, flag2 = 0;
ErrorStatus status = ERROR;
flag1 = I2Cx->STAR1;
flag2 = I2Cx->STAR2;
flag2 = flag2 << 16;
lastevent = ( flag1 | flag2 ) & FLAG_Mask;
if( ( lastevent & I2C_EVENT ) == I2C_EVENT )
{
status = SUCCESS;
}
else
{
status = ERROR;
}
return status;
}
/*********************************************************************
* @fn I2C_GetLastEvent
*
* @brief Returns the last I2Cx Event.
*
* @param I2Cx - where x can be 1 or 2 to select the I2C peripheral.
*
* @return none
*/
uint32_t I2C_GetLastEvent( I2C_TypeDef *I2Cx )
{
uint32_t lastevent = 0;
uint32_t flag1 = 0, flag2 = 0;
flag1 = I2Cx->STAR1;
flag2 = I2Cx->STAR2;
flag2 = flag2 << 16;
lastevent = ( flag1 | flag2 ) & FLAG_Mask;
return lastevent;
}
/*********************************************************************
* @fn I2C_GetFlagStatus
*
* @brief Checks whether the last I2Cx Event is equal to the one passed
* as parameter.
*
* @param I2Cx - where x can be 1 or 2 to select the I2C peripheral.
* I2C_FLAG - specifies the flag to check.
* I2C_FLAG_DUALF - Dual flag (Slave mode).
* I2C_FLAG_SMBHOST - SMBus host header (Slave mode).
* I2C_FLAG_SMBDEFAULT - SMBus default header (Slave mode).
* I2C_FLAG_GENCALL - General call header flag (Slave mode).
* I2C_FLAG_TRA - Transmitter/Receiver flag.
* I2C_FLAG_BUSY - Bus busy flag.
* I2C_FLAG_MSL - Master/Slave flag.
* I2C_FLAG_SMBALERT - SMBus Alert flag.
* I2C_FLAG_TIMEOUT - Timeout or Tlow error flag.
* I2C_FLAG_PECERR - PEC error in reception flag.
* I2C_FLAG_OVR - Overrun/Underrun flag (Slave mode).
* I2C_FLAG_AF - Acknowledge failure flag.
* I2C_FLAG_ARLO - Arbitration lost flag (Master mode).
* I2C_FLAG_BERR - Bus error flag.
* I2C_FLAG_TXE - Data register empty flag (Transmitter).
* I2C_FLAG_RXNE- Data register not empty (Receiver) flag.
* I2C_FLAG_STOPF - Stop detection flag (Slave mode).
* I2C_FLAG_ADD10 - 10-bit header sent flag (Master mode).
* I2C_FLAG_BTF - Byte transfer finished flag.
* I2C_FLAG_ADDR - Address sent flag (Master mode) "ADSL"
* Address matched flag (Slave mode)"ENDA".
* I2C_FLAG_SB - Start bit flag (Master mode).
*
* @return FlagStatus - SET or RESET.
*/
FlagStatus I2C_GetFlagStatus( I2C_TypeDef *I2Cx, uint32_t I2C_FLAG )
{
FlagStatus bitstatus = RESET;
__IO uint32_t i2creg = 0, i2cxbase = 0;
i2cxbase = ( uint32_t )I2Cx;
i2creg = I2C_FLAG >> 28;
I2C_FLAG &= FLAG_Mask;
if( i2creg != 0 )
{
i2cxbase += 0x14;
}
else
{
I2C_FLAG = ( uint32_t )( I2C_FLAG >> 16 );
i2cxbase += 0x18;
}
if( ( ( *( __IO uint32_t * )i2cxbase ) & I2C_FLAG ) != ( uint32_t )RESET )
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
/*********************************************************************
* @fn I2C_ClearFlag
*
* @brief Clears the I2Cx's pending flags.
*
* @param I2Cx - where x can be 1 or 2 to select the I2C peripheral.
* I2C_FLAG - specifies the flag to clear.
* I2C_FLAG_SMBALERT - SMBus Alert flag.
* I2C_FLAG_TIMEOUT - Timeout or Tlow error flag.
* I2C_FLAG_PECERR - PEC error in reception flag.
* I2C_FLAG_OVR - Overrun/Underrun flag (Slave mode).
* I2C_FLAG_AF - Acknowledge failure flag.
* I2C_FLAG_ARLO - Arbitration lost flag (Master mode).
* I2C_FLAG_BERR - Bus error flag.
*
* @return none
*/
void I2C_ClearFlag( I2C_TypeDef *I2Cx, uint32_t I2C_FLAG )
{
uint32_t flagpos = 0;
flagpos = I2C_FLAG & FLAG_Mask;
I2Cx->STAR1 = ( uint16_t )~flagpos;
}
/*********************************************************************
* @fn I2C_GetITStatus
*
* @brief Checks whether the specified I2C interrupt has occurred or not.
*
* @param I2Cx - where x can be 1 or 2 to select the I2C peripheral.
* II2C_IT - specifies the interrupt source to check.
* I2C_IT_SMBALERT - SMBus Alert flag.
* I2C_IT_TIMEOUT - Timeout or Tlow error flag.
* I2C_IT_PECERR - PEC error in reception flag.
* I2C_IT_OVR - Overrun/Underrun flag (Slave mode).
* I2C_IT_AF - Acknowledge failure flag.
* I2C_IT_ARLO - Arbitration lost flag (Master mode).
* I2C_IT_BERR - Bus error flag.
* I2C_IT_TXE - Data register empty flag (Transmitter).
* I2C_IT_RXNE - Data register not empty (Receiver) flag.
* I2C_IT_STOPF - Stop detection flag (Slave mode).
* I2C_IT_ADD10 - 10-bit header sent flag (Master mode).
* I2C_IT_BTF - Byte transfer finished flag.
* I2C_IT_ADDR - Address sent flag (Master mode) "ADSL" Address matched
* flag (Slave mode)"ENDAD".
* I2C_IT_SB - Start bit flag (Master mode).
*
* @return none
*/
ITStatus I2C_GetITStatus( I2C_TypeDef *I2Cx, uint32_t I2C_IT )
{
ITStatus bitstatus = RESET;
uint32_t enablestatus = 0;
enablestatus = ( uint32_t )( ( ( I2C_IT & ITEN_Mask ) >> 16 ) & ( I2Cx->CTLR2 ) ) ;
I2C_IT &= FLAG_Mask;
if( ( ( I2Cx->STAR1 & I2C_IT ) != ( uint32_t )RESET ) && enablestatus )
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
/*********************************************************************
* @fn I2C_ClearITPendingBit
*
* @brief Clears the I2Cx interrupt pending bits.
*
* @param I2Cx - where x can be 1 or 2 to select the I2C peripheral.
* I2C_IT - specifies the interrupt pending bit to clear.
* I2C_IT_SMBALERT - SMBus Alert interrupt.
* I2C_IT_TIMEOUT - Timeout or Tlow error interrupt.
* I2C_IT_PECERR - PEC error in reception interrupt.
* I2C_IT_OVR - Overrun/Underrun interrupt (Slave mode).
* I2C_IT_AF - Acknowledge failure interrupt.
* I2C_IT_ARLO - Arbitration lost interrupt (Master mode).
* I2C_IT_BERR - Bus error interrupt.
*
* @return none
*/
void I2C_ClearITPendingBit( I2C_TypeDef *I2Cx, uint32_t I2C_IT )
{
uint32_t flagpos = 0;
flagpos = I2C_IT & FLAG_Mask;
I2Cx->STAR1 = ( uint16_t )~flagpos;
}
@@ -0,0 +1,125 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : ch32f10x_iwdg.c
* Author : WCH
* Version : V1.0.0
* Date : 2019/10/15
* Description : This file provides all the IWDG firmware functions.
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#include "ch32f10x_iwdg.h"
/* CTLR register bit mask */
#define CTLR_KEY_Reload ((uint16_t)0xAAAA)
#define CTLR_KEY_Enable ((uint16_t)0xCCCC)
/*********************************************************************
* @fn IWDG_WriteAccessCmd
*
* @brief Enables or disables write access to IWDG_PSCR and IWDG_RLDR registers.
*
* @param WDG_WriteAccess - new state of write access to IWDG_PSCR and
* IWDG_RLDR registers.
* IWDG_WriteAccess_Enable - Enable write access to IWDG_PSCR and
* IWDG_RLDR registers.
* IWDG_WriteAccess_Disable - Disable write access to IWDG_PSCR
* and IWDG_RLDR registers.
*
* @return none
*/
void IWDG_WriteAccessCmd( uint16_t IWDG_WriteAccess )
{
IWDG->CTLR = IWDG_WriteAccess;
}
/*********************************************************************
* @fn IWDG_SetPrescaler
*
* @brief Sets IWDG Prescaler value.
*
* @param IWDG_Prescaler - specifies the IWDG Prescaler value.
* IWDG_Prescaler_4 - IWDG prescaler set to 4.
* IWDG_Prescaler_8 - IWDG prescaler set to 8.
* IWDG_Prescaler_16 - IWDG prescaler set to 16.
* IWDG_Prescaler_32 - IWDG prescaler set to 32.
* IWDG_Prescaler_64 - IWDG prescaler set to 64.
* IWDG_Prescaler_128 - IWDG prescaler set to 128.
* IWDG_Prescaler_256 - IWDG prescaler set to 256.
*
* @return none
*/
void IWDG_SetPrescaler( uint8_t IWDG_Prescaler )
{
IWDG->PSCR = IWDG_Prescaler;
}
/*********************************************************************
* @fn IWDG_SetReload
*
* @brief Sets IWDG Reload value.
*
* @param Reload - specifies the IWDG Reload value.
* This parameter must be a number between 0 and 0x0FFF.
*
* @return none
*/
void IWDG_SetReload( uint16_t Reload )
{
IWDG->RLDR = Reload;
}
/*********************************************************************
* @fn IWDG_ReloadCounter
*
* @brief Reloads IWDG counter with value defined in the reload register.
*
* @return none
*/
void IWDG_ReloadCounter( void )
{
IWDG->CTLR = CTLR_KEY_Reload;
}
/*********************************************************************
* @fn IWDG_Enable
*
* @brief Enables IWDG (write access to IWDG_PSCR and IWDG_RLDR registers disabled).
*
* @return none
*/
void IWDG_Enable( void )
{
IWDG->CTLR = CTLR_KEY_Enable;
}
/*********************************************************************
* @fn IWDG_GetFlagStatus
*
* @brief Checks whether the specified IWDG flag is set or not.
*
* @param IWDG_FLAG - specifies the flag to check.
* IWDG_FLAG_PVU - Prescaler Value Update on going.
* IWDG_FLAG_RVU - Reload Value Update on going.
*
* @return none
*/
FlagStatus IWDG_GetFlagStatus( uint16_t IWDG_FLAG )
{
FlagStatus bitstatus = RESET;
if( ( IWDG->STATR & IWDG_FLAG ) != ( uint32_t )RESET )
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
@@ -0,0 +1,148 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : ch32f10x_misc.c
* Author : WCH
* Version : V1.0.0
* Date : 2019/10/15
* Description : This file provides all the miscellaneous firmware functions (add-on
* to CMSIS functions).
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* SPDX-License-Identifier: Apache-2.0
*********************************************************************************/
#include "ch32f10x_misc.h"
#define AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000)
/*********************************************************************
* @fn NVIC_PriorityGroupConfig
*
* @brief Configures the priority grouping - pre-emption priority and subpriority.
*
* @param NVIC_PriorityGroup - specifies the priority grouping bits length.
* NVIC_PriorityGroup_0 - 0 bits for pre-emption priority
* 4 bits for subpriority
* NVIC_PriorityGroup_1 - 1 bits for pre-emption priority
* 3 bits for subpriority
* NVIC_PriorityGroup_2 - 2 bits for pre-emption priority
* 2 bits for subpriority
* NVIC_PriorityGroup_3 - 3 bits for pre-emption priority
* 1 bits for subpriority
* NVIC_PriorityGroup_4 - 4 bits for pre-emption priority
* 0 bits for subpriority
*
* @return none
*/
void NVIC_PriorityGroupConfig( uint32_t NVIC_PriorityGroup )
{
SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
}
/*********************************************************************
* @fn NVIC_Init
*
* @brief Initializes the NVIC peripheral according to the specified parameters in
* the NVIC_InitStruct.
*
* @param NVIC_InitStruct - pointer to a NVIC_InitTypeDef structure that contains the
* configuration information for the specified NVIC peripheral.
*
* @return none
*/
void NVIC_Init( NVIC_InitTypeDef *NVIC_InitStruct )
{
uint32_t tmppriority = 0x00, tmppre = 0x00, tmpsub = 0x0F;
if( NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE )
{
/* Compute the Corresponding IRQ Priority */
tmppriority = ( 0x700 - ( ( SCB->AIRCR ) & ( uint32_t )0x700 ) ) >> 0x08;
tmppre = ( 0x4 - tmppriority );
tmpsub = tmpsub >> tmppriority;
tmppriority = ( uint32_t )NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre;
tmppriority |= NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub;
tmppriority = tmppriority << 0x04;
NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel] = tmppriority;
/* Enable the Selected IRQ Channels */
NVIC->ISER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] =
( uint32_t )0x01 << ( NVIC_InitStruct->NVIC_IRQChannel & ( uint8_t )0x1F );
}
else
{
/* Disable the Selected IRQ Channels */
NVIC->ICER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] =
( uint32_t )0x01 << ( NVIC_InitStruct->NVIC_IRQChannel & ( uint8_t )0x1F );
}
}
/*********************************************************************
* @fn NVIC_SetVectorTable
*
* @brief Sets the vector table location and Offset.
*
* @param NVIC_VectTab - specifies if the vector table is in RAM or FLASH memory.The
* value can be NVIC_VectTab_RAM or NVIC_VectTab_FLASH.
* Offset - Vector Table base offset field. This value must be a multiple of 0x200.
*
* @return none
*/
void NVIC_SetVectorTable( uint32_t NVIC_VectTab, uint32_t Offset )
{
SCB->VTOR = NVIC_VectTab | ( Offset & ( uint32_t )0x1FFFFF80 );
}
/*********************************************************************
* @fn NVIC_SystemLPConfig
*
* @brief Selects the condition for the system to enter low power mode.
*
* @param LowPowerMode - Specifies the new mode for the system to enter low power mode.
* NVIC_LP_SEVONPEND
* NVIC_LP_SLEEPDEEP
* NVIC_LP_SLEEPONEXIT
* NewState - new state of LP condition. This parameter can be: ENABLE or DISABLE.
*
* @return none
*/
void NVIC_SystemLPConfig( uint8_t LowPowerMode, FunctionalState NewState )
{
if( NewState != DISABLE )
{
SCB->SCR |= LowPowerMode;
}
else
{
SCB->SCR &= ( uint32_t )( ~( uint32_t )LowPowerMode );
}
}
/*********************************************************************
* @fn SysTick_CLKSourceConfig
*
* @brief Configures the SysTick clock source.
*
* @param SysTick_CLKSource: Specifies the new mode for the system to enter low power mode.
* ysTick_CLKSource_HCLK_Div8: AHB clock divided by 8 selected as SysTick clock source.
* SysTick_CLKSource_HCLK: AHB clock selected as SysTick clock source.
*
* @return none
*/
void SysTick_CLKSourceConfig( uint32_t SysTick_CLKSource )
{
if( SysTick_CLKSource == SysTick_CLKSource_HCLK )
{
SysTick->CTRL |= SysTick_CLKSource_HCLK;
}
else
{
SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8;
}
}
@@ -0,0 +1,218 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : ch32f10x_pwr.c
* Author : WCH
* Version : V1.0.0
* Date : 2019/10/15
* Description : This file provides all the PWR firmware functions.
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/
#include "ch32f10x_pwr.h"
#include "ch32f10x_rcc.h"
/* PWR registers bit address in the alias region */
#define PWR_OFFSET (PWR_BASE - PERIPH_BASE)
/* CTLR Register */
/* Alias word address of DBP bit */
#define CTLR_OFFSET (PWR_OFFSET + 0x00)
#define DBP_BitNumber 0x08
#define CTLR_DBP_BB (PERIPH_BB_BASE + (CTLR_OFFSET * 32) + (DBP_BitNumber * 4))
/* Alias word address of PVDE bit */
#define PVDE_BitNumber 0x04
#define CTLR_PVDE_BB (PERIPH_BB_BASE + (CTLR_OFFSET * 32) + (PVDE_BitNumber * 4))
/* CSR Register */
/* Alias word address of EWUP bit */
#define CSR_OFFSET (PWR_OFFSET + 0x04)
#define EWUP_BitNumber 0x08
#define CSR_EWUP_BB (PERIPH_BB_BASE + (CSR_OFFSET * 32) + (EWUP_BitNumber * 4))
/* PWR registers bit mask */
/* CTLR register bit mask */
#define CTLR_DS_MASK ((uint32_t)0xFFFFFFFC)
#define CTLR_PLS_MASK ((uint32_t)0xFFFFFF1F)
/*********************************************************************
* @fn PWR_DeInit
*
* @brief Deinitializes the PWR peripheral registers to their default
* reset values.
*
* @return none
*/
void PWR_DeInit( void )
{
RCC_APB1PeriphResetCmd( RCC_APB1Periph_PWR, ENABLE );
RCC_APB1PeriphResetCmd( RCC_APB1Periph_PWR, DISABLE );
}
/*********************************************************************
* @fn PWR_BackupAccessCmd
*
* @brief Enables or disables access to the RTC and backup registers.
*
* @param NewState - new state of the access to the RTC and backup registers,
* This parameter can be: ENABLE or DISABLE.
*
* @return none
*/
void PWR_BackupAccessCmd( FunctionalState NewState )
{
*( __IO uint32_t * ) CTLR_DBP_BB = ( uint32_t )NewState;
}
/*********************************************************************
* @fn PWR_PVDCmd
*
* @brief Enables or disables the Power Voltage Detector(PVD).
*
* @param NewState - new state of the PVD(ENABLE or DISABLE).
*
* @return none
*/
void PWR_PVDCmd( FunctionalState NewState )
{
*( __IO uint32_t * ) CTLR_PVDE_BB = ( uint32_t )NewState;
}
/*********************************************************************
* @fn PWR_PVDLevelConfig
*
* @brief Configures the voltage threshold detected by the Power Voltage
* Detector(PVD).
*
* @param PWR_PVDLevel - specifies the PVD detection level
* PWR_PVDLevel_2V2 - PVD detection level set to 2.2V
* PWR_PVDLevel_2V3 - PVD detection level set to 2.3V
* PWR_PVDLevel_2V4 - PVD detection level set to 2.4V
* PWR_PVDLevel_2V5 - PVD detection level set to 2.5V
* PWR_PVDLevel_2V6 - PVD detection level set to 2.6V
* PWR_PVDLevel_2V7 - PVD detection level set to 2.7V
* PWR_PVDLevel_2V8 - PVD detection level set to 2.8V
* PWR_PVDLevel_2V9 - PVD detection level set to 2.9V
*
* @return none
*/
void PWR_PVDLevelConfig( uint32_t PWR_PVDLevel )
{
uint32_t tmpreg = 0;
tmpreg = PWR->CTLR;
tmpreg &= CTLR_PLS_MASK;
tmpreg |= PWR_PVDLevel;
PWR->CTLR = tmpreg;
}
/*********************************************************************
* @fn PWR_WakeUpPinCmd
*
* @brief Enables or disables the WakeUp Pin functionality.
*
* @param NewState - new state of the WakeUp Pin functionality
* (ENABLE or DISABLE).
*
* @return none
*/
void PWR_WakeUpPinCmd( FunctionalState NewState )
{
*( __IO uint32_t * ) CSR_EWUP_BB = ( uint32_t )NewState;
}
/*********************************************************************
* @fn PWR_EnterSTOPMode
*
* @brief Enters STOP mode.
*
* @param PWR_Regulator - specifies the regulator state in STOP mode.
* PWR_Regulator_ON - STOP mode with regulator ON
* PWR_Regulator_LowPower - STOP mode with regulator in low power mode
* PWR_STOPEntry - specifies if STOP mode in entered with WFI or WFE instruction.
* PWR_STOPEntry_WFI - enter STOP mode with WFI instruction
* PWR_STOPEntry_WFE - enter STOP mode with WFE instruction
*
* @return none
*/
void PWR_EnterSTOPMode( uint32_t PWR_Regulator, uint8_t PWR_STOPEntry )
{
uint32_t tmpreg = 0;
tmpreg = PWR->CTLR;
tmpreg &= CTLR_DS_MASK;
tmpreg |= PWR_Regulator;
PWR->CTLR = tmpreg;
SCB->SCR |= SCB_SCR_SLEEPDEEP;
if( PWR_STOPEntry == PWR_STOPEntry_WFI )
{
__WFI();
}
else
{
__WFE();
}
SCB->SCR &= ( uint32_t )~( ( uint32_t )SCB_SCR_SLEEPDEEP );
}
/*********************************************************************
* @fn PWR_EnterSTANDBYMode
*
* @brief Enters STANDBY mode.
*
* @return none
*/
void PWR_EnterSTANDBYMode( void )
{
PWR->CTLR |= PWR_CTLR_CWUF;
PWR->CTLR |= PWR_CTLR_PDDS;
SCB->SCR |= SCB_SCR_SLEEPDEEP;
#if defined ( __CC_ARM )
__force_stores();
#endif
__WFI();
}
/********************************************************************************
* Function Name : PWR_GetFlagStatus
* Description : Checks whether the specified PWR flag is set or not.
* Input : PWR_FLAG: specifies the flag to check.
* PWR_FLAG_WU: Wake Up flag
* PWR_FLAG_SB: StandBy flag
* PWR_FLAG_PVDO: PVD Output
* Return : The new state of PWR_FLAG (SET or RESET).
*********************************************************************************/
FlagStatus PWR_GetFlagStatus( uint32_t PWR_FLAG )
{
FlagStatus bitstatus = RESET;
if( ( PWR->CSR & PWR_FLAG ) != ( uint32_t )RESET )
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
/********************************************************************************
* Function Name : PWR_ClearFlag
* Description : Clears the PWR's pending flags.
* Input : PWR_FLAG: specifies the flag to clear.
* PWR_FLAG_WU: Wake Up flag
* PWR_FLAG_SB: StandBy flag
* Return : None
*********************************************************************************/
void PWR_ClearFlag( uint32_t PWR_FLAG )
{
PWR->CTLR |= PWR_FLAG << 2;
}
@@ -0,0 +1,931 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : ch32f10x_rcc.c
* Author : WCH
* Version : V1.0.0
* Date : 2019/10/15
* Description : This file provides all the RCC firmware functions.
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#include "ch32f10x_rcc.h"
/* RCC registers bit address in the alias region */
#define RCC_OFFSET (RCC_BASE - PERIPH_BASE)
/* CTLR Register */
/* Alias word address of HSION bit */
#define CTLR_OFFSET (RCC_OFFSET + 0x00)
#define HSION_BitNumber 0x00
#define CTLR_HSION_BB (PERIPH_BB_BASE + (CTLR_OFFSET * 32) + (HSION_BitNumber * 4))
/* Alias word address of PLLON bit */
#define PLLON_BitNumber 0x18
#define CTLR_PLLON_BB (PERIPH_BB_BASE + (CTLR_OFFSET * 32) + (PLLON_BitNumber * 4))
/* Alias word address of CSSON bit */
#define CSSON_BitNumber 0x13
#define CTLR_CSSON_BB (PERIPH_BB_BASE + (CTLR_OFFSET * 32) + (CSSON_BitNumber * 4))
/* CFGR0 Register */
/* Alias word address of USBPRE bit */
#define CFGR0_OFFSET (RCC_OFFSET + 0x04)
#define USBPRE_BitNumber 0x16
#define CFGR0_USBPRE_BB (PERIPH_BB_BASE + (CFGR0_OFFSET * 32) + (USBPRE_BitNumber * 4))
/* BDCTLR Register */
/* Alias word address of RTCEN bit */
#define BDCTLR_OFFSET (RCC_OFFSET + 0x20)
#define RTCEN_BitNumber 0x0F
#define BDCTLR_RTCEN_BB (PERIPH_BB_BASE + (BDCTLR_OFFSET * 32) + (RTCEN_BitNumber * 4))
/* Alias word address of BDRST bit */
#define BDRST_BitNumber 0x10
#define BDCTLR_BDRST_BB (PERIPH_BB_BASE + (BDCTLR_OFFSET * 32) + (BDRST_BitNumber * 4))
/* RSTSCKR Register */
/* Alias word address of LSION bit */
#define RSTSCKR_OFFSET (RCC_OFFSET + 0x24)
#define LSION_BitNumber 0x00
#define RSTSCKR_LSION_BB (PERIPH_BB_BASE + (RSTSCKR_OFFSET * 32) + (LSION_BitNumber * 4))
/* RCC registers bit mask */
/* CTLR register bit mask */
#define CTLR_HSEBYP_Reset ((uint32_t)0xFFFBFFFF)
#define CTLR_HSEBYP_Set ((uint32_t)0x00040000)
#define CTLR_HSEON_Reset ((uint32_t)0xFFFEFFFF)
#define CTLR_HSEON_Set ((uint32_t)0x00010000)
#define CTLR_HSITRIM_Mask ((uint32_t)0xFFFFFF07)
#define CFGR0_PLL_Mask ((uint32_t)0xFFC0FFFF)
#define CFGR0_PLLMull_Mask ((uint32_t)0x003C0000)
#define CFGR0_PLLSRC_Mask ((uint32_t)0x00010000)
#define CFGR0_PLLXTPRE_Mask ((uint32_t)0x00020000)
#define CFGR0_SWS_Mask ((uint32_t)0x0000000C)
#define CFGR0_SW_Mask ((uint32_t)0xFFFFFFFC)
#define CFGR0_HPRE_Reset_Mask ((uint32_t)0xFFFFFF0F)
#define CFGR0_HPRE_Set_Mask ((uint32_t)0x000000F0)
#define CFGR0_PPRE1_Reset_Mask ((uint32_t)0xFFFFF8FF)
#define CFGR0_PPRE1_Set_Mask ((uint32_t)0x00000700)
#define CFGR0_PPRE2_Reset_Mask ((uint32_t)0xFFFFC7FF)
#define CFGR0_PPRE2_Set_Mask ((uint32_t)0x00003800)
#define CFGR0_ADCPRE_Reset_Mask ((uint32_t)0xFFFF3FFF)
#define CFGR0_ADCPRE_Set_Mask ((uint32_t)0x0000C000)
/* RSTSCKR register bit mask */
#define RSTSCKR_RMVF_Set ((uint32_t)0x01000000)
/* RCC Flag Mask */
#define FLAG_Mask ((uint8_t)0x1F)
/* INTR register byte 2 (Bits[15:8]) base address */
#define INTR_BYTE2_ADDRESS ((uint32_t)0x40021009)
/* INTR register byte 3 (Bits[23:16]) base address */
#define INTR_BYTE3_ADDRESS ((uint32_t)0x4002100A)
/* CFGR0 register byte 4 (Bits[31:24]) base address */
#define CFGR0_BYTE4_ADDRESS ((uint32_t)0x40021007)
/* BDCTLR register base address */
#define BDCTLR_ADDRESS (PERIPH_BASE + BDCTLR_OFFSET)
static __I uint8_t APBAHBPrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9};
static __I uint8_t ADCPrescTable[4] = {2, 4, 6, 8};
/*********************************************************************
* @fn RCC_DeInit
*
* @brief Resets the RCC clock configuration to the default reset state.
*
* @return none
*/
void RCC_DeInit( void )
{
RCC->CTLR |= ( uint32_t )0x00000001;
RCC->CFGR0 &= ( uint32_t )0xF8FF0000;
RCC->CTLR &= ( uint32_t )0xFEF6FFFF;
RCC->CTLR &= ( uint32_t )0xFFFBFFFF;
RCC->CFGR0 &= ( uint32_t )0xFF80FFFF;
RCC->INTR = 0x009F0000;
}
/*********************************************************************
* @fn RCC_HSEConfig
*
* @brief Configures the External High Speed oscillator (HSE).
*
* @param RCC_HSE -
* RCC_HSE_OFF - HSE oscillator OFF.
* RCC_HSE_ON - HSE oscillator ON.
* RCC_HSE_Bypass - HSE oscillator bypassed with external clock.
*
* @return none
*/
void RCC_HSEConfig( uint32_t RCC_HSE )
{
RCC->CTLR &= CTLR_HSEON_Reset;
RCC->CTLR &= CTLR_HSEBYP_Reset;
switch( RCC_HSE )
{
case RCC_HSE_ON:
RCC->CTLR |= CTLR_HSEON_Set;
break;
case RCC_HSE_Bypass:
RCC->CTLR |= CTLR_HSEBYP_Set | CTLR_HSEON_Set;
break;
default:
break;
}
}
/*********************************************************************
* @fn RCC_WaitForHSEStartUp
*
* @brief Waits for HSE start-up.
*
* @return SUCCESS - HSE oscillator is stable and ready to use.
* ERROR - HSE oscillator not yet ready.
*/
ErrorStatus RCC_WaitForHSEStartUp( void )
{
__IO uint32_t StartUpCounter = 0;
ErrorStatus status = ERROR;
FlagStatus HSEStatus = RESET;
do
{
HSEStatus = RCC_GetFlagStatus( RCC_FLAG_HSERDY );
StartUpCounter++;
}
while( ( StartUpCounter != HSE_STARTUP_TIMEOUT ) && ( HSEStatus == RESET ) );
if( RCC_GetFlagStatus( RCC_FLAG_HSERDY ) != RESET )
{
status = SUCCESS;
}
else
{
status = ERROR;
}
return ( status );
}
/*********************************************************************
* @fn RCC_AdjustHSICalibrationValue
*
* @brief Adjusts the Internal High Speed oscillator (HSI) calibration value.
*
* @param HSICalibrationValue - specifies the calibration trimming value.
* This parameter must be a number between 0 and 0x1F.
*
* @return none
*/
void RCC_AdjustHSICalibrationValue( uint8_t HSICalibrationValue )
{
uint32_t tmpreg = 0;
tmpreg = RCC->CTLR;
tmpreg &= CTLR_HSITRIM_Mask;
tmpreg |= ( uint32_t )HSICalibrationValue << 3;
RCC->CTLR = tmpreg;
}
/*********************************************************************
* @fn RCC_HSICmd
*
* @brief Enables or disables the Internal High Speed oscillator (HSI).
*
* @param NewState - ENABLE or DISABLE.
*
* @return none
*/
void RCC_HSICmd( FunctionalState NewState )
{
*( __IO uint32_t * ) CTLR_HSION_BB = ( uint32_t )NewState;
}
/*********************************************************************
* @fn RCC_PLLConfig
*
* @brief Configures the PLL clock source and multiplication factor.
*
* @param RCC_PLLSource - specifies the PLL entry clock source.
* RCC_PLLSource_HSI_Div2 - HSI oscillator clock divided by 2
* selected as PLL clock entry.
* RCC_PLLSource_HSE_Div1 - HSE oscillator clock selected as PLL
* clock entry.
* RCC_PLLSource_HSE_Div2 - HSE oscillator clock divided by 2
* selected as PLL clock entry.
* RCC_PLLMul - specifies the PLL multiplication factor.
* This parameter can be RCC_PLLMul_x where x:[2,16].
*
* @return none
*/
void RCC_PLLConfig( uint32_t RCC_PLLSource, uint32_t RCC_PLLMul )
{
uint32_t tmpreg = 0;
tmpreg = RCC->CFGR0;
tmpreg &= CFGR0_PLL_Mask;
tmpreg |= RCC_PLLSource | RCC_PLLMul;
RCC->CFGR0 = tmpreg;
}
/*********************************************************************
* @fn RCC_PLLCmd
*
* @brief Enables or disables the PLL.
*
* @param NewState - ENABLE or DISABLE.
*
* @return none
*/
void RCC_PLLCmd( FunctionalState NewState )
{
*( __IO uint32_t * ) CTLR_PLLON_BB = ( uint32_t )NewState;
}
/*********************************************************************
* @fn RCC_SYSCLKConfig
*
* @brief Configures the system clock (SYSCLK).
*
* @param RCC_SYSCLKSource - specifies the clock source used as system clock.
* RCC_SYSCLKSource_HSI - HSI selected as system clock.
* RCC_SYSCLKSource_HSE - HSE selected as system clock.
* RCC_SYSCLKSource_PLLCLK - PLL selected as system clock.
*
* @return none
*/
void RCC_SYSCLKConfig( uint32_t RCC_SYSCLKSource )
{
uint32_t tmpreg = 0;
tmpreg = RCC->CFGR0;
tmpreg &= CFGR0_SW_Mask;
tmpreg |= RCC_SYSCLKSource;
RCC->CFGR0 = tmpreg;
}
/*********************************************************************
* @fn RCC_GetSYSCLKSource
*
* @brief Returns the clock source used as system clock.
*
* @return 0x00 - HSI used as system clock.
* 0x04 - HSE used as system clock.
* 0x08 - PLL used as system clock.
*/
uint8_t RCC_GetSYSCLKSource( void )
{
return ( ( uint8_t )( RCC->CFGR0 & CFGR0_SWS_Mask ) );
}
/*********************************************************************
* @fn RCC_HCLKConfig
*
* @brief Configures the AHB clock (HCLK).
*
* @param RCC_SYSCLK - defines the AHB clock divider. This clock is derived from
* the system clock (SYSCLK).
* RCC_SYSCLK_Div1 - AHB clock = SYSCLK.
* RCC_SYSCLK_Div2 - AHB clock = SYSCLK/2.
* RCC_SYSCLK_Div4 - AHB clock = SYSCLK/4.
* RCC_SYSCLK_Div8 - AHB clock = SYSCLK/8.
* RCC_SYSCLK_Div16 - AHB clock = SYSCLK/16.
* RCC_SYSCLK_Div64 - AHB clock = SYSCLK/64.
* RCC_SYSCLK_Div128 - AHB clock = SYSCLK/128.
* RCC_SYSCLK_Div256 - AHB clock = SYSCLK/256.
* RCC_SYSCLK_Div512 - AHB clock = SYSCLK/512.
*
* @return none
*/
void RCC_HCLKConfig( uint32_t RCC_SYSCLK )
{
uint32_t tmpreg = 0;
tmpreg = RCC->CFGR0;
tmpreg &= CFGR0_HPRE_Reset_Mask;
tmpreg |= RCC_SYSCLK;
RCC->CFGR0 = tmpreg;
}
/*********************************************************************
* @fn RCC_PCLK1Config
*
* @brief Configures the Low Speed APB clock (PCLK1).
*
* @param RCC_HCLK - defines the APB1 clock divider. This clock is derived from
* the AHB clock (HCLK).
* RCC_HCLK_Div1 - APB1 clock = HCLK.
* RCC_HCLK_Div2 - APB1 clock = HCLK/2.
* RCC_HCLK_Div4 - APB1 clock = HCLK/4.
* RCC_HCLK_Div8 - APB1 clock = HCLK/8.
* RCC_HCLK_Div16 - APB1 clock = HCLK/16.
*
* @return none
*/
void RCC_PCLK1Config( uint32_t RCC_HCLK )
{
uint32_t tmpreg = 0;
tmpreg = RCC->CFGR0;
tmpreg &= CFGR0_PPRE1_Reset_Mask;
tmpreg |= RCC_HCLK;
RCC->CFGR0 = tmpreg;
}
/*********************************************************************
* @fn RCC_PCLK2Config
*
* @brief Configures the High Speed APB clock (PCLK2).
*
* @param RCC_HCLK - defines the APB2 clock divider. This clock is derived from
* the AHB clock (HCLK).
* RCC_HCLK_Div1 - APB1 clock = HCLK.
* RCC_HCLK_Div2 - APB1 clock = HCLK/2.
* RCC_HCLK_Div4 - APB1 clock = HCLK/4.
* RCC_HCLK_Div8 - APB1 clock = HCLK/8.
* RCC_HCLK_Div16 - APB1 clock = HCLK/16.
*
* @return none
*/
void RCC_PCLK2Config( uint32_t RCC_HCLK )
{
uint32_t tmpreg = 0;
tmpreg = RCC->CFGR0;
tmpreg &= CFGR0_PPRE2_Reset_Mask;
tmpreg |= RCC_HCLK << 3;
RCC->CFGR0 = tmpreg;
}
/*********************************************************************
* @fn RCC_ITConfig
*
* @brief Enables or disables the specified RCC interrupts.
*
* @param RCC_IT - specifies the RCC interrupt sources to be enabled or disabled.
* RCC_IT_LSIRDY - LSI ready interrupt.
* RCC_IT_LSERDY - LSE ready interrupt.
* RCC_IT_HSIRDY - HSI ready interrupt.
* RCC_IT_HSERDY - HSE ready interrupt.
* RCC_IT_PLLRDY - PLL ready interrupt.
* NewState - ENABLE or DISABLE.
*
* @return none
*/
void RCC_ITConfig( uint8_t RCC_IT, FunctionalState NewState )
{
if( NewState != DISABLE )
{
*( __IO uint8_t * ) INTR_BYTE2_ADDRESS |= RCC_IT;
}
else
{
*( __IO uint8_t * ) INTR_BYTE2_ADDRESS &= ( uint8_t )~RCC_IT;
}
}
/*********************************************************************
* @fn RCC_USBCLKConfig
*
* @brief Configures the USB clock (USBCLK).
*
* @param RCC_USBCLKSource: specifies the USB clock source. This clock is
* derived from the PLL output.
* RCC_USBCLKSource_PLLCLK_1Div5: PLL clock divided by 1,5 selected as USB
* clock source.
* RCC_USBCLKSource_PLLCLK_Div1: PLL clock selected as USB clock source.
*
* @return none
*/
void RCC_USBCLKConfig( uint32_t RCC_USBCLKSource )
{
*( __IO uint32_t * ) CFGR0_USBPRE_BB = RCC_USBCLKSource;
}
/*********************************************************************
* @fn RCC_ADCCLKConfig
*
* @brief Configures the ADC clock (ADCCLK).
*
* @param RCC_PCLK2 - defines the ADC clock divider. This clock is derived from
* the APB2 clock (PCLK2).
* RCC_PCLK2_Div2 - ADC clock = PCLK2/2.
* RCC_PCLK2_Div4 - ADC clock = PCLK2/4.
* RCC_PCLK2_Div6 - ADC clock = PCLK2/6.
* RCC_PCLK2_Div8 - ADC clock = PCLK2/8.
*
* @return none
*/
void RCC_ADCCLKConfig( uint32_t RCC_PCLK2 )
{
uint32_t tmpreg = 0;
tmpreg = RCC->CFGR0;
tmpreg &= CFGR0_ADCPRE_Reset_Mask;
tmpreg |= RCC_PCLK2;
RCC->CFGR0 = tmpreg;
}
/*********************************************************************
* @fn RCC_LSEConfig
*
* @brief Configures the External Low Speed oscillator (LSE).
*
* @param RCC_LSE - specifies the new state of the LSE.
* RCC_LSE_OFF - LSE oscillator OFF.
* RCC_LSE_ON - LSE oscillator ON.
* RCC_LSE_Bypass - LSE oscillator bypassed with external clock.
*
* @return none
*/
void RCC_LSEConfig( uint8_t RCC_LSE )
{
*( __IO uint8_t * ) BDCTLR_ADDRESS = RCC_LSE_OFF;
*( __IO uint8_t * ) BDCTLR_ADDRESS = RCC_LSE_OFF;
switch( RCC_LSE )
{
case RCC_LSE_ON:
*( __IO uint8_t * ) BDCTLR_ADDRESS = RCC_LSE_ON;
break;
case RCC_LSE_Bypass:
*( __IO uint8_t * ) BDCTLR_ADDRESS = RCC_LSE_Bypass | RCC_LSE_ON;
break;
default:
break;
}
}
/*********************************************************************
* @fn RCC_LSICmd
*
* @brief Enables or disables the Internal Low Speed oscillator (LSI).
*
* @param NewState - ENABLE or DISABLE.
*
* @return none
*/
void RCC_LSICmd( FunctionalState NewState )
{
*( __IO uint32_t * ) RSTSCKR_LSION_BB = ( uint32_t )NewState;
}
/*********************************************************************
* @fn RCC_RTCCLKConfig
*
* @brief Once the RTC clock is selected it can't be changed unless the Backup domain is reset.
*
* @param RCC_RTCCLKSource - specifies the RTC clock source.
* RCC_RTCCLKSource_LSE - LSE selected as RTC clock.
* RCC_RTCCLKSource_LSI - LSI selected as RTC clock.
* RCC_RTCCLKSource_HSE_Div128 - HSE clock divided by 128 selected as RTC clock.
*
* @return none
*/
void RCC_RTCCLKConfig( uint32_t RCC_RTCCLKSource )
{
RCC->BDCTLR |= RCC_RTCCLKSource;
}
/*********************************************************************
* @fn RCC_RTCCLKCmd
*
* @brief This function must be used only after the RTC clock was selected
* using the RCC_RTCCLKConfig function.
*
* @param NewState - ENABLE or DISABLE.
*
* @return none
*/
void RCC_RTCCLKCmd( FunctionalState NewState )
{
*( __IO uint32_t * ) BDCTLR_RTCEN_BB = ( uint32_t )NewState;
}
/*********************************************************************
* @fn RCC_GetClocksFreq
*
* @brief The result of this function could be not correct when using
* fractional value for HSE crystal.
*
* @param RCC_Clocks - pointer to a RCC_ClocksTypeDef structure which will hold
* the clocks frequencies.
*
* @return none
*/
void RCC_GetClocksFreq( RCC_ClocksTypeDef *RCC_Clocks )
{
uint32_t tmp = 0, pllmull = 0, pllsource = 0, presc = 0;
tmp = RCC->CFGR0 & CFGR0_SWS_Mask;
switch( tmp )
{
case 0x00:
RCC_Clocks->SYSCLK_Frequency = HSI_VALUE;
break;
case 0x04:
RCC_Clocks->SYSCLK_Frequency = HSE_VALUE;
break;
case 0x08:
pllmull = RCC->CFGR0 & CFGR0_PLLMull_Mask;
pllsource = RCC->CFGR0 & CFGR0_PLLSRC_Mask;
pllmull = ( pllmull >> 18 ) + 2;
if( pllsource == 0x00 )
{
if( EXTEN->EXTEN_CTR & EXTEN_PLL_HSI_PRE )
{
RCC_Clocks->SYSCLK_Frequency = ( HSI_VALUE ) * pllmull;
}
else
{
RCC_Clocks->SYSCLK_Frequency = ( HSI_VALUE >> 1 ) * pllmull;
}
}
else
{
if( ( RCC->CFGR0 & CFGR0_PLLXTPRE_Mask ) != ( uint32_t )RESET )
{
RCC_Clocks->SYSCLK_Frequency = ( HSE_VALUE >> 1 ) * pllmull;
}
else
{
RCC_Clocks->SYSCLK_Frequency = HSE_VALUE * pllmull;
}
}
break;
default:
RCC_Clocks->SYSCLK_Frequency = HSI_VALUE;
break;
}
tmp = RCC->CFGR0 & CFGR0_HPRE_Set_Mask;
tmp = tmp >> 4;
presc = APBAHBPrescTable[tmp];
RCC_Clocks->HCLK_Frequency = RCC_Clocks->SYSCLK_Frequency >> presc;
tmp = RCC->CFGR0 & CFGR0_PPRE1_Set_Mask;
tmp = tmp >> 8;
presc = APBAHBPrescTable[tmp];
RCC_Clocks->PCLK1_Frequency = RCC_Clocks->HCLK_Frequency >> presc;
tmp = RCC->CFGR0 & CFGR0_PPRE2_Set_Mask;
tmp = tmp >> 11;
presc = APBAHBPrescTable[tmp];
RCC_Clocks->PCLK2_Frequency = RCC_Clocks->HCLK_Frequency >> presc;
tmp = RCC->CFGR0 & CFGR0_ADCPRE_Set_Mask;
tmp = tmp >> 14;
presc = ADCPrescTable[tmp];
RCC_Clocks->ADCCLK_Frequency = RCC_Clocks->PCLK2_Frequency / presc;
}
/*********************************************************************
* @fn RCC_AHBPeriphClockCmd
*
* @brief Enables or disables the AHB peripheral clock.
*
* @param RCC_AHBPeriph - specifies the AHB peripheral to gates its clock.
* RCC_AHBPeriph_DMA1.
* RCC_AHBPeriph_DMA2.
* RCC_AHBPeriph_SRAM.
* NewState: ENABLE or DISABLE.
*
* @return none
*/
void RCC_AHBPeriphClockCmd( uint32_t RCC_AHBPeriph, FunctionalState NewState )
{
if( NewState != DISABLE )
{
RCC->AHBPCENR |= RCC_AHBPeriph;
}
else
{
RCC->AHBPCENR &= ~RCC_AHBPeriph;
}
}
/*********************************************************************
* @fn RCC_APB2PeriphClockCmd
*
* @brief Enables or disables the High Speed APB (APB2) peripheral clock.
*
* @param RCC_APB2Periph - specifies the APB2 peripheral to gates its clock.
* RCC_APB2Periph_AFIO.
* RCC_APB2Periph_GPIOA.
* RCC_APB2Periph_GPIOB.
* RCC_APB2Periph_GPIOC.
* RCC_APB2Periph_GPIOD.
* RCC_APB2Periph_GPIOE
* RCC_APB2Periph_ADC1.
* RCC_APB2Periph_ADC2
* RCC_APB2Periph_TIM1.
* RCC_APB2Periph_SPI1.
* RCC_APB2Periph_TIM8
* RCC_APB2Periph_USART1.
* NewState - ENABLE or DISABLE
*
* @return none
*/
void RCC_APB2PeriphClockCmd( uint32_t RCC_APB2Periph, FunctionalState NewState )
{
if( NewState != DISABLE )
{
RCC->APB2PCENR |= RCC_APB2Periph;
}
else
{
RCC->APB2PCENR &= ~RCC_APB2Periph;
}
}
/*********************************************************************
* @fn RCC_APB1PeriphClockCmd
*
* @brief Enables or disables the Low Speed APB (APB1) peripheral clock.
*
* @param RCC_APB1Periph - specifies the APB1 peripheral to gates its clock.
* RCC_APB1Periph_TIM2.
* RCC_APB1Periph_TIM3.
* RCC_APB1Periph_TIM4.
* RCC_APB1Periph_WWDG.
* RCC_APB1Periph_SPI2.
* RCC_APB1Periph_USART2.
* RCC_APB1Periph_I2C1.
* RCC_APB1Periph_I2C2.
* RCC_APB1Periph_USB.
* RCC_APB1Periph_CAN1.
* RCC_APB1Periph_BKP.
* RCC_APB1Periph_PWR.
* RCC_APB1Periph_DAC.
* NewState - ENABLE or DISABLE.
*
* @return none
*/
void RCC_APB1PeriphClockCmd( uint32_t RCC_APB1Periph, FunctionalState NewState )
{
if( NewState != DISABLE )
{
RCC->APB1PCENR |= RCC_APB1Periph;
}
else
{
RCC->APB1PCENR &= ~RCC_APB1Periph;
}
}
/*********************************************************************
* @fn RCC_APB2PeriphResetCmd
*
* @brief Forces or releases High Speed APB (APB2) peripheral reset.
*
* @param RCC_APB2Periph - specifies the APB2 peripheral to reset.
* RCC_APB2Periph_AFIO.
* RCC_APB2Periph_GPIOA.
* RCC_APB2Periph_GPIOB.
* RCC_APB2Periph_GPIOC.
* RCC_APB2Periph_GPIOD.
* RCC_APB2Periph_GPIOE
* RCC_APB2Periph_ADC1.
* RCC_APB2Periph_TIM1.
* RCC_APB2Periph_SPI1.
* RCC_APB2Periph_USART1.
* NewState - ENABLE or DISABLE
*
* @return none
*/
void RCC_APB2PeriphResetCmd( uint32_t RCC_APB2Periph, FunctionalState NewState )
{
if( NewState != DISABLE )
{
RCC->APB2PRSTR |= RCC_APB2Periph;
}
else
{
RCC->APB2PRSTR &= ~RCC_APB2Periph;
}
}
/*********************************************************************
* @fn RCC_APB1PeriphResetCmd
*
* @brief Forces or releases Low Speed APB (APB1) peripheral reset.
*
* @param RCC_APB1Periph - specifies the APB1 peripheral to reset.
* RCC_APB1Periph_TIM2.
* RCC_APB1Periph_TIM3.
* RCC_APB1Periph_TIM4.
* RCC_APB1Periph_WWDG.
* RCC_APB1Periph_SPI2.
* RCC_APB1Periph_USART2.
* RCC_APB1Periph_USART3.
* RCC_APB1Periph_I2C1.
* RCC_APB1Periph_I2C2.
* RCC_APB1Periph_USB.
* RCC_APB1Periph_CAN1.
* RCC_APB1Periph_BKP.
* RCC_APB1Periph_PWR.
* RCC_APB1Periph_DAC.
* NewState - ENABLE or DISABLE.
*
* @return none
*/
void RCC_APB1PeriphResetCmd( uint32_t RCC_APB1Periph, FunctionalState NewState )
{
if( NewState != DISABLE )
{
RCC->APB1PRSTR |= RCC_APB1Periph;
}
else
{
RCC->APB1PRSTR &= ~RCC_APB1Periph;
}
}
/*********************************************************************
* @fn RCC_BackupResetCmd
*
* @brief Forces or releases the Backup domain reset.
*
* @param NewState - ENABLE or DISABLE.
*
* @return none
*/
void RCC_BackupResetCmd( FunctionalState NewState )
{
*( __IO uint32_t * ) BDCTLR_BDRST_BB = ( uint32_t )NewState;
}
/*********************************************************************
* @fn RCC_ClockSecuritySystemCmd
*
* @brief Enables or disables the Clock Security System.
*
* @param NewState - ENABLE or DISABLE.
*
* @return none
*/
void RCC_ClockSecuritySystemCmd( FunctionalState NewState )
{
*( __IO uint32_t * ) CTLR_CSSON_BB = ( uint32_t )NewState;
}
/*********************************************************************
* @fn RCC_MCOConfig
*
* @brief Selects the clock source to output on MCO pin.
*
* @param RCC_MCO - specifies the clock source to output.
* RCC_MCO_NoClock - No clock selected.
* RCC_MCO_SYSCLK - System clock selected.
* RCC_MCO_HSI - HSI oscillator clock selected.
* RCC_MCO_HSE - HSE oscillator clock selected.
* RCC_MCO_PLLCLK_Div2 - PLL clock divided by 2 selected.
*
* @return none
*/
void RCC_MCOConfig( uint8_t RCC_MCO )
{
*( __IO uint8_t * ) CFGR0_BYTE4_ADDRESS = RCC_MCO;
}
/*********************************************************************
* @fn RCC_GetFlagStatus
*
* @brief Checks whether the specified RCC flag is set or not.
*
* @param RCC_FLAG - specifies the flag to check.
* RCC_FLAG_HSIRDY - HSI oscillator clock ready.
* RCC_FLAG_HSERDY - HSE oscillator clock ready.
* RCC_FLAG_PLLRDY - PLL clock ready.
* RCC_FLAG_LSERDY - LSE oscillator clock ready.
* RCC_FLAG_LSIRDY - LSI oscillator clock ready.
* RCC_FLAG_PINRST - Pin reset.
* RCC_FLAG_PORRST - POR/PDR reset.
* RCC_FLAG_SFTRST - Software reset.
* RCC_FLAG_IWDGRST - Independent Watchdog reset.
* RCC_FLAG_WWDGRST - Window Watchdog reset.
* RCC_FLAG_LPWRRST - Low Power reset.
*
* @return FlagStatus - SET or RESET.
*/
FlagStatus RCC_GetFlagStatus( uint8_t RCC_FLAG )
{
uint32_t tmp = 0;
uint32_t statusreg = 0;
FlagStatus bitstatus = RESET;
tmp = RCC_FLAG >> 5;
if( tmp == 1 )
{
statusreg = RCC->CTLR;
}
else if( tmp == 2 )
{
statusreg = RCC->BDCTLR;
}
else
{
statusreg = RCC->RSTSCKR;
}
tmp = RCC_FLAG & FLAG_Mask;
if( ( statusreg & ( ( uint32_t )1 << tmp ) ) != ( uint32_t )RESET )
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
/*********************************************************************
* @fn RCC_ClearFlag
*
* @brief Clears the RCC reset flags.
*
* @return none
*/
void RCC_ClearFlag( void )
{
RCC->RSTSCKR |= RSTSCKR_RMVF_Set;
}
/*********************************************************************
* @fn RCC_GetITStatus
*
* @brief Checks whether the specified RCC interrupt has occurred or not.
*
* @param RCC_IT - specifies the RCC interrupt source to check.
* RCC_IT_LSIRDY - LSI ready interrupt.
* RCC_IT_LSERDY - LSE ready interrupt.
* RCC_IT_HSIRDY - HSI ready interrupt.
* RCC_IT_HSERDY - HSE ready interrupt.
* RCC_IT_PLLRDY - PLL ready interrupt.
* RCC_IT_CSS - Clock Security System interrupt.
*
* @return ITStatus - SET or RESET.
*/
ITStatus RCC_GetITStatus( uint8_t RCC_IT )
{
ITStatus bitstatus = RESET;
if( ( RCC->INTR & RCC_IT ) != ( uint32_t )RESET )
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
/*********************************************************************
* @fn RCC_ClearITPendingBit
*
* @brief Clears the RCC's interrupt pending bits.
*
* @param RCC_IT - specifies the interrupt pending bit to clear.
* RCC_IT_LSIRDY - LSI ready interrupt.
* RCC_IT_LSERDY - LSE ready interrupt.
* RCC_IT_HSIRDY - HSI ready interrupt.
* RCC_IT_HSERDY - HSE ready interrupt.
* RCC_IT_PLLRDY - PLL ready interrupt.
* RCC_IT_CSS - Clock Security System interrupt.
*
* @return none
*/
void RCC_ClearITPendingBit( uint8_t RCC_IT )
{
*( __IO uint8_t * ) INTR_BYTE3_ADDRESS = RCC_IT;
}
@@ -0,0 +1,285 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : ch32f10x_rtc.c
* Author : WCH
* Version : V1.0.0
* Date : 2019/10/15
* Description : This file provides all the RTC firmware functions.
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/
#include "ch32f10x_rtc.h"
/* RTC_Private_Defines */
#define RTC_LSB_MASK ((uint32_t)0x0000FFFF) /* RTC LSB Mask */
#define PRLH_MSB_MASK ((uint32_t)0x000F0000) /* RTC Prescaler MSB Mask */
/*********************************************************************
* @fn RTC_ITConfig
*
* @brief Enables or disables the specified RTC interrupts.
*
* @param RTC_IT - specifies the RTC interrupts sources to be enabled or disabled.
* RTC_IT_OW - Overflow interrupt
* RTC_IT_ALR - Alarm interrupt
* RTC_IT_SEC - Second interrupt
*
* @return NewState - new state of the specified RTC interrupts(ENABLE or DISABLE).
*/
void RTC_ITConfig( uint16_t RTC_IT, FunctionalState NewState )
{
if( NewState != DISABLE )
{
RTC->CTLRH |= RTC_IT;
}
else
{
RTC->CTLRH &= ( uint16_t )~RTC_IT;
}
}
/*********************************************************************
* @fn RTC_EnterConfigMode
*
* @brief Enters the RTC configuration mode.
*
* @return none
*/
void RTC_EnterConfigMode( void )
{
RTC->CTLRL |= RTC_CTLRL_CNF;
}
/*********************************************************************
* @fn RTC_ExitConfigMode
*
* @brief Exits from the RTC configuration mode.
*
* @return none
*/
void RTC_ExitConfigMode( void )
{
RTC->CTLRL &= ( uint16_t )~( ( uint16_t )RTC_CTLRL_CNF );
}
/*********************************************************************
* @fn RTC_GetCounter
*
* @brief Gets the RTC counter value
*
* @return RTC counter value
*/
uint32_t RTC_GetCounter( void )
{
uint16_t high1 = 0, high2 = 0, low = 0;
high1 = RTC->CNTH;
low = RTC->CNTL;
high2 = RTC->CNTH;
if( high1 != high2 )
{
return ( ( ( uint32_t ) high2 << 16 ) | RTC->CNTL );
}
else
{
return ( ( ( uint32_t ) high1 << 16 ) | low );
}
}
/*********************************************************************
* @fn RTC_SetCounter
*
* @brief Sets the RTC counter value.
*
* @param CounterValue - RTC counter new value.
*
* @return RTC counter value
*/
void RTC_SetCounter( uint32_t CounterValue )
{
RTC_EnterConfigMode();
RTC->CNTH = CounterValue >> 16;
RTC->CNTL = ( CounterValue & RTC_LSB_MASK );
RTC_ExitConfigMode();
}
/*********************************************************************
* @fn RTC_SetPrescaler
*
* @brief Sets the RTC prescaler value
*
* @param PrescalerValue - RTC prescaler new value
*
* @return none
*/
void RTC_SetPrescaler( uint32_t PrescalerValue )
{
RTC_EnterConfigMode();
RTC->PSCRH = ( PrescalerValue & PRLH_MSB_MASK ) >> 16;
RTC->PSCRL = ( PrescalerValue & RTC_LSB_MASK );
RTC_ExitConfigMode();
}
/*********************************************************************
* @fn RTC_SetAlarm
*
* @brief Sets the RTC alarm value
*
* @param AlarmValue - RTC alarm new value
*
* @return none
*/
void RTC_SetAlarm( uint32_t AlarmValue )
{
RTC_EnterConfigMode();
RTC->ALRMH = AlarmValue >> 16;
RTC->ALRML = ( AlarmValue & RTC_LSB_MASK );
RTC_ExitConfigMode();
}
/*********************************************************************
* @fn RTC_GetDivider
*
* @brief Gets the RTC divider value
*
* @return RTC Divider value
*/
uint32_t RTC_GetDivider( void )
{
uint32_t tmp = 0x00;
tmp = ( ( uint32_t )RTC->DIVH & ( uint32_t )0x000F ) << 16;
tmp |= RTC->DIVL;
return tmp;
}
/*********************************************************************
* @fn RTC_WaitForLastTask
*
* @brief Waits until last write operation on RTC registers has finished
*
* @return none
*/
void RTC_WaitForLastTask( void )
{
while( ( RTC->CTLRL & RTC_FLAG_RTOFF ) == ( uint16_t )RESET )
{
}
}
/*********************************************************************
* @fn RTC_WaitForSynchro
*
* @brief Waits until the RTC registers are synchronized with RTC APB clock
*
* @return none
*/
void RTC_WaitForSynchro( void )
{
RTC->CTLRL &= ( uint16_t )~RTC_FLAG_RSF;
while( ( RTC->CTLRL & RTC_FLAG_RSF ) == ( uint16_t )RESET )
{
}
}
/*********************************************************************
* @fn RTC_GetFlagStatus
*
* @brief Checks whether the specified RTC flag is set or not
*
* @param RTC_FLAG- specifies the flag to check
* RTC_FLAG_RTOFF - RTC Operation OFF flag
* RTC_FLAG_RSF - Registers Synchronized flag
* RTC_FLAG_OW - Overflow flag
* RTC_FLAG_ALR - Alarm flag
* RTC_FLAG_SEC - Second flag
*
* @return The new state of RTC_FLAG (SET or RESET)
*/
FlagStatus RTC_GetFlagStatus( uint16_t RTC_FLAG )
{
FlagStatus bitstatus = RESET;
if( ( RTC->CTLRL & RTC_FLAG ) != ( uint16_t )RESET )
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
/*********************************************************************
* @fn RTC_ClearFlag
*
* @brief Clears the RTC's pending flags
*
* @param RTC_FLAG - specifies the flag to clear
* RTC_FLAG_RSF - Registers Synchronized flag
* RTC_FLAG_OW - Overflow flag
* RTC_FLAG_ALR - Alarm flag
* RTC_FLAG_SEC - Second flag
*
* @return none
*/
void RTC_ClearFlag( uint16_t RTC_FLAG )
{
RTC->CTLRL &= ( uint16_t )~RTC_FLAG;
}
/*********************************************************************
* @fn RTC_GetITStatus
*
* @brief Checks whether the specified RTC interrupt has occurred or not
*
* @param RTC_IT - specifies the RTC interrupts sources to check
* RTC_FLAG_OW - Overflow interrupt
* RTC_FLAG_ALR - Alarm interrupt
* RTC_FLAG_SEC - Second interrupt
*
* @return The new state of the RTC_IT (SET or RESET)
*/
ITStatus RTC_GetITStatus( uint16_t RTC_IT )
{
ITStatus bitstatus = RESET;
bitstatus = ( ITStatus )( RTC->CTLRL & RTC_IT );
if( ( ( RTC->CTLRH & RTC_IT ) != ( uint16_t )RESET ) && ( bitstatus != ( uint16_t )RESET ) )
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
/*********************************************************************
* @fn RTC_ClearITPendingBit
*
* @brief Clears the RTC's interrupt pending bits
*
* @param RTC_IT - specifies the interrupt pending bit to clear
* RTC_FLAG_OW - Overflow interrupt
* RTC_FLAG_ALR - Alarm interrupt
* RTC_FLAG_SEC - Second interrupt
*
* @return none
*/
void RTC_ClearITPendingBit( uint16_t RTC_IT )
{
RTC->CTLRL &= ( uint16_t )~RTC_IT;
}
@@ -0,0 +1,654 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : ch32f10x_spi.c
* Author : WCH
* Version : V1.0.0
* Date : 2019/10/15
* Description : This file provides all the SPI firmware functions.
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* SPDX-License-Identifier: Apache-2.0
*********************************************************************************/
#include "ch32f10x_spi.h"
#include "ch32f10x_rcc.h"
/* SPI SPE mask */
#define CTLR1_SPE_Set ((uint16_t)0x0040)
#define CTLR1_SPE_Reset ((uint16_t)0xFFBF)
/* I2S I2SE mask */
#define I2SCFGR_I2SE_Set ((uint16_t)0x0400)
#define I2SCFGR_I2SE_Reset ((uint16_t)0xFBFF)
/* SPI CRCNext mask */
#define CTLR1_CRCNext_Set ((uint16_t)0x1000)
/* SPI CRCEN mask */
#define CTLR1_CRCEN_Set ((uint16_t)0x2000)
#define CTLR1_CRCEN_Reset ((uint16_t)0xDFFF)
/* SPI SSOE mask */
#define CTLR2_SSOE_Set ((uint16_t)0x0004)
#define CTLR2_SSOE_Reset ((uint16_t)0xFFFB)
/* SPI registers Masks */
#define CTLR1_CLEAR_Mask ((uint16_t)0x3040)
#define I2SCFGR_CLEAR_Mask ((uint16_t)0xF040)
/* SPI or I2S mode selection masks */
#define SPI_Mode_Select ((uint16_t)0xF7FF)
#define I2S_Mode_Select ((uint16_t)0x0800)
/* I2S clock source selection masks */
#define I2S2_CLOCK_SRC ((uint32_t)(0x00020000))
#define I2S3_CLOCK_SRC ((uint32_t)(0x00040000))
#define I2S_MUL_MASK ((uint32_t)(0x0000F000))
#define I2S_DIV_MASK ((uint32_t)(0x000000F0))
/*********************************************************************
* @fn SPI_I2S_DeInit
*
* @brief Deinitializes the SPIx peripheral registers to their default
* reset values (Affects also the I2Ss).
* @param SPIx - where x can be 1, 2 or 3 to select the SPI peripheral.
*
* @return none
*/
void SPI_I2S_DeInit( SPI_TypeDef *SPIx )
{
if( SPIx == SPI1 )
{
RCC_APB2PeriphResetCmd( RCC_APB2Periph_SPI1, ENABLE );
RCC_APB2PeriphResetCmd( RCC_APB2Periph_SPI1, DISABLE );
}
else if( SPIx == SPI2 )
{
RCC_APB1PeriphResetCmd( RCC_APB1Periph_SPI2, ENABLE );
RCC_APB1PeriphResetCmd( RCC_APB1Periph_SPI2, DISABLE );
}
else
{
if( SPIx == SPI3 )
{
RCC_APB1PeriphResetCmd( RCC_APB1Periph_SPI3, ENABLE );
RCC_APB1PeriphResetCmd( RCC_APB1Periph_SPI3, DISABLE );
}
}
}
/*********************************************************************
* @fn SPI_Init
*
* @brief Initializes the SPIx peripheral according to the specified
* parameters in the SPI_InitStruct.
*
* @param SPIx - where x can be 1, 2 or 3 to select the SPI peripheral.
* SPI_InitStruct - pointer to a SPI_InitTypeDef structure that
* contains the configuration information for the specified SPI peripheral.
*
* @return none
*/
void SPI_Init( SPI_TypeDef *SPIx, SPI_InitTypeDef *SPI_InitStruct )
{
uint16_t tmpreg = 0;
tmpreg = SPIx->CTLR1;
tmpreg &= CTLR1_CLEAR_Mask;
tmpreg |= ( uint16_t )( ( uint32_t )SPI_InitStruct->SPI_Direction | SPI_InitStruct->SPI_Mode |
SPI_InitStruct->SPI_DataSize | SPI_InitStruct->SPI_CPOL |
SPI_InitStruct->SPI_CPHA | SPI_InitStruct->SPI_NSS |
SPI_InitStruct->SPI_BaudRatePrescaler | SPI_InitStruct->SPI_FirstBit );
SPIx->CTLR1 = tmpreg;
SPIx->I2SCFGR &= SPI_Mode_Select;
SPIx->CRCR = SPI_InitStruct->SPI_CRCPolynomial;
}
/*********************************************************************
* @fn I2S_Init
*
* @brief Initializes the SPIx peripheral according to the specified
* parameters in the I2S_InitStruct.
* @param SPIx - where x can be 1, 2 or 3 to select the SPI peripheral.
* (configured in I2S mode).
* I2S_InitStruct - pointer to an I2S_InitTypeDef structure that
* contains the configuration information for the specified SPI peripheral
* configured in I2S mode.
* @return none
*/
void I2S_Init( SPI_TypeDef *SPIx, I2S_InitTypeDef *I2S_InitStruct )
{
uint16_t tmpreg = 0, i2sdiv = 2, i2sodd = 0, packetlength = 1;
uint32_t tmp = 0;
RCC_ClocksTypeDef RCC_Clocks;
uint32_t sourceclock = 0;
SPIx->I2SCFGR &= I2SCFGR_CLEAR_Mask;
SPIx->I2SPR = 0x0002;
tmpreg = SPIx->I2SCFGR;
if( I2S_InitStruct->I2S_AudioFreq == I2S_AudioFreq_Default )
{
i2sodd = ( uint16_t )0;
i2sdiv = ( uint16_t )2;
}
else
{
if( I2S_InitStruct->I2S_DataFormat == I2S_DataFormat_16b )
{
packetlength = 1;
}
else
{
packetlength = 2;
}
if( ( ( uint32_t )SPIx ) == SPI2_BASE )
{
tmp = I2S2_CLOCK_SRC;
}
else
{
tmp = I2S3_CLOCK_SRC;
}
RCC_GetClocksFreq( &RCC_Clocks );
sourceclock = RCC_Clocks.SYSCLK_Frequency;
if( I2S_InitStruct->I2S_MCLKOutput == I2S_MCLKOutput_Enable )
{
tmp = ( uint16_t )( ( ( ( ( sourceclock / 256 ) * 10 ) / I2S_InitStruct->I2S_AudioFreq ) ) + 5 );
}
else
{
tmp = ( uint16_t )( ( ( ( ( sourceclock / ( 32 * packetlength ) ) * 10 ) / I2S_InitStruct->I2S_AudioFreq ) ) + 5 );
}
tmp = tmp / 10;
i2sodd = ( uint16_t )( tmp & ( uint16_t )0x0001 );
i2sdiv = ( uint16_t )( ( tmp - i2sodd ) / 2 );
i2sodd = ( uint16_t )( i2sodd << 8 );
}
if( ( i2sdiv < 2 ) || ( i2sdiv > 0xFF ) )
{
i2sdiv = 2;
i2sodd = 0;
}
SPIx->I2SPR = ( uint16_t )( i2sdiv | ( uint16_t )( i2sodd | ( uint16_t )I2S_InitStruct->I2S_MCLKOutput ) );
tmpreg |= ( uint16_t )( I2S_Mode_Select | ( uint16_t )( I2S_InitStruct->I2S_Mode | \
( uint16_t )( I2S_InitStruct->I2S_Standard | ( uint16_t )( I2S_InitStruct->I2S_DataFormat | \
( uint16_t )I2S_InitStruct->I2S_CPOL ) ) ) );
SPIx->I2SCFGR = tmpreg;
}
/*********************************************************************
* @fn SPI_StructInit
*
* @brief Fills each SPI_InitStruct member with its default value.
*
* @param SPI_InitStruct - pointer to a SPI_InitTypeDef structure which
* will be initialized.
*
* @return none
*/
void SPI_StructInit( SPI_InitTypeDef *SPI_InitStruct )
{
SPI_InitStruct->SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStruct->SPI_Mode = SPI_Mode_Slave;
SPI_InitStruct->SPI_DataSize = SPI_DataSize_8b;
SPI_InitStruct->SPI_CPOL = SPI_CPOL_Low;
SPI_InitStruct->SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStruct->SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
SPI_InitStruct->SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStruct->SPI_CRCPolynomial = 7;
}
/*********************************************************************
* @fn I2S_StructInit
*
* @brief Fills each I2S_InitStruct member with its default value.
*
* @param I2S_InitStruct - pointer to a I2S_InitTypeDef structure which
* will be initialized.
*
* @return none
*/
void I2S_StructInit( I2S_InitTypeDef *I2S_InitStruct )
{
I2S_InitStruct->I2S_Mode = I2S_Mode_SlaveTx;
I2S_InitStruct->I2S_Standard = I2S_Standard_Phillips;
I2S_InitStruct->I2S_DataFormat = I2S_DataFormat_16b;
I2S_InitStruct->I2S_MCLKOutput = I2S_MCLKOutput_Disable;
I2S_InitStruct->I2S_AudioFreq = I2S_AudioFreq_Default;
I2S_InitStruct->I2S_CPOL = I2S_CPOL_Low;
}
/*********************************************************************
* @fn SPI_Cmd
*
* @brief Enables or disables the specified SPI peripheral.
*
* @param SPIx - where x can be 1, 2 or 3 to select the SPI peripheral.
* NewState - ENABLE or DISABLE.
*
* @return none
*/
void SPI_Cmd( SPI_TypeDef *SPIx, FunctionalState NewState )
{
if( NewState != DISABLE )
{
SPIx->CTLR1 |= CTLR1_SPE_Set;
}
else
{
SPIx->CTLR1 &= CTLR1_SPE_Reset;
}
}
/*********************************************************************
* @fn I2S_Cmd
*
* @brief Enables or disables the specified SPI peripheral (in I2S mode).
*
* @param SPIx - where x can be 1, 2 or 3 to select the SPI peripheral.
* NewState - ENABLE or DISABLE.
*
* @return none
*/
void I2S_Cmd( SPI_TypeDef *SPIx, FunctionalState NewState )
{
if( NewState != DISABLE )
{
SPIx->I2SCFGR |= I2SCFGR_I2SE_Set;
}
else
{
SPIx->I2SCFGR &= I2SCFGR_I2SE_Reset;
}
}
/*********************************************************************
* @fn SPI_I2S_ITConfig
*
* @brief Enables or disables the specified SPI/I2S interrupts.
*
* @param SPIx - where x can be
* - 1, 2 or 3 in SPI mode.
* - 2 or 3 in I2S mode.
* SPI_I2S_IT - specifies the SPI/I2S interrupt source to be
* enabled or disabled.
* SPI_I2S_IT_TXE - Tx buffer empty interrupt mask.
* SPI_I2S_IT_RXNE - Rx buffer not empty interrupt mask.
* SPI_I2S_IT_ERR - Error interrupt mask.
* NewState: ENABLE or DISABLE.
* @return none
*/
void SPI_I2S_ITConfig( SPI_TypeDef *SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState )
{
uint16_t itpos = 0, itmask = 0 ;
itpos = SPI_I2S_IT >> 4;
itmask = ( uint16_t )1 << ( uint16_t )itpos;
if( NewState != DISABLE )
{
SPIx->CTLR2 |= itmask;
}
else
{
SPIx->CTLR2 &= ( uint16_t )~itmask;
}
}
/*********************************************************************
* @fn SPI_I2S_DMACmd
*
* @brief Enables or disables the SPIx/I2Sx DMA interface.
*
* @param SPIx - where x can be
* - 1, 2 or 3 in SPI mode.
* - 2 or 3 in I2S mode.
* SPI_I2S_DMAReq - specifies the SPI/I2S DMA transfer request to
* be enabled or disabled.
* SPI_I2S_DMAReq_Tx - Tx buffer DMA transfer request.
* SPI_I2S_DMAReq_Rx - Rx buffer DMA transfer request.
* NewState - ENABLE or DISABLE.
*
* @return none
*/
void SPI_I2S_DMACmd( SPI_TypeDef *SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState )
{
if( NewState != DISABLE )
{
SPIx->CTLR2 |= SPI_I2S_DMAReq;
}
else
{
SPIx->CTLR2 &= ( uint16_t )~SPI_I2S_DMAReq;
}
}
/*********************************************************************
* @fn SPI_I2S_SendData
*
* @brief Transmits a Data through the SPIx/I2Sx peripheral.
*
* @param SPIx - where x can be
* - 1, 2 or 3 in SPI mode.
* - 2 or 3 in I2S mode.
* Data - Data to be transmitted.
*
* @return none
*/
void SPI_I2S_SendData( SPI_TypeDef *SPIx, uint16_t Data )
{
SPIx->DATAR = Data;
}
/*********************************************************************
* @fn SPI_I2S_ReceiveData
*
* @brief Returns the most recent received data by the SPIx/I2Sx peripheral.
*
* @param SPIx - where x can be
* - 1, 2 or 3 in SPI mode.
* - 2 or 3 in I2S mode.
* Data - Data to be transmitted.
*
* @return SPIx->DATAR - The value of the received data.
*/
uint16_t SPI_I2S_ReceiveData( SPI_TypeDef *SPIx )
{
return SPIx->DATAR;
}
/*********************************************************************
* @fn SPI_NSSInternalSoftwareConfig
*
* @brief Configures internally by software the NSS pin for the selected SPI.
*
* @param SPIx - where x can be 1, 2 or 3 to select the SPI peripheral.
* SPI_NSSInternalSoft -
* SPI_NSSInternalSoft_Set - Set NSS pin internally.
* SPI_NSSInternalSoft_Reset - Reset NSS pin internally.
*
* @return none
*/
void SPI_NSSInternalSoftwareConfig( SPI_TypeDef *SPIx, uint16_t SPI_NSSInternalSoft )
{
if( SPI_NSSInternalSoft != SPI_NSSInternalSoft_Reset )
{
SPIx->CTLR1 |= SPI_NSSInternalSoft_Set;
}
else
{
SPIx->CTLR1 &= SPI_NSSInternalSoft_Reset;
}
}
/*********************************************************************
* @fn SPI_SSOutputCmd
*
* @brief Enables or disables the SS output for the selected SPI.
*
* @param SPIx - where x can be 1, 2 or 3 to select the SPI peripheral.
* NewState - new state of the SPIx SS output.
*
* @return none
*/
void SPI_SSOutputCmd( SPI_TypeDef *SPIx, FunctionalState NewState )
{
if( NewState != DISABLE )
{
SPIx->CTLR2 |= CTLR2_SSOE_Set;
}
else
{
SPIx->CTLR2 &= CTLR2_SSOE_Reset;
}
}
/*********************************************************************
* @fn SPI_DataSizeConfig
*
* @brief Configures the data size for the selected SPI.
*
* @param SPIx - where x can be 1, 2 or 3 to select the SPI peripheral.
* SPI_DataSize - specifies the SPI data size.
* SPI_DataSize_16b - Set data frame format to 16bit.
* SPI_DataSize_8b - Set data frame format to 8bit.
*
* @return none
*/
void SPI_DataSizeConfig( SPI_TypeDef *SPIx, uint16_t SPI_DataSize )
{
SPIx->CTLR1 &= ( uint16_t )~SPI_DataSize_16b;
SPIx->CTLR1 |= SPI_DataSize;
}
/*********************************************************************
* @fn SPI_TransmitCRC
*
* @brief Transmit the SPIx CRC value.
*
* @param SPIx - where x can be 1, 2 or 3 to select the SPI peripheral.
*
* @return none
*/
void SPI_TransmitCRC( SPI_TypeDef *SPIx )
{
SPIx->CTLR1 |= CTLR1_CRCNext_Set;
}
/*********************************************************************
* @fn SPI_CalculateCRC
*
* @brief Enables or disables the CRC value calculation of the transferred bytes.
*
* @param SPIx - where x can be 1, 2 or 3 to select the SPI peripheral.
* NewState - new state of the SPIx CRC value calculation.
*
* @return none
*/
void SPI_CalculateCRC( SPI_TypeDef *SPIx, FunctionalState NewState )
{
if( NewState != DISABLE )
{
SPIx->CTLR1 |= CTLR1_CRCEN_Set;
}
else
{
SPIx->CTLR1 &= CTLR1_CRCEN_Reset;
}
}
/*********************************************************************
* @fn SPI_GetCRC
*
* @brief Returns the transmit or the receive CRC register value for the specified SPI.
*
* @param SPIx - where x can be 1, 2 or 3 to select the SPI peripheral.
* SPI_CRC - specifies the CRC register to be read.
* SPI_CRC_Tx - Selects Tx CRC register.
* SPI_CRC_Rx - Selects Rx CRC register.
*
* @return crcreg: The selected CRC register value.
*/
uint16_t SPI_GetCRC( SPI_TypeDef *SPIx, uint8_t SPI_CRC )
{
uint16_t crcreg = 0;
if( SPI_CRC != SPI_CRC_Rx )
{
crcreg = SPIx->TCRCR;
}
else
{
crcreg = SPIx->RCRCR;
}
return crcreg;
}
/*********************************************************************
* @fn SPI_GetCRCPolynomial
*
* @brief Returns the CRC Polynomial register value for the specified SPI.
*
* @param SPIx - where x can be 1, 2 or 3 to select the SPI peripheral.
*
* @return SPIx->CRCR - The CRC Polynomial register value.
*/
uint16_t SPI_GetCRCPolynomial( SPI_TypeDef *SPIx )
{
return SPIx->CRCR;
}
/*********************************************************************
* @fn SPI_BiDirectionalLineConfig
*
* @brief Selects the data transfer direction in bi-directional mode
* for the specified SPI.
*
* @param SPIx - where x can be 1, 2 or 3 to select the SPI peripheral.
* SPI_Direction - specifies the data transfer direction in
* bi-directional mode.
* SPI_Direction_Tx - Selects Tx transmission direction.
* SPI_Direction_Rx - Selects Rx receive direction.
*
* @return none
*/
void SPI_BiDirectionalLineConfig( SPI_TypeDef *SPIx, uint16_t SPI_Direction )
{
if( SPI_Direction == SPI_Direction_Tx )
{
SPIx->CTLR1 |= SPI_Direction_Tx;
}
else
{
SPIx->CTLR1 &= SPI_Direction_Rx;
}
}
/*********************************************************************
* @fn SPI_I2S_GetFlagStatus
*
* @brief Checks whether the specified SPI/I2S flag is set or not.
*
* @param SPIx - where x can be
* - 1, 2 or 3 in SPI mode.
* - 2 or 3 in I2S mode.
* SPI_I2S_FLAG - specifies the SPI/I2S flag to check.
* SPI_I2S_FLAG_TXE - Transmit buffer empty flag.
* SPI_I2S_FLAG_RXNE - Receive buffer not empty flag.
* SPI_I2S_FLAG_BSY - Busy flag.
* SPI_I2S_FLAG_OVR - Overrun flag.
* SPI_FLAG_MODF - Mode Fault flag.
* SPI_FLAG_CRCERR - CRC Error flag.
* I2S_FLAG_UDR - Underrun Error flag.
* I2S_FLAG_CHSIDE - Channel Side flag.
*
* @return FlagStatus: SET or RESET.
*/
FlagStatus SPI_I2S_GetFlagStatus( SPI_TypeDef *SPIx, uint16_t SPI_I2S_FLAG )
{
FlagStatus bitstatus = RESET;
if( ( SPIx->STATR & SPI_I2S_FLAG ) != ( uint16_t )RESET )
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
/*********************************************************************
* @fn SPI_I2S_ClearFlag
*
* @brief Clears the SPIx CRC Error (CRCERR) flag.
*
* @param SPIx - where x can be
* - 1, 2 or 3 in SPI mode.
* - 2 or 3 in I2S mode.
* SPI_I2S_FLAG - specifies the SPI flag to clear.
* SPI_FLAG_CRCERR - CRC Error flag.
*
* @return FlagStatus: SET or RESET.
*/
void SPI_I2S_ClearFlag( SPI_TypeDef *SPIx, uint16_t SPI_I2S_FLAG )
{
SPIx->STATR = ( uint16_t )~SPI_I2S_FLAG;
}
/*********************************************************************
* @fn SPI_I2S_GetITStatus
*
* @brief Checks whether the specified SPI/I2S interrupt has occurred or not.
*
* @param SPIx - where x can be
* - 1, 2 or 3 in SPI mode.
* - 2 or 3 in I2S mode.
* SPI_I2S_IT - specifies the SPI/I2S interrupt source to check..
* SPI_I2S_IT_TXE - Transmit buffer empty interrupt.
* SPI_I2S_IT_RXNE - Receive buffer not empty interrupt.
* SPI_I2S_IT_OVR - Overrun interrupt.
* SPI_IT_MODF - Mode Fault interrupt.
* SPI_IT_CRCERR - CRC Error interrupt.
* I2S_IT_UDR - Underrun Error interrupt.
*
* @return FlagStatus: SET or RESET.
*/
ITStatus SPI_I2S_GetITStatus( SPI_TypeDef *SPIx, uint8_t SPI_I2S_IT )
{
ITStatus bitstatus = RESET;
uint16_t itpos = 0, itmask = 0, enablestatus = 0;
itpos = 0x01 << ( SPI_I2S_IT & 0x0F );
itmask = SPI_I2S_IT >> 4;
itmask = 0x01 << itmask;
enablestatus = ( SPIx->CTLR2 & itmask ) ;
if( ( ( SPIx->STATR & itpos ) != ( uint16_t )RESET ) && enablestatus )
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
/*********************************************************************
* @fn SPI_I2S_ClearITPendingBit
*
* @brief Clears the SPIx CRC Error (CRCERR) interrupt pending bit.
*
* @param SPIx - where x can be
* - 1, 2 or 3 in SPI mode.
* SPI_I2S_IT - specifies the SPI interrupt pending bit to clear.
* SPI_IT_CRCERR - CRC Error interrupt.
*
* @return none
*/
void SPI_I2S_ClearITPendingBit( SPI_TypeDef *SPIx, uint8_t SPI_I2S_IT )
{
uint16_t itpos = 0;
itpos = 0x01 << ( SPI_I2S_IT & 0x0F );
SPIx->STATR = ( uint16_t )~itpos;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,825 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : ch32f10x_usart.c
* Author : WCH
* Version : V1.0.0
* Date : 2019/10/15
* Description : This file provides all the USART firmware functions.
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#include "ch32f10x_usart.h"
#include "ch32f10x_rcc.h"
/* USART_Private_Defines */
#define CTLR1_UE_Set ((uint16_t)0x2000) /* USART Enable Mask */
#define CTLR1_UE_Reset ((uint16_t)0xDFFF) /* USART Disable Mask */
#define CTLR1_WAKE_Mask ((uint16_t)0xF7FF) /* USART WakeUp Method Mask */
#define CTLR1_RWU_Set ((uint16_t)0x0002) /* USART mute mode Enable Mask */
#define CTLR1_RWU_Reset ((uint16_t)0xFFFD) /* USART mute mode Enable Mask */
#define CTLR1_SBK_Set ((uint16_t)0x0001) /* USART Break Character send Mask */
#define CTLR1_CLEAR_Mask ((uint16_t)0xE9F3) /* USART CR1 Mask */
#define CTLR2_Address_Mask ((uint16_t)0xFFF0) /* USART address Mask */
#define CTLR2_LINEN_Set ((uint16_t)0x4000) /* USART LIN Enable Mask */
#define CTLR2_LINEN_Reset ((uint16_t)0xBFFF) /* USART LIN Disable Mask */
#define CTLR2_LBDL_Mask ((uint16_t)0xFFDF) /* USART LIN Break detection Mask */
#define CTLR2_STOP_CLEAR_Mask ((uint16_t)0xCFFF) /* USART CR2 STOP Bits Mask */
#define CTLR2_CLOCK_CLEAR_Mask ((uint16_t)0xF0FF) /* USART CR2 Clock Mask */
#define CTLR3_SCEN_Set ((uint16_t)0x0020) /* USART SC Enable Mask */
#define CTLR3_SCEN_Reset ((uint16_t)0xFFDF) /* USART SC Disable Mask */
#define CTLR3_NACK_Set ((uint16_t)0x0010) /* USART SC NACK Enable Mask */
#define CTLR3_NACK_Reset ((uint16_t)0xFFEF) /* USART SC NACK Disable Mask */
#define CTLR3_HDSEL_Set ((uint16_t)0x0008) /* USART Half-Duplex Enable Mask */
#define CTLR3_HDSEL_Reset ((uint16_t)0xFFF7) /* USART Half-Duplex Disable Mask */
#define CTLR3_IRLP_Mask ((uint16_t)0xFFFB) /* USART IrDA LowPower mode Mask */
#define CTLR3_CLEAR_Mask ((uint16_t)0xFCFF) /* USART CR3 Mask */
#define CTLR3_IREN_Set ((uint16_t)0x0002) /* USART IrDA Enable Mask */
#define CTLR3_IREN_Reset ((uint16_t)0xFFFD) /* USART IrDA Disable Mask */
#define GPR_LSB_Mask ((uint16_t)0x00FF) /* Guard Time Register LSB Mask */
#define GPR_MSB_Mask ((uint16_t)0xFF00) /* Guard Time Register MSB Mask */
#define IT_Mask ((uint16_t)0x001F) /* USART Interrupt Mask */
/* USART OverSampling-8 Mask */
#define CTLR1_OVER8_Set ((uint16_t)0x8000) /* USART OVER8 mode Enable Mask */
#define CTLR1_OVER8_Reset ((uint16_t)0x7FFF) /* USART OVER8 mode Disable Mask */
/* USART One Bit Sampling Mask */
#define CTLR3_ONEBITE_Set ((uint16_t)0x0800) /* USART ONEBITE mode Enable Mask */
#define CTLR3_ONEBITE_Reset ((uint16_t)0xF7FF) /* USART ONEBITE mode Disable Mask */
/*********************************************************************
* @fn USART_DeInit
*
* @brief Deinitializes the USARTx peripheral registers to their default
* reset values.
*
* @param USARTx - where x can be 1, 2 or 3 to select the UART peripheral.
*
* @return none
*/
void USART_DeInit( USART_TypeDef *USARTx )
{
if( USARTx == USART1 )
{
RCC_APB2PeriphResetCmd( RCC_APB2Periph_USART1, ENABLE );
RCC_APB2PeriphResetCmd( RCC_APB2Periph_USART1, DISABLE );
}
else if( USARTx == USART2 )
{
RCC_APB1PeriphResetCmd( RCC_APB1Periph_USART2, ENABLE );
RCC_APB1PeriphResetCmd( RCC_APB1Periph_USART2, DISABLE );
}
else if( USARTx == USART3 )
{
RCC_APB1PeriphResetCmd( RCC_APB1Periph_USART3, ENABLE );
RCC_APB1PeriphResetCmd( RCC_APB1Periph_USART3, DISABLE );
}
else if( USARTx == UART4 )
{
RCC_APB1PeriphResetCmd( RCC_APB1Periph_UART4, ENABLE );
RCC_APB1PeriphResetCmd( RCC_APB1Periph_UART4, DISABLE );
}
else
{
if( USARTx == UART5 )
{
RCC_APB1PeriphResetCmd( RCC_APB1Periph_UART5, ENABLE );
RCC_APB1PeriphResetCmd( RCC_APB1Periph_UART5, DISABLE );
}
}
}
/*********************************************************************
* @fn USART_Init
*
* @brief Initializes the USARTx peripheral according to the specified
* parameters in the USART_InitStruct.
*
* @param USARTx - where x can be 1, 2 or 3 to select the UART peripheral.
* USART_InitStruct - pointer to a USART_InitTypeDef structure
* that contains the configuration information for the specified
* USART peripheral.
*
* @return none
*/
void USART_Init( USART_TypeDef *USARTx, USART_InitTypeDef *USART_InitStruct )
{
uint32_t tmpreg = 0x00, apbclock = 0x00;
uint32_t integerdivider = 0x00;
uint32_t fractionaldivider = 0x00;
uint32_t usartxbase = 0;
RCC_ClocksTypeDef RCC_ClocksStatus;
if( USART_InitStruct->USART_HardwareFlowControl != USART_HardwareFlowControl_None )
{
}
usartxbase = ( uint32_t )USARTx;
tmpreg = USARTx->CTLR2;
tmpreg &= CTLR2_STOP_CLEAR_Mask;
tmpreg |= ( uint32_t )USART_InitStruct->USART_StopBits;
USARTx->CTLR2 = ( uint16_t )tmpreg;
tmpreg = USARTx->CTLR1;
tmpreg &= CTLR1_CLEAR_Mask;
tmpreg |= ( uint32_t )USART_InitStruct->USART_WordLength | USART_InitStruct->USART_Parity |
USART_InitStruct->USART_Mode;
USARTx->CTLR1 = ( uint16_t )tmpreg;
tmpreg = USARTx->CTLR3;
tmpreg &= CTLR3_CLEAR_Mask;
tmpreg |= USART_InitStruct->USART_HardwareFlowControl;
USARTx->CTLR3 = ( uint16_t )tmpreg;
RCC_GetClocksFreq( &RCC_ClocksStatus );
if( usartxbase == USART1_BASE )
{
apbclock = RCC_ClocksStatus.PCLK2_Frequency;
}
else
{
apbclock = RCC_ClocksStatus.PCLK1_Frequency;
}
if( ( USARTx->CTLR1 & CTLR1_OVER8_Set ) != 0 )
{
integerdivider = ( ( 25 * apbclock ) / ( 2 * ( USART_InitStruct->USART_BaudRate ) ) );
}
else
{
integerdivider = ( ( 25 * apbclock ) / ( 4 * ( USART_InitStruct->USART_BaudRate ) ) );
}
tmpreg = ( integerdivider / 100 ) << 4;
fractionaldivider = integerdivider - ( 100 * ( tmpreg >> 4 ) );
if( ( USARTx->CTLR1 & CTLR1_OVER8_Set ) != 0 )
{
tmpreg |= ( ( ( ( fractionaldivider * 8 ) + 50 ) / 100 ) ) & ( ( uint8_t )0x07 );
}
else
{
tmpreg |= ( ( ( ( fractionaldivider * 16 ) + 50 ) / 100 ) ) & ( ( uint8_t )0x0F );
}
USARTx->BRR = ( uint16_t )tmpreg;
}
/*********************************************************************
* @fn USART_StructInit
*
* @brief Fills each USART_InitStruct member with its default value.
*
* @param USART_InitStruct: pointer to a USART_InitTypeDef structure
* which will be initialized.
*
* @return none
*/
void USART_StructInit( USART_InitTypeDef *USART_InitStruct )
{
USART_InitStruct->USART_BaudRate = 9600;
USART_InitStruct->USART_WordLength = USART_WordLength_8b;
USART_InitStruct->USART_StopBits = USART_StopBits_1;
USART_InitStruct->USART_Parity = USART_Parity_No ;
USART_InitStruct->USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStruct->USART_HardwareFlowControl = USART_HardwareFlowControl_None;
}
/*********************************************************************
* @fn USART_ClockInit
*
* @brief Initializes the USARTx peripheral Clock according to the
* specified parameters in the USART_ClockInitStruct .
*
* @param USARTx - where x can be 1, 2, 3 to select the USART peripheral.
* USART_ClockInitStruct - pointer to a USART_ClockInitTypeDef
* structure that contains the configuration information for the specified
* USART peripheral.
*
* @return none
*/
void USART_ClockInit( USART_TypeDef *USARTx, USART_ClockInitTypeDef *USART_ClockInitStruct )
{
uint32_t tmpreg = 0x00;
tmpreg = USARTx->CTLR2;
tmpreg &= CTLR2_CLOCK_CLEAR_Mask;
tmpreg |= ( uint32_t )USART_ClockInitStruct->USART_Clock | USART_ClockInitStruct->USART_CPOL |
USART_ClockInitStruct->USART_CPHA | USART_ClockInitStruct->USART_LastBit;
USARTx->CTLR2 = ( uint16_t )tmpreg;
}
/*********************************************************************
* @fn USART_ClockStructInit
*
* @brief Fills each USART_ClockStructInit member with its default value.
*
* @param USART_ClockInitStruct: pointer to a USART_ClockInitTypeDef
* structure which will be initialized.
*
* @return none
*/
void USART_ClockStructInit( USART_ClockInitTypeDef *USART_ClockInitStruct )
{
USART_ClockInitStruct->USART_Clock = USART_Clock_Disable;
USART_ClockInitStruct->USART_CPOL = USART_CPOL_Low;
USART_ClockInitStruct->USART_CPHA = USART_CPHA_1Edge;
USART_ClockInitStruct->USART_LastBit = USART_LastBit_Disable;
}
/*********************************************************************
* @fn USART_Cmd
*
* @brief Enables or disables the specified USART peripheral.
* reset values (Affects also the I2Ss).
*
* @param USARTx - where x can be 1, 2, 3 to select the USART peripheral.
* NewState: ENABLE or DISABLE.
*
* @return none
*/
void USART_Cmd( USART_TypeDef *USARTx, FunctionalState NewState )
{
if( NewState != DISABLE )
{
USARTx->CTLR1 |= CTLR1_UE_Set;
}
else
{
USARTx->CTLR1 &= CTLR1_UE_Reset;
}
}
/*********************************************************************
* @fn USART_ITConfig
*
* @brief Enables or disables the specified USART interrupts.
* reset values (Affects also the I2Ss).
*
* @param USARTx - where x can be 1, 2, 3 to select the USART peripheral.
* USART_IT - specifies the USART interrupt sources to be enabled or disabled.
* USART_IT_CTS - CTS change interrupt.
* USART_IT_LBD - LIN Break detection interrupt.
* USART_IT_TXE - Transmit Data Register empty interrupt.
* USART_IT_TC - Transmission complete interrupt.
* USART_IT_RXNE - Receive Data register not empty interrupt.
* USART_IT_IDLE - Idle line detection interrupt.
* USART_IT_PE - Parity Error interrupt.
* USART_IT_ERR - Error interrupt.
* NewState - ENABLE or DISABLE.
*
* @return none
*/
void USART_ITConfig( USART_TypeDef *USARTx, uint16_t USART_IT, FunctionalState NewState )
{
uint32_t usartreg = 0x00, itpos = 0x00, itmask = 0x00;
uint32_t usartxbase = 0x00;
if( USART_IT == USART_IT_CTS )
{
}
usartxbase = ( uint32_t )USARTx;
usartreg = ( ( ( uint8_t )USART_IT ) >> 0x05 );
itpos = USART_IT & IT_Mask;
itmask = ( ( ( uint32_t )0x01 ) << itpos );
if( usartreg == 0x01 )
{
usartxbase += 0x0C;
}
else if( usartreg == 0x02 )
{
usartxbase += 0x10;
}
else
{
usartxbase += 0x14;
}
if( NewState != DISABLE )
{
*( __IO uint32_t * )usartxbase |= itmask;
}
else
{
*( __IO uint32_t * )usartxbase &= ~itmask;
}
}
/*********************************************************************
* @fn USART_DMACmd
*
* @brief Enables or disables the USART DMA interface.
*
* @param USARTx - where x can be 1, 2, 3 to select the USART peripheral.
* USART_DMAReq - specifies the DMA request.
* USART_DMAReq_Tx - USART DMA transmit request.
* USART_DMAReq_Rx - USART DMA receive request.
* NewState - ENABLE or DISABLE.
*
* @return none
*/
void USART_DMACmd( USART_TypeDef *USARTx, uint16_t USART_DMAReq, FunctionalState NewState )
{
if( NewState != DISABLE )
{
USARTx->CTLR3 |= USART_DMAReq;
}
else
{
USARTx->CTLR3 &= ( uint16_t )~USART_DMAReq;
}
}
/*********************************************************************
* @fn USART_SetAddress
*
* @brief Sets the address of the USART node.
*
* @param USARTx - where x can be 1, 2, 3 to select the USART peripheral.
* USART_Address - Indicates the address of the USART node.
*
* @return none
*/
void USART_SetAddress( USART_TypeDef *USARTx, uint8_t USART_Address )
{
USARTx->CTLR2 &= CTLR2_Address_Mask;
USARTx->CTLR2 |= USART_Address;
}
/*********************************************************************
* @fn USART_WakeUpConfig
*
* @brief Selects the USART WakeUp method.
*
* @param USARTx - where x can be 1, 2, 3 to select the USART peripheral.
* USART_WakeUp - specifies the USART wakeup method.
* USART_WakeUp_IdleLine - WakeUp by an idle line detection.
* USART_WakeUp_AddressMark - WakeUp by an address mark.
*
* @return none
*/
void USART_WakeUpConfig( USART_TypeDef *USARTx, uint16_t USART_WakeUp )
{
USARTx->CTLR1 &= CTLR1_WAKE_Mask;
USARTx->CTLR1 |= USART_WakeUp;
}
/*********************************************************************
* @fn USART_ReceiverWakeUpCmd
*
* @brief Determines if the USART is in mute mode or not.
*
* @param USARTx - where x can be 1, 2, 3 to select the USART peripheral.
* NewState - ENABLE or DISABLE.
*
* @return none
*/
void USART_ReceiverWakeUpCmd( USART_TypeDef *USARTx, FunctionalState NewState )
{
if( NewState != DISABLE )
{
USARTx->CTLR1 |= CTLR1_RWU_Set;
}
else
{
USARTx->CTLR1 &= CTLR1_RWU_Reset;
}
}
/*********************************************************************
* @fn USART_LINBreakDetectLengthConfig
*
* @brief Sets the USART LIN Break detection length.
*
* @param USARTx - where x can be 1, 2, 3 to select the USART peripheral.
* USART_LINBreakDetectLength - specifies the LIN break detection length.
* USART_LINBreakDetectLength_10b - 10-bit break detection.
* USART_LINBreakDetectLength_11b - 11-bit break detection.
*
* @return none
*/
void USART_LINBreakDetectLengthConfig( USART_TypeDef *USARTx, uint16_t USART_LINBreakDetectLength )
{
USARTx->CTLR2 &= CTLR2_LBDL_Mask;
USARTx->CTLR2 |= USART_LINBreakDetectLength;
}
/*********************************************************************
* @fn USART_LINCmd
*
* @brief Enables or disables the USART LIN mode.
*
* @param USARTx - where x can be 1, 2, 3 to select the USART peripheral.
* NewState - ENABLE or DISABLE.
*
* @return none
*/
void USART_LINCmd( USART_TypeDef *USARTx, FunctionalState NewState )
{
if( NewState != DISABLE )
{
USARTx->CTLR2 |= CTLR2_LINEN_Set;
}
else
{
USARTx->CTLR2 &= CTLR2_LINEN_Reset;
}
}
/*********************************************************************
* @fn USART_SendData
*
* @brief Transmits single data through the USARTx peripheral.
*
* @param USARTx - where x can be 1, 2, 3 to select the USART peripheral.
* Data - the data to transmit.
*
* @return none
*/
void USART_SendData( USART_TypeDef *USARTx, uint16_t Data )
{
USARTx->DATAR = ( Data & ( uint16_t )0x01FF );
}
/*********************************************************************
* @fn USART_ReceiveData
*
* @brief Returns the most recent received data by the USARTx peripheral.
*
* @param USARTx - where x can be 1, 2, 3 to select the USART peripheral.
*
* @return The received data.
*/
uint16_t USART_ReceiveData( USART_TypeDef *USARTx )
{
return ( uint16_t )( USARTx->DATAR & ( uint16_t )0x01FF );
}
/*********************************************************************
* @fn USART_SendBreak
*
* @brief Transmits break characters.
*
* @param USARTx - where x can be 1, 2, 3 to select the USART peripheral.
*
* @return none
*/
void USART_SendBreak( USART_TypeDef *USARTx )
{
USARTx->CTLR1 |= CTLR1_SBK_Set;
}
/*********************************************************************
* @fn USART_SetGuardTime
*
* @brief Sets the specified USART guard time.
*
* @param USARTx - where x can be 1, 2, 3 to select the USART peripheral.
* USART_GuardTime - specifies the guard time.
*
* @return none
*/
void USART_SetGuardTime( USART_TypeDef *USARTx, uint8_t USART_GuardTime )
{
USARTx->GPR &= GPR_LSB_Mask;
USARTx->GPR |= ( uint16_t )( ( uint16_t )USART_GuardTime << 0x08 );
}
/*********************************************************************
* @fn USART_SetPrescaler
*
* @brief Sets the system clock prescaler.
*
* @param USARTx - where x can be 1, 2, 3 to select the USART peripheral.
* USART_Prescaler - specifies the prescaler clock.
*
* @return none
*/
void USART_SetPrescaler( USART_TypeDef *USARTx, uint8_t USART_Prescaler )
{
USARTx->GPR &= GPR_MSB_Mask;
USARTx->GPR |= USART_Prescaler;
}
/*********************************************************************
* @fn USART_SmartCardCmd
*
* @brief Enables or disables the USART Smart Card mode.
*
* @param USARTx - where x can be 1, 2, 3 to select the USART peripheral.
* NewState - ENABLE or DISABLE.
*
* @return none
*/
void USART_SmartCardCmd( USART_TypeDef *USARTx, FunctionalState NewState )
{
if( NewState != DISABLE )
{
USARTx->CTLR3 |= CTLR3_SCEN_Set;
}
else
{
USARTx->CTLR3 &= CTLR3_SCEN_Reset;
}
}
/*********************************************************************
* @fn USART_SmartCardNACKCmd
*
* @brief Enables or disables NACK transmission.
*
* @param USARTx - where x can be 1, 2, 3 to select the USART peripheral.
* NewState - ENABLE or DISABLE.
*
* @return none
*/
void USART_SmartCardNACKCmd( USART_TypeDef *USARTx, FunctionalState NewState )
{
if( NewState != DISABLE )
{
USARTx->CTLR3 |= CTLR3_NACK_Set;
}
else
{
USARTx->CTLR3 &= CTLR3_NACK_Reset;
}
}
/*********************************************************************
* @fn USART_HalfDuplexCmd
*
* @brief Enables or disables the USART Half Duplex communication.
*
* @param USARTx - where x can be 1, 2, 3 to select the USART peripheral.
* NewState - ENABLE or DISABLE.
*
* @return none
*/
void USART_HalfDuplexCmd( USART_TypeDef *USARTx, FunctionalState NewState )
{
if( NewState != DISABLE )
{
USARTx->CTLR3 |= CTLR3_HDSEL_Set;
}
else
{
USARTx->CTLR3 &= CTLR3_HDSEL_Reset;
}
}
/*********************************************************************
* @fn USART_OverSampling8Cmd
*
* @brief Enables or disables the USART's 8x oversampling mode.
*
* @param USARTx - where x can be 1, 2, 3 to select the USART peripheral.
* NewState - ENABLE or DISABLE.
*
* @return none
*/
void USART_OverSampling8Cmd( USART_TypeDef *USARTx, FunctionalState NewState )
{
if( NewState != DISABLE )
{
USARTx->CTLR1 |= CTLR1_OVER8_Set;
}
else
{
USARTx->CTLR1 &= CTLR1_OVER8_Reset;
}
}
/*********************************************************************
* @fn USART_OneBitMethodCmd
*
* @brief Enables or disables the USART's one bit sampling method.
*
* @param USARTx - where x can be 1, 2, 3 to select the USART peripheral.
* NewState - ENABLE or DISABLE.
*
* @return none
*/
void USART_OneBitMethodCmd( USART_TypeDef *USARTx, FunctionalState NewState )
{
if( NewState != DISABLE )
{
USARTx->CTLR3 |= CTLR3_ONEBITE_Set;
}
else
{
USARTx->CTLR3 &= CTLR3_ONEBITE_Reset;
}
}
/*********************************************************************
* @fn USART_IrDAConfig
*
* @brief Configures the USART's IrDA interface.
*
* @param USARTx - where x can be 1, 2, 3 to select the USART peripheral.
* USART_IrDAMode - specifies the IrDA mode.
* USART_IrDAMode_LowPower.
* USART_IrDAMode_Normal.
*
* @return none
*/
void USART_IrDAConfig( USART_TypeDef *USARTx, uint16_t USART_IrDAMode )
{
USARTx->CTLR3 &= CTLR3_IRLP_Mask;
USARTx->CTLR3 |= USART_IrDAMode;
}
/*********************************************************************
* @fn USART_IrDACmd
*
* @brief Enables or disables the USART's IrDA interface.
*
* @param USARTx - where x can be 1, 2, 3 to select the USART peripheral.
* NewState - ENABLE or DISABLE.
*
* @return none
*/
void USART_IrDACmd( USART_TypeDef *USARTx, FunctionalState NewState )
{
if( NewState != DISABLE )
{
USARTx->CTLR3 |= CTLR3_IREN_Set;
}
else
{
USARTx->CTLR3 &= CTLR3_IREN_Reset;
}
}
/*********************************************************************
* @fn USART_GetFlagStatus
*
* @brief Checks whether the specified USART flag is set or not.
*
* @param USARTx - where x can be 1, 2, 3 to select the USART peripheral.
* USART_FLAG - specifies the flag to check.
* USART_FLAG_CTS - CTS Change flag.
* USART_FLAG_LBD - LIN Break detection flag.
* USART_FLAG_TXE - Transmit data register empty flag.
* USART_FLAG_TC - Transmission Complete flag.
* USART_FLAG_RXNE - Receive data register not empty flag.
* USART_FLAG_IDLE - Idle Line detection flag.
* USART_FLAG_ORE - OverRun Error flag.
* USART_FLAG_NE - Noise Error flag.
* USART_FLAG_FE - Framing Error flag.
* USART_FLAG_PE - Parity Error flag.
*
* @return bitstatus: SET or RESET
*/
FlagStatus USART_GetFlagStatus( USART_TypeDef *USARTx, uint16_t USART_FLAG )
{
FlagStatus bitstatus = RESET;
if( USART_FLAG == USART_FLAG_CTS )
{
}
if( ( USARTx->STATR & USART_FLAG ) != ( uint16_t )RESET )
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
/*********************************************************************
* @fn USART_ClearFlag
*
* @brief Clears the USARTx's pending flags.
*
* @param USARTx - where x can be 1, 2, 3 to select the USART peripheral.
* USART_FLAG - specifies the flag to clear.
* USART_FLAG_CTS - CTS Change flag.
* USART_FLAG_LBD - LIN Break detection flag.
* USART_FLAG_TC - Transmission Complete flag.
* USART_FLAG_RXNE - Receive data register not empty flag.
*
* @return none
*/
void USART_ClearFlag( USART_TypeDef *USARTx, uint16_t USART_FLAG )
{
if( ( USART_FLAG & USART_FLAG_CTS ) == USART_FLAG_CTS )
{
}
USARTx->STATR = ( uint16_t )~USART_FLAG;
}
/*********************************************************************
* @fn USART_GetITStatus
*
* @brief Checks whether the specified USART interrupt has occurred or not.
*
* @param USARTx - where x can be 1, 2, 3 to select the USART peripheral.
* USART_IT - specifies the USART interrupt source to check.
* USART_IT_CTS - CTS change interrupt.
* USART_IT_LBD - LIN Break detection interrupt.
* USART_IT_TXE - Tansmit Data Register empty interrupt.
* USART_IT_TC - Transmission complete interrupt.
* USART_IT_RXNE - Receive Data register not empty interrupt.
* USART_IT_IDLE - Idle line detection interrupt.
* USART_IT_ORE_RX - OverRun Error interrupt if the RXNEIE bit is set.
* USART_IT_ORE_ER - OverRun Error interrupt if the EIE bit is set.
* USART_IT_NE - Noise Error interrupt.
* USART_IT_FE - Framing Error interrupt.
* USART_IT_PE - Parity Error interrupt.
*
* @return bitstatus: SET or RESET.
*/
ITStatus USART_GetITStatus( USART_TypeDef *USARTx, uint16_t USART_IT )
{
uint32_t bitpos = 0x00, itmask = 0x00, usartreg = 0x00;
ITStatus bitstatus = RESET;
if( USART_IT == USART_IT_CTS )
{
}
usartreg = ( ( ( uint8_t )USART_IT ) >> 0x05 );
itmask = USART_IT & IT_Mask;
itmask = ( uint32_t )0x01 << itmask;
if( usartreg == 0x01 )
{
itmask &= USARTx->CTLR1;
}
else if( usartreg == 0x02 )
{
itmask &= USARTx->CTLR2;
}
else
{
itmask &= USARTx->CTLR3;
}
bitpos = USART_IT >> 0x08;
bitpos = ( uint32_t )0x01 << bitpos;
bitpos &= USARTx->STATR;
if( ( itmask != ( uint16_t )RESET ) && ( bitpos != ( uint16_t )RESET ) )
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
/*********************************************************************
* @fn USART_ClearITPendingBit
*
* @brief Clears the USARTx's interrupt pending bits.
*
* @param USARTx - where x can be 1, 2, 3 to select the USART peripheral.
* USART_IT - specifies the interrupt pending bit to clear.
* USART_IT_CTS - CTS change interrupt.
* USART_IT_LBD - LIN Break detection interrupt.
* USART_IT_TC - Transmission complete interrupt.
* USART_IT_RXNE - Receive Data register not empty interrupt.
*
* @return none
*/
void USART_ClearITPendingBit( USART_TypeDef *USARTx, uint16_t USART_IT )
{
uint16_t bitpos = 0x00, itmask = 0x00;
if( USART_IT == USART_IT_CTS )
{
}
bitpos = USART_IT >> 0x08;
itmask = ( ( uint16_t )0x01 << ( uint16_t )bitpos );
USARTx->STATR = ( uint16_t )~itmask;
}
@@ -0,0 +1,114 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : ch32f10x_usb.c
* Author : WCH
* Version : V1.0.0
* Date : 2019/10/15
* Description : This file provides all the USB firmware functions.
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#include "ch32f10x_usb.h"
#include "ch32f10x_rcc.h"
#include "debug.h"
/******************************** USB DEVICE **********************************/
/* Endpoint address */
PUINT8 pEP0_RAM_Addr;
PUINT8 pEP1_RAM_Addr;
PUINT8 pEP2_RAM_Addr;
PUINT8 pEP3_RAM_Addr;
/*********************************************************************
* @fn USB_DeviceInit
*
* @brief Initializes USB device.
*
* @return none
*/
void USB_DeviceInit( void )
{
R8_USB_CTRL = 0x00;
R8_UEP4_1_MOD = RB_UEP4_RX_EN | RB_UEP4_TX_EN | RB_UEP1_RX_EN | RB_UEP1_TX_EN;
R8_UEP2_3_MOD = RB_UEP2_RX_EN | RB_UEP2_TX_EN | RB_UEP3_RX_EN | RB_UEP3_TX_EN;
R16_UEP0_DMA = ( UINT16 )( UINT32 )pEP0_RAM_Addr;
R16_UEP1_DMA = ( UINT16 )( UINT32 )pEP1_RAM_Addr;
R16_UEP2_DMA = ( UINT16 )( UINT32 )pEP2_RAM_Addr;
R16_UEP3_DMA = ( UINT16 )( UINT32 )pEP3_RAM_Addr;
R8_UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
R8_UEP1_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
R8_UEP2_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
R8_UEP3_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
R8_UEP4_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
R8_USB_INT_FG = 0xFF;
R8_USB_INT_EN = RB_UIE_SUSPEND | RB_UIE_BUS_RST | RB_UIE_TRANSFER;
R8_USB_DEV_AD = 0x00;
R8_USB_CTRL = RB_UC_DEV_PU_EN | RB_UC_INT_BUSY | RB_UC_DMA_EN;
R8_UDEV_CTRL = RB_UD_PD_DIS | RB_UD_PORT_EN;
}
/*********************************************************************
* @fn DevEP1_IN_Deal
*
* @brief Device endpoint1 IN
*
* @param l: IN length(<64B)
*
* @return none
*/
void DevEP1_IN_Deal( UINT8 l )
{
R8_UEP1_T_LEN = l;
R8_UEP1_CTRL = ( R8_UEP1_CTRL & ~MASK_UEP_T_RES ) | UEP_T_RES_ACK;
}
/*********************************************************************
* @fn DevEP2_IN_Deal
*
* @brief Device endpoint2 IN
*
* @param l: IN length(<64B)
*
* @return none
*/
void DevEP2_IN_Deal( UINT8 l )
{
R8_UEP2_T_LEN = l;
R8_UEP2_CTRL = ( R8_UEP2_CTRL & ~MASK_UEP_T_RES ) | UEP_T_RES_ACK;
}
/*********************************************************************
* @fn DevEP3_IN_Deal
*
* @brief Device endpoint3 IN
*
* @param l: IN length(<64B)
*
* @return none
*/
void DevEP3_IN_Deal( UINT8 l )
{
R8_UEP3_T_LEN = l;
R8_UEP3_CTRL = ( R8_UEP3_CTRL & ~MASK_UEP_T_RES ) | UEP_T_RES_ACK;
}
/*********************************************************************
* @fn DevEP4_IN_Deal
*
* @brief Device endpoint4 IN
*
* @param l: IN length(<64B)
*
* @return none
*/
void DevEP4_IN_Deal( UINT8 l )
{
R8_UEP4_T_LEN = l;
R8_UEP4_CTRL = ( R8_UEP4_CTRL & ~MASK_UEP_T_RES ) | UEP_T_RES_ACK;
}
@@ -0,0 +1,879 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : ch32f10x_usb_host.c
* Author : WCH
* Version : V1.0.0
* Date : 2019/10/15
* Description : This file provides all the USB firmware functions.
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* SPDX-License-Identifier: Apache-2.0
*******************************************************************************/
#include "ch32f10x_usb_host.h"
#include "debug.h"
/******************************** HOST DEVICE **********************************/
UINT8 UsbDevEndp0Size;
UINT8 FoundNewDev;
_RootHubDev ThisUsbDev;
PUINT8 pHOST_RX_RAM_Addr;
PUINT8 pHOST_TX_RAM_Addr;
extern UINT8 Com_Buffer[128];
__align( 4 ) const UINT8 SetupGetDevDescr[] = { USB_REQ_TYP_IN, USB_GET_DESCRIPTOR, 0x00, USB_DESCR_TYP_DEVICE, 0x00, 0x00, sizeof( USB_DEV_DESCR ), 0x00 };
__align( 4 ) const UINT8 SetupGetCfgDescr[] = { USB_REQ_TYP_IN, USB_GET_DESCRIPTOR, 0x00, USB_DESCR_TYP_CONFIG, 0x00, 0x00, 0x04, 0x00 };
__align( 4 ) const UINT8 SetupSetUsbAddr[] = { USB_REQ_TYP_OUT, USB_SET_ADDRESS, USB_DEVICE_ADDR, 0x00, 0x00, 0x00, 0x00, 0x00 };
__align( 4 ) const UINT8 SetupSetUsbConfig[] = { USB_REQ_TYP_OUT, USB_SET_CONFIGURATION, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
__align( 4 ) const UINT8 SetupSetUsbInterface[] = { USB_REQ_RECIP_INTERF, USB_SET_INTERFACE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
__align( 4 ) const UINT8 SetupClrEndpStall[] = { USB_REQ_TYP_OUT | USB_REQ_RECIP_ENDP, USB_CLEAR_FEATURE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
/*********************************************************************
* @fn DisableRootHubPort( )
*
* @brief Disable root hub
*
* @return none
*/
void DisableRootHubPort( void )
{
#ifdef FOR_ROOT_UDISK_ONLY
CH103DiskStatus = DISK_DISCONNECT;
#endif
#ifndef DISK_BASE_BUF_LEN
ThisUsbDev.DeviceStatus = ROOT_DEV_DISCONNECT;
ThisUsbDev.DeviceAddress = 0x00;
#endif
}
/*********************************************************************
* @fn AnalyzeRootHub
*
* @brief Analyze root hub state.
*
* @return Error
*/
UINT8 AnalyzeRootHub( void )
{
UINT8 s;
s = ERR_SUCCESS;
if( R8_USB_MIS_ST & RB_UMS_DEV_ATTACH )
{
#ifdef DISK_BASE_BUF_LEN
if( CH103DiskStatus == DISK_DISCONNECT
#else
if( ThisUsbDev.DeviceStatus == ROOT_DEV_DISCONNECT
#endif
|| ( R8_UHOST_CTRL & RB_UH_PORT_EN ) == 0x00 )
{
DisableRootHubPort( );
#ifdef DISK_BASE_BUF_LEN
CH103DiskStatus = DISK_CONNECT;
#else
ThisUsbDev.DeviceSpeed = R8_USB_MIS_ST & RB_UMS_DM_LEVEL ? 0 : 1;
ThisUsbDev.DeviceStatus = ROOT_DEV_CONNECTED;
#endif
s = ERR_USB_CONNECT;
}
}
#ifdef DISK_BASE_BUF_LEN
else if( CH103DiskStatus >= DISK_CONNECT )
{
#else
else if( ThisUsbDev.DeviceStatus >= ROOT_DEV_CONNECTED )
{
#endif
DisableRootHubPort( );
if( s == ERR_SUCCESS )
{
s = ERR_USB_DISCON;
}
}
return( s );
}
/*********************************************************************
* @fn SetHostUsbAddr
*
* @brief Set USB host address
*
* @param addr - host address
*
* @return none
*/
void SetHostUsbAddr( UINT8 addr )
{
R8_USB_DEV_AD = ( R8_USB_DEV_AD & RB_UDA_GP_BIT ) | ( addr & MASK_USB_ADDR );
}
#ifndef FOR_ROOT_UDISK_ONLY
/*********************************************************************
* @fn SetUsbSpeed
*
* @brief Set USB speed.
*
* @param FullSpeed - USB speed.
*
* @return none
*/
void SetUsbSpeed( UINT8 FullSpeed )
{
if( FullSpeed )
{
R8_USB_CTRL &= ~ RB_UC_LOW_SPEED;
R8_UH_SETUP &= ~ RB_UH_PRE_PID_EN;
}
else
{
R8_USB_CTRL |= RB_UC_LOW_SPEED;
}
}
#endif
/*********************************************************************
* @fn ResetRootHubPort( )
*
* @brief Reset root hub
*
* @return none
*/
void ResetRootHubPort( void )
{
UsbDevEndp0Size = DEFAULT_ENDP0_SIZE;
SetHostUsbAddr( 0x00 );
R8_UHOST_CTRL &= ~RB_UH_PORT_EN;
SetUsbSpeed( 1 );
R8_UHOST_CTRL = ( R8_UHOST_CTRL & ~RB_UH_LOW_SPEED ) | RB_UH_BUS_RESET;
Delay_Ms( 15 );
R8_UHOST_CTRL = R8_UHOST_CTRL & ~ RB_UH_BUS_RESET;
Delay_Us( 250 );
R8_USB_INT_FG = RB_UIF_DETECT;
}
/*********************************************************************
* @fn EnableRootHubPort( )
*
* @brief Enable root hub.
*
* @return ERROR
*/
UINT8 EnableRootHubPort( void )
{
#ifdef DISK_BASE_BUF_LEN
if( CH103DiskStatus < DISK_CONNECT )
{
CH103DiskStatus = DISK_CONNECT;
}
#else
if( ThisUsbDev.DeviceStatus < ROOT_DEV_CONNECTED )
{
ThisUsbDev.DeviceStatus = ROOT_DEV_CONNECTED;
}
#endif
if( R8_USB_MIS_ST & RB_UMS_DEV_ATTACH )
{
#ifndef DISK_BASE_BUF_LEN
if( ( R8_UHOST_CTRL & RB_UH_PORT_EN ) == 0x00 )
{
ThisUsbDev.DeviceSpeed = ( R8_USB_MIS_ST & RB_UMS_DM_LEVEL ) ? 0 : 1;
if( ThisUsbDev.DeviceSpeed == 0 )
{
R8_UHOST_CTRL |= RB_UH_LOW_SPEED;
}
}
#endif
R8_UHOST_CTRL |= RB_UH_PORT_EN;
return( ERR_SUCCESS );
}
return( ERR_USB_DISCON );
}
/*********************************************************************
* @fn WaitUSB_Interrupt
*
* @brief Wait USB Interrput.
*
* @return ERROR
*/
UINT8 WaitUSB_Interrupt( void )
{
UINT16 i;
for( i = WAIT_USB_TOUT_200US; i != 0 && ( R8_USB_INT_FG & RB_UIF_TRANSFER ) == 0; i -- ) {;}
return( ( R8_USB_INT_FG & RB_UIF_TRANSFER ) ? ERR_SUCCESS : ERR_USB_UNKNOWN );
}
/*********************************************************************
* @fn USBHostTransact
*
* @brief USB host transport transaction
* @param endp_pid: endpoint and PID
* tog: Synchronization flag
* timeout: timeout times
*
* @return EEROR:
* ERR_USB_UNKNOWN
* ERR_USB_DISCON
* ERR_USB_CONNECT
* ERR_SUCCESS
*/
UINT8 USBHostTransact( UINT8 endp_pid, UINT8 tog, UINT32 timeout )
{
UINT8 TransRetry;
UINT8 s, r;
UINT16 i;
R8_UH_RX_CTRL = R8_UH_TX_CTRL = tog;
TransRetry = 0;
do
{
R8_UH_EP_PID = endp_pid;
R8_USB_INT_FG = RB_UIF_TRANSFER;
for( i = WAIT_USB_TOUT_200US; i != 0 && ( R8_USB_INT_FG & RB_UIF_TRANSFER ) == 0; i -- );
R8_UH_EP_PID = 0x00;
if( ( R8_USB_INT_FG & RB_UIF_TRANSFER ) == 0 )
{
return( ERR_USB_UNKNOWN );
}
if( R8_USB_INT_FG & RB_UIF_DETECT )
{
R8_USB_INT_FG = RB_UIF_DETECT;
s = AnalyzeRootHub( );
if( s == ERR_USB_CONNECT )
{
FoundNewDev = 1;
}
#ifdef DISK_BASE_BUF_LEN
if( CH103DiskStatus == DISK_DISCONNECT )
{
return( ERR_USB_DISCON );
}
if( CH103DiskStatus == DISK_CONNECT )
{
return( ERR_USB_CONNECT );
}
#else
if( ThisUsbDev.DeviceStatus == ROOT_DEV_DISCONNECT )
{
return( ERR_USB_DISCON );
}
if( ThisUsbDev.DeviceStatus == ROOT_DEV_CONNECTED )
{
return( ERR_USB_CONNECT );
}
#endif
Delay_Us( 200 );
}
if( R8_USB_INT_FG & RB_UIF_TRANSFER )
{
if( R8_USB_INT_ST & RB_UIS_TOG_OK )
{
return( ERR_SUCCESS );
}
r = R8_USB_INT_ST & MASK_UIS_H_RES;
if( r == USB_PID_STALL )
{
return( r | ERR_USB_TRANSFER );
}
if( r == USB_PID_NAK )
{
if( timeout == 0 )
{
return( r | ERR_USB_TRANSFER );
}
if( timeout < 0xFFFF )
{
timeout --;
}
-- TransRetry;
}
else switch( endp_pid >> 4 )
{
case USB_PID_SETUP:
case USB_PID_OUT:
if( r )
{
return( r | ERR_USB_TRANSFER );
}
break;
case USB_PID_IN:
if( r == USB_PID_DATA0 && r == USB_PID_DATA1 )
{
}
else if( r )
{
return( r | ERR_USB_TRANSFER );
}
break;
default:
return( ERR_USB_UNKNOWN );
}
}
else
{
R8_USB_INT_FG = 0xFF;
}
Delay_Us( 15 );
}
while( ++ TransRetry < 3 );
return( ERR_USB_TRANSFER );
}
/*********************************************************************
* @fn HostCtrlTransfer
*
* @brief Host control transport.
*
* @param DataBuf : Receive or send data buffer.
* RetLen : Data length.
*
* @return ERR_USB_BUF_OVER IN
* ERR_SUCCESS
*/
UINT8 HostCtrlTransfer( PUINT8 DataBuf, PUINT8 RetLen )
{
UINT16 RemLen = 0;
UINT8 s, RxLen, RxCnt, TxCnt;
PUINT8 pBuf;
PUINT8 pLen;
pBuf = DataBuf;
pLen = RetLen;
Delay_Us( 200 );
if( pLen )
{
*pLen = 0;
}
R8_UH_TX_LEN = sizeof( USB_SETUP_REQ );
s = USBHostTransact( USB_PID_SETUP << 4 | 0x00, 0x00, 200000 / 20 );
if( s != ERR_SUCCESS )
{
return( s );
}
R8_UH_RX_CTRL = R8_UH_TX_CTRL = RB_UH_R_TOG | RB_UH_R_AUTO_TOG | RB_UH_T_TOG | RB_UH_T_AUTO_TOG;
R8_UH_TX_LEN = 0x01;
RemLen = pSetupReq -> wLength;
if( RemLen && pBuf )
{
if( pSetupReq -> bRequestType & USB_REQ_TYP_IN )
{
while( RemLen )
{
Delay_Us( 200 );
s = USBHostTransact( USB_PID_IN << 4 | 0x00, R8_UH_RX_CTRL, 200000 / 20 );
if( s != ERR_SUCCESS )
{
return( s );
}
RxLen = R8_USB_RX_LEN < RemLen ? R8_USB_RX_LEN : RemLen;
RemLen -= RxLen;
if( pLen )
{
*pLen += RxLen;
}
for( RxCnt = 0; RxCnt != RxLen; RxCnt ++ )
{
*pBuf = pHOST_RX_RAM_Addr[ RxCnt ];
pBuf ++;
}
if( R8_USB_RX_LEN == 0 || ( R8_USB_RX_LEN & ( UsbDevEndp0Size - 1 ) ) )
{
break;
}
}
R8_UH_TX_LEN = 0x00;
}
else
{
while( RemLen )
{
Delay_Us( 200 );
R8_UH_TX_LEN = RemLen >= UsbDevEndp0Size ? UsbDevEndp0Size : RemLen;
for( TxCnt = 0; TxCnt != R8_UH_TX_LEN; TxCnt ++ )
{
pHOST_TX_RAM_Addr[ TxCnt ] = *pBuf;
pBuf ++;
}
s = USBHostTransact( USB_PID_OUT << 4 | 0x00, R8_UH_TX_CTRL, 200000 / 20 );
if( s != ERR_SUCCESS )
{
return( s );
}
RemLen -= R8_UH_TX_LEN;
if( pLen )
{
*pLen += R8_UH_TX_LEN;
}
}
}
}
Delay_Us( 200 );
s = USBHostTransact( ( R8_UH_TX_LEN ? USB_PID_IN << 4 | 0x00 : USB_PID_OUT << 4 | 0x00 ), RB_UH_R_TOG | RB_UH_T_TOG, 200000 / 20 );
if( s != ERR_SUCCESS )
{
return( s );
}
if( R8_UH_TX_LEN == 0 )
{
return( ERR_SUCCESS );
}
if( R8_USB_RX_LEN == 0 )
{
return( ERR_SUCCESS );
}
return( ERR_USB_BUF_OVER );
}
/*********************************************************************
* @fn CopySetupReqPkg
*
* @brief Copy setup request package.
*
* @param pReqPkt: setup request package address.
*
* @return none
*/
void CopySetupReqPkg( const UINT8 *pReqPkt )
{
UINT8 i;
for( i = 0; i != sizeof( USB_SETUP_REQ ); i ++ ){
( ( PUINT8 )pSetupReq )[ i ] = *pReqPkt;
pReqPkt++;
}
}
/*********************************************************************
* @fn CtrlGetDeviceDescr
*
* @brief Get device descrptor.
*
* @param DataBuf: Data buffer.
*
* @return ERR_USB_BUF_OVER
* ERR_SUCCESS
*/
UINT8 CtrlGetDeviceDescr( PUINT8 DataBuf )
{
UINT8 s;
UINT8 len;
UsbDevEndp0Size = DEFAULT_ENDP0_SIZE;
CopySetupReqPkg( SetupGetDevDescr );
s = HostCtrlTransfer( DataBuf, &len );
if( s != ERR_SUCCESS )
{
return( s );
}
UsbDevEndp0Size = ( ( PUSB_DEV_DESCR )DataBuf ) -> bMaxPacketSize0;
if( len < ( ( PUSB_SETUP_REQ )SetupGetDevDescr )->wLength )
{
return( ERR_USB_BUF_OVER );
}
return( ERR_SUCCESS );
}
/*********************************************************************
* @fn CtrlGetConfigDescr
*
* @brief Get configration descrptor.
*
* @param DataBuf: Data buffer.
*
* @return ERR_USB_BUF_OVER
* ERR_SUCCESS
*/
UINT8 CtrlGetConfigDescr( PUINT8 DataBuf )
{
UINT8 s;
UINT8 len;
CopySetupReqPkg( SetupGetCfgDescr );
s = HostCtrlTransfer( DataBuf, &len );
if( s != ERR_SUCCESS )
{
return( s );
}
if( len < ( ( PUSB_SETUP_REQ )SetupGetCfgDescr ) -> wLength )
{
return( ERR_USB_BUF_OVER );
}
len = ( ( PUSB_CFG_DESCR )DataBuf ) -> wTotalLength;
CopySetupReqPkg( SetupGetCfgDescr );
pSetupReq ->wLength = len;
s = HostCtrlTransfer( DataBuf, &len );
if( s != ERR_SUCCESS )
{
return( s );
}
return( ERR_SUCCESS );
}
/*********************************************************************
* @fn CtrlSetUsbAddress
*
* @brief Set USB device address.
*
* @param addr: Device address.
*
* @return ERR_SUCCESS
*/
UINT8 CtrlSetUsbAddress( UINT8 addr )
{
UINT8 s;
CopySetupReqPkg( SetupSetUsbAddr );
pSetupReq -> wValue = addr;
s = HostCtrlTransfer( NULL, NULL );
if( s != ERR_SUCCESS )
{
return( s );
}
SetHostUsbAddr( addr );
Delay_Ms( 10 );
return( ERR_SUCCESS );
}
/*********************************************************************
* @fn CtrlSetUsbConfig
*
* @brief Set usb configration.
*
* @param cfg: Configration Value.
*
* @return ERR_SUCCESS
*/
UINT8 CtrlSetUsbConfig( UINT8 cfg )
{
CopySetupReqPkg( SetupSetUsbConfig );
pSetupReq -> wValue = cfg;
return( HostCtrlTransfer( NULL, NULL ) );
}
/*********************************************************************
* @fn CtrlClearEndpStall
*
* @brief Clear endpoint STALL.
*
* @param endp: Endpoint address.
*
* @return ERR_SUCCESS
*/
UINT8 CtrlClearEndpStall( UINT8 endp )
{
CopySetupReqPkg( SetupClrEndpStall );
pSetupReq -> wIndex = endp;
return( HostCtrlTransfer( NULL, NULL ) );
}
/*********************************************************************
* @fn CtrlSetUsbIntercace
*
* @brief Set USB Interface configration.
*
* @param cfg: Configration value.
*
* @return ERR_SUCCESS
*/
UINT8 CtrlSetUsbIntercace( UINT8 cfg )
{
CopySetupReqPkg( SetupSetUsbInterface );
pSetupReq -> wValue = cfg;
return( HostCtrlTransfer( NULL, NULL ) );
}
/*********************************************************************
* @fn USB_HostInit
*
* @brief Initializes USB host mode.
*
* @return ERR_SUCCESS
*/
void USB_HostInit( void )
{
R8_USB_CTRL = RB_UC_HOST_MODE;
R8_UHOST_CTRL = 0;
R8_USB_DEV_AD = 0x00;
R8_UH_EP_MOD = RB_UH_EP_TX_EN | RB_UH_EP_RX_EN;
R16_UH_RX_DMA = ( UINT16 )( UINT32 )pHOST_RX_RAM_Addr;
R16_UH_TX_DMA = ( UINT16 )( UINT32 )pHOST_TX_RAM_Addr;
R8_UH_RX_CTRL = 0x00;
R8_UH_TX_CTRL = 0x00;
R8_USB_CTRL = RB_UC_HOST_MODE | RB_UC_INT_BUSY | RB_UC_DMA_EN;
R8_UH_SETUP = RB_UH_SOF_EN;
R8_USB_INT_FG = 0xFF;
DisableRootHubPort( );
R8_USB_INT_EN = RB_UIE_TRANSFER | RB_UIE_DETECT;
FoundNewDev = 0;
}
/*********************************************************************
* @fn InitRootDevice
*
* @brief Initializes USB root hub.
*
* @param DataBuf: Data buffer.
*
* @return ERROR
*/
UINT8 InitRootDevice( PUINT8 DataBuf )
{
UINT8 i, s;
UINT8 cfg, dv_cls, if_cls;
ResetRootHubPort( );
for( i = 0, s = 0; i < 100; i ++ )
{
Delay_Ms( 1 );
if( EnableRootHubPort( ) == ERR_SUCCESS )
{
i = 0;
s ++;
if( s > 100 )
{
break;
}
}
}
if( i )
{
DisableRootHubPort( );
return( ERR_USB_DISCON );
}
SetUsbSpeed( ThisUsbDev.DeviceSpeed );
s = CtrlGetDeviceDescr( DataBuf );
if( s == ERR_SUCCESS )
{
ThisUsbDev.DeviceVID = ( ( PUSB_DEV_DESCR )DataBuf )->idVendor;
ThisUsbDev.DevicePID = ( ( PUSB_DEV_DESCR )DataBuf )->idProduct;
dv_cls = ( ( PUSB_DEV_DESCR )DataBuf ) -> bDeviceClass;
s = CtrlSetUsbAddress( ( ( PUSB_SETUP_REQ )SetupSetUsbAddr )->wValue );
if( s == ERR_SUCCESS )
{
ThisUsbDev.DeviceAddress = ( ( PUSB_SETUP_REQ )SetupSetUsbAddr )->wValue;
s = CtrlGetConfigDescr( DataBuf );
if( s == ERR_SUCCESS )
{
cfg = ( ( PUSB_CFG_DESCR )DataBuf )->bConfigurationValue;
if_cls = ( ( PUSB_CFG_DESCR_LONG )DataBuf )->itf_descr.bInterfaceClass;
if( ( dv_cls == 0x00 ) && ( if_cls == USB_DEV_CLASS_STORAGE ) )
{
#ifdef FOR_ROOT_UDISK_ONLY
CH103DiskStatus = DISK_USB_ADDR;
return( ERR_SUCCESS );
}
else
{
return( ERR_USB_UNSUPPORT );
}
#else
s = CtrlSetUsbConfig( cfg );
if( s == ERR_SUCCESS )
{
ThisUsbDev.DeviceStatus = ROOT_DEV_SUCCESS;
ThisUsbDev.DeviceType = USB_DEV_CLASS_STORAGE;
SetUsbSpeed( 1 );
return( ERR_SUCCESS );
}
}
else if( ( dv_cls == 0x00 ) && ( if_cls == USB_DEV_CLASS_PRINTER ) && ( ( PUSB_CFG_DESCR_LONG )DataBuf )->itf_descr.bInterfaceSubClass == 0x01 )
{
s = CtrlSetUsbConfig( cfg );
if( s == ERR_SUCCESS )
{
ThisUsbDev.DeviceStatus = ROOT_DEV_SUCCESS;
ThisUsbDev.DeviceType = USB_DEV_CLASS_PRINTER;
SetUsbSpeed( 1 );
return( ERR_SUCCESS );
}
}
else if( ( dv_cls == 0x00 ) && ( if_cls == USB_DEV_CLASS_HID ) && ( ( PUSB_CFG_DESCR_LONG )DataBuf )->itf_descr.bInterfaceSubClass <= 0x01 )
{
if_cls = ( ( PUSB_CFG_DESCR_LONG )DataBuf ) -> itf_descr.bInterfaceProtocol;
s = CtrlSetUsbConfig( cfg );
if( s == ERR_SUCCESS )
{
ThisUsbDev.DeviceStatus = ROOT_DEV_SUCCESS;
if( if_cls == 1 )
{
ThisUsbDev.DeviceType = DEV_TYPE_KEYBOARD;
SetUsbSpeed( 1 );
return( ERR_SUCCESS );
}
else if( if_cls == 2 )
{
ThisUsbDev.DeviceType = DEV_TYPE_MOUSE;
SetUsbSpeed( 1 );
return( ERR_SUCCESS );
}
s = ERR_USB_UNSUPPORT;
}
}
else
{
s = CtrlSetUsbConfig( cfg );
if( s == ERR_SUCCESS )
{
ThisUsbDev.DeviceStatus = ROOT_DEV_SUCCESS;
ThisUsbDev.DeviceType = DEV_TYPE_UNKNOW;
SetUsbSpeed( 1 );
return( ERR_SUCCESS );
}
}
#endif
}
}
}
#ifdef FOR_ROOT_UDISK_ONLY
CH103DiskStatus = DISK_CONNECT;
#else
ThisUsbDev.DeviceStatus = ROOT_DEV_FAILED;
#endif
SetUsbSpeed( 1 );
return( s );
}
/*********************************************************************
* @fn HubGetPortStatus
*
* @brief 查询HUB端口状态,返回在Com_Buffer中
*
* @param UINT8 HubPortIndex
*
* @return ERR_SUCCESS 成功
* ERR_USB_BUF_OVER 长度错误
*/
UINT8 HubGetPortStatus( UINT8 HubPortIndex )
{
UINT8 s;
UINT8 len;
pSetupReq -> bRequestType = HUB_GET_PORT_STATUS;
pSetupReq -> bRequest = HUB_GET_STATUS;
pSetupReq -> wValue = 0x0000;
pSetupReq -> wIndex = 0x0000 | HubPortIndex;
pSetupReq -> wLength = 0x0004;
s = HostCtrlTransfer( Com_Buffer, &len ); // 执行控制传输
if( s != ERR_SUCCESS )
{
return( s );
}
if( len < 4 )
{
return( ERR_USB_BUF_OVER ); // 描述符长度错误
}
return( ERR_SUCCESS );
}
/*********************************************************************
* @fn HubSetPortFeature
*
* @brief 设置HUB端口特性
*
* @param UINT8 HubPortIndex
* UINT8 FeatureSelt
*
* @return ERR_SUCCESS 成功
*/
UINT8 HubSetPortFeature( UINT8 HubPortIndex, UINT8 FeatureSelt )
{
pSetupReq -> bRequestType = HUB_SET_PORT_FEATURE;
pSetupReq -> bRequest = HUB_SET_FEATURE;
pSetupReq -> wValue = 0x0000 | FeatureSelt;
pSetupReq -> wIndex = 0x0000 | HubPortIndex;
pSetupReq -> wLength = 0x0000;
return( HostCtrlTransfer( NULL, NULL ) ); // 执行控制传输
}
/*********************************************************************
* @fn HubClearPortFeature
*
* @brief 清除HUB端口特性
*
* @param UINT8 HubPortIndex
* UINT8 FeatureSelt
*
* @return ERR_SUCCESS 成功
*/
UINT8 HubClearPortFeature( UINT8 HubPortIndex, UINT8 FeatureSelt )
{
pSetupReq -> bRequestType = HUB_CLEAR_PORT_FEATURE;
pSetupReq -> bRequest = HUB_CLEAR_FEATURE;
pSetupReq -> wValue = 0x0000 | FeatureSelt;
pSetupReq -> wIndex = 0x0000 | HubPortIndex;
pSetupReq -> wLength = 0x0000;
return( HostCtrlTransfer( NULL, NULL ) ); // 执行控制传输
}
@@ -0,0 +1,150 @@
/********************************** (C) COPYRIGHT *******************************
* File Name : ch32f10x_wwdg.c
* Author : WCH
* Version : V1.0.0
* Date : 2019/10/15
* Description : This file provides all the WWDG firmware functions.
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* SPDX-License-Identifier: Apache-2.0
**********************************************************************************/
#include "ch32f10x_wwdg.h"
#include "ch32f10x_rcc.h"
/* WWDG registers bit address in the alias region */
#define WWDG_OFFSET (WWDG_BASE - PERIPH_BASE)
/* Alias word address of EWI bit */
#define CFGR_OFFSET (WWDG_OFFSET + 0x04)
#define EWI_BitNumber 0x09
#define CFGR_EWI_BB (PERIPH_BB_BASE + (CFGR_OFFSET * 32) + (EWI_BitNumber * 4))
/* CTLR register bit mask */
#define CTLR_WDGA_Set ((uint32_t)0x00000080)
/* CFGR register bit mask */
#define CFGR_WDGTB_Mask ((uint32_t)0xFFFFFE7F)
#define CFGR_W_Mask ((uint32_t)0xFFFFFF80)
#define BIT_Mask ((uint8_t)0x7F)
/*********************************************************************
* @fn WWDG_DeInit
*
* @brief Deinitializes the WWDG peripheral registers to their default reset values
*
* @return none
*/
void WWDG_DeInit( void )
{
RCC_APB1PeriphResetCmd( RCC_APB1Periph_WWDG, ENABLE );
RCC_APB1PeriphResetCmd( RCC_APB1Periph_WWDG, DISABLE );
}
/*********************************************************************
* @fn WWDG_SetPrescaler
*
* @brief Sets the WWDG Prescaler
*
* @param WWDG_Prescaler - specifies the WWDG Prescaler
* WWDG_Prescaler_1 - WWDG counter clock = (PCLK1/4096)/1
* WWDG_Prescaler_2 - WWDG counter clock = (PCLK1/4096)/2
* WWDG_Prescaler_4 - WWDG counter clock = (PCLK1/4096)/4
* WWDG_Prescaler_8 - WWDG counter clock = (PCLK1/4096)/8
*
* @return none
*/
void WWDG_SetPrescaler( uint32_t WWDG_Prescaler )
{
uint32_t tmpreg = 0;
tmpreg = WWDG->CFGR & CFGR_WDGTB_Mask;
tmpreg |= WWDG_Prescaler;
WWDG->CFGR = tmpreg;
}
/*********************************************************************
* @fn WWDG_SetWindowValue
*
* @brief Sets the WWDG window value
*
* @param WindowValue - specifies the window value to be compared to the
* downcounter,which must be lower than 0x80
*
* @return none
*/
void WWDG_SetWindowValue( uint8_t WindowValue )
{
__IO uint32_t tmpreg = 0;
tmpreg = WWDG->CFGR & CFGR_W_Mask;
tmpreg |= WindowValue & ( uint32_t ) BIT_Mask;
WWDG->CFGR = tmpreg;
}
/*********************************************************************
* @fn WWDG_EnableIT
*
* @brief Enables the WWDG Early Wakeup interrupt(EWI)
*
* @return none
*/
void WWDG_EnableIT( void )
{
*( __IO uint32_t * ) CFGR_EWI_BB = ( uint32_t )ENABLE;
}
/*********************************************************************
* @fn WWDG_SetCounter
*
* @brief Sets the WWDG counter value
*
* @param Counter - specifies the watchdog counter value,which must be a
* number between 0x40 and 0x7F
*
* @return none
*/
void WWDG_SetCounter( uint8_t Counter )
{
WWDG->CTLR = Counter & BIT_Mask;
}
/*********************************************************************
* @fn WWDG_Enable
*
* @brief Enables WWDG and load the counter value
*
* @param Counter - specifies the watchdog counter value,which must be a
* number between 0x40 and 0x7F
* @return none
*/
void WWDG_Enable( uint8_t Counter )
{
WWDG->CTLR = CTLR_WDGA_Set | Counter;
}
/*********************************************************************
* @fn WWDG_GetFlagStatus
*
* @brief Checks whether the Early Wakeup interrupt flag is set or not
*
* @return The new state of the Early Wakeup interrupt flag (SET or RESET)
*/
FlagStatus WWDG_GetFlagStatus( void )
{
return ( FlagStatus )( WWDG->STATR );
}
/*********************************************************************
* @fn WWDG_ClearFlag
*
* @brief Clears Early Wakeup interrupt flag
*
* @return none
*/
void WWDG_ClearFlag( void )
{
WWDG->STATR = ( uint32_t )RESET;
}