mirror of
https://github.com/WeActStudio/WeActStudio.EpaperModule.git
synced 2026-08-16 13:13:45 +02:00
first commit
This commit is contained in:
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;
|
||||
}
|
||||
Reference in New Issue
Block a user