A36 PCB1.1 软件工程整理

This commit is contained in:
2024-04-17 19:45:26 +08:00
commit 3401b91efc
3896 changed files with 4032291 additions and 0 deletions

View File

@ -0,0 +1,252 @@
/*
******************************************************************************
* @file driver_adc.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief Header file of ADC HAL module.
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_ADC_H__
#define __DRIVER_ADC_H__
#include "fr30xx.h"
/** @addtogroup ADC_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
#define ADC_MAX_CHANNELS (8)
#define ADC_MAX_IO_INPUT_MAP (4)
/* Control Register for ADC */
typedef struct
{
uint32_t ADC_ConvertEN : 1;
uint32_t ADC_Reset : 1;
uint32_t rsv_0 : 1;
uint32_t ADC_SoftTrigger : 1;
uint32_t rsv_1 : 28;
}REG_ADC_Control_t;
/* Config Register for ADC */
typedef struct
{
uint32_t ADC_ChannelMax : 4;
uint32_t ADC_ConvertMode : 1;
uint32_t ADC_TriggerMode : 1;
uint32_t ADC_FIFO_EN : 1;
uint32_t rsv_0 : 1;
uint32_t ADC_SoftTriggerChannel : 4;
uint32_t rsv_1 : 20;
}REG_ADC_Config_t;
/* Timing Register for ADC */
typedef struct
{
uint32_t Clock_DIV : 8;
uint32_t rsv_0 : 8;
uint32_t SetupCycle : 6;
uint32_t SampleCycle : 5;
uint32_t TimeoutCycle : 5;
}REG_ADC_Timing_t;
/* ----------------------------------------------*/
/* ADC Registers */
/* ----------------------------------------------*/
typedef struct
{
volatile REG_ADC_Control_t Control; /* Offset 0x00 */
volatile REG_ADC_Config_t Config; /* Offset 0x04 */
volatile REG_ADC_Timing_t Timing; /* Offset 0x08 */
volatile uint32_t rsv_0; /* Offset 0x0C */
volatile uint32_t rsv_1; /* Offset 0x10 */
volatile uint32_t rsv_2; /* Offset 0x14 */
volatile uint32_t Channel_Status; /* Offset 0x18 */
volatile uint32_t rsv_3; /* Offset 0x1C */
volatile uint32_t ADC_INT_Enble; /* Offset 0x20 */
volatile uint32_t ADC_INT_Status; /* Offset 0x24 */
volatile uint32_t ADC_INT_Raws; /* Offset 0x28 */
volatile uint32_t ACT0; /* Offset 0x2C */
volatile uint32_t ACT1; /* Offset 0x30 */
volatile uint32_t ChannelMap[8]; /* Offset 0x34 ~ 0x50 */
volatile uint32_t rsv0[8];
volatile uint32_t ChannelData[8]; /* Offset 0x74 ~ 0x90 */
}struct_ADC_t;
#define ADC ((struct_ADC_t *)ADC_BASE)
/* ################################ Register Section END ################################ */
/**
* @}
*/
/** @addtogroup ADC_Initialization_Config_Section
* @{
*/
/* ################################ Initialization, Config Section Start ################################ */
#define ADC_INT_CONVERT_ERR (0x10)
#define ADC_INT_CHANNEL_VALID (0x08)
#define ADC_ACT0_REF_1P2V (0x1A036)
#define ADC_ACT0_REF_IOLDO (0xDA036)
#define ADC_ACT1_VBE_EN (0x02)
#define ADC_ACT1_VBAT_EN (0x04)
#define ADC_ACT1_IS (0x40)
/* ADC interrupt index */
typedef enum
{
ADC_CHANNEL_MAP_PMU_P4, /* PMU P4 */
ADC_CHANNEL_MAP_PMU_P5, /* PMU P5 */
ADC_CHANNEL_MAP_PMU_P6, /* PMU P6 */
ADC_CHANNEL_MAP_PMU_P7, /* PMU P7 */
ADC_CHANNEL_MAP_VBE, /* VBE */
ADC_CHANNEL_MAP_VBAT, /* 1/4 VBAT */
}enum_ADC_Channel_Map_t;
/* ADC interrupt index */
typedef enum
{
ADC_FIFO_EMPTY = 0x01,
ADC_FIFO_FULL = 0x02,
ADC_FIFO_ALMOST_FULL = 0x04,
ADC_CHANNEL_VALID = 0x08,
ADC_ERR = 0x10,
}enum_ADC_int_index_t;
/* ADC convert mode */
typedef enum
{
ADC_SINGLE_MODE,
ADC_LOOP_MODE,
}enum_ADC_convert_mode_t;
/* ADC FIFO mode */
typedef enum
{
ADC_FIFO_DISABLE,
ADC_FIFO_ENABLE,
}enum_ADC_FIFO_EN_t;
/* ADC convert mode */
typedef enum
{
ADC_HARDWARE_TRIGGER,
ADC_SOFTWARE_TRIGGER,
}enum_ADC_trigger_mode_t;
typedef enum
{
ADC_REF_IOLDO,
ADC_REF_1P2V,
}enum_ADC_reference_t;
/**
* @brief hard trigger config definition
*/
typedef struct
{
uint32_t ADC_Convert_Mode; /*!< Specifies the convert mode, single or loop.
This parameter can be a value @ref enum_ADC_convert_mode_t */
uint32_t ADC_Channel_Max; /*!< Specifies the number of Maximum conversion channels.
This parameter can be a value between 1 ~ 8 */
}struct_HardTriggerConfig_t;
/**
* @brief ADC Initialization Structure definition
*/
typedef struct
{
uint32_t ADC_Reference; /*!< Specifies the reference source of ADC.
This parameter can be a value @ref enum_ADC_reference_t */
uint32_t ADC_TriggerMode; /*!< Specifies the number of ADC Trigger Mode.
This parameter can be a value @ref enum_ADC_trigger_mode_t */
struct_HardTriggerConfig_t HardTriggerConfig; /*!< ADC hard trigger config parameters */
}adc_InitConfig_t;
/* ################################ Initialization, Config Section END ################################ */
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
/* ADC hard Convert Enable/Disable */
#define __ADC_CONVERT_ENABLE() (ADC->Control.ADC_ConvertEN = 1)
#define __ADC_CONVERT_DISABLE() (ADC->Control.ADC_ConvertEN = 0)
/* ADC State machine Reset */
#define __ADC_RESET() (ADC->Control.ADC_Reset = 1)
/* soft trigger convert */
#define __ADC_SOFT_TRIGGER() (ADC->Control.ADC_SoftTrigger = 1)
/* set soft trigger channel */
#define __ADC_SET_SOFT_TRIGGER_CHANNEL(__CHANNEL__) (ADC->Config.ADC_SoftTriggerChannel = __CHANNEL__)
/* Set max channel */
#define __ADC_SET_MAX_CHANNEL(__MAXCH__) (ADC->Config.ADC_ChannelMax = __MAXCH__)
/* Set convert mode */
#define __ADC_SET_CONVERT_MODE(__MODE__) (ADC->Config.ADC_ConvertMode = __MODE__)
/* Set trigger mode */
#define __ADC_SET_TRIGGER_MODE(__MODE__) (ADC->Config.ADC_TriggerMode = __MODE__)
/* set adc clock div */
#define __ADC_SET_CLK_DIV(__DIV__) (ADC->Timing.Clock_DIV = __DIV__)
/* set convert setup/sample/timout cycle */
#define __ADC_SET_SETUP_CYCLE(__CYCLE__) (ADC->Timing.SetupCycle = __CYCLE__)
#define __ADC_SET_SAMPLE_CYCLE(__CYCLE__) (ADC->Timing.SampleCycle = __CYCLE__)
#define __ADC_SET_TIMEOUT_CYCLE(__CYCLE__) (ADC->Timing.TimeoutCycle = __CYCLE__)
/* Get ADC Channel status */
#define __ADC_GET_CHANNEL_STATUS() (ADC->Channel_Status)
/* ADC interrupt enable/disable */
#define __ADC_INT_ENABLE(__INDEX__) (ADC->ADC_INT_Enble |= __INDEX__)
#define __ADC_INT_DISABLE(__INDEX__) (ADC->ADC_INT_Enble &= ~(__INDEX__))
#define __ADC_GET_INT_STATUS() (ADC->ADC_INT_Raws)
/* Set channel map */
#define __ADC_SET_CHANNEL_MAP(__CHANNEL__, __MAP__) (ADC->ChannelMap[__CHANNEL__] = __MAP__)
/* Get channel data */
#define __ADC_GET_CHANNEL_DATA(__CHANNEL__) (ADC->ChannelData[__CHANNEL__])
/* Exported functions --------------------------------------------------------*/
/* adc_init */
void adc_init(adc_InitConfig_t InitConfig);
/* adc_convert_start/stop */
void adc_convert_start(void);
void adc_convert_start_IT(void);
void adc_convert_stop(void);
void adc_channel_valid_int_enable(void);
void adc_channel_valid_int_dsiable(void);
/* adc_soft_trigger_convert */
void adc_soft_trigger_convert(uint8_t fu8_Channel);
/* adc_get_channel_valid_status */
bool adc_get_channel_valid_status(uint8_t fu8_Channel);
/* adc_get_channel_data */
uint32_t adc_get_channel_data(uint8_t fu8_Channel);
/* adc_set_channel_maping */
void adc_set_channel_maping(uint8_t fu8_Channel, enum_ADC_Channel_Map_t fe_Map);
#endif

View File

@ -0,0 +1,148 @@
/*
******************************************************************************
* @file driver_aes.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2022
* @brief Header file of aes module.
******************************************************************************
* @attention
*
* Copyright (c) 2022 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_AES_H__
#define __DRIVER_AES_H__
#include "fr30xx.h"
/** @addtogroup AES_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
/*AES CTRL REG 0x40*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t START : 1;//AES work enable,this bit only maintain active for one cycle and is cleared automatically
uint32_t KEY_INT_EN : 1;//whehter key expand finish interrupt enable
uint32_t DATA_INT_EN : 1;//whether encrypt or decrypt finish interrupt enable
uint32_t CBC : 1;//CBC mode or ECB mode
uint32_t KEY_LEN : 2;//00->128bit 01->192bit 10->256bit 11->reserved
uint32_t OPCODE : 2;//00->encrypt 01->decrypt 10->keyexpand 11->reserved
uint32_t ENDIAN_SEL : 1;//0->small endian for data register 1->big endian for data register
uint32_t RSV : 23;
} Bits;
} REG_AES_CTRL_t;
/*AES STATE REG 0x44*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t BUSY : 1;//busy indication bit
uint32_t KEY_INT_FLAG : 1;//key expand finish interrupt flag
uint32_t DATA_INT_FLAG : 1;//data finish interrupt flag
uint32_t RSV : 29;
} Bits;
} REG_AES_STATE_t;
/* ------------------------------------------------*/
/* AES Register */
/* ------------------------------------------------*/
typedef struct
{
volatile uint32_t DATAIN_0; /* Offset 0x00 */
volatile uint32_t DATAIN_1; /* Offset 0x04 */
volatile uint32_t DATAIN_2; /* Offset 0x08 */
volatile uint32_t DATAIN_3; /* Offset 0x0C */
volatile uint32_t KEY_0; /* Offset 0x10 */
volatile uint32_t KEY_1; /* Offset 0x14 */
volatile uint32_t KEY_2; /* Offser 0x18 */
volatile uint32_t KEY_3; /* Offser 0x1c */
volatile uint32_t KEY_4; /* Offser 0x20 */
volatile uint32_t KEY_5; /* Offser 0x24 */
volatile uint32_t KEY_6; /* Offser 0x28 */
volatile uint32_t KEY_7; /* Offset 0x2C */
volatile uint32_t IV_0; /* Offset 0x30 */
volatile uint32_t IV_1; /* Offset 0x34 */
volatile uint32_t IV_2; /* Offset 0x38 */
volatile uint32_t IV_3; /* Offset 0x3C */
volatile REG_AES_CTRL_t AES_CTRL; /* Offset 0x40 */
volatile REG_AES_STATE_t AES_STATE; /* Offset 0x44 */
volatile uint32_t DATAOUT_0; /* Offset 0x48 */
volatile uint32_t DATAOUT_1; /* Offset 0x4C */
volatile uint32_t DATAOUT_2; /* Offset 0x50 */
volatile uint32_t DATAOUT_3; /* Offset 0x54 */
}struct_SEC_AES_t;
#define SEC_AES ((struct_SEC_AES_t *)(SEC_BASE))
/* ################################ Register Section END ################################## */
/**
* @}
*/
/** @addtogroup AES_Initialization_Config_Section
* @{
*/
/* ################################ Initialization Config Section Start ################################ */
#define AES_OPCODE_ENCRYPT (0)
#define AES_OPCODE_DECRYPT (1)
#define AES_OPCODE_KEY_EXPAND (2)
#define AES_CBC_MODE_DISABLE (0)
#define AES_CBC_MODE_ENABLE (1)
typedef enum
{
AES_ECB_128,
AES_ECB_192,
AES_ECB_256,
AES_CBC_128,
AES_CBC_192,
AES_CBC_256,
}enum_AES_MODE_t;
typedef enum
{
AES_SMALL_ENDIAN, /* small endian for data register */
AES_BIG_ENDIAN, /* big endian for data register */
}enum_ENDIAN_t;
/* ################################ Initialization Config Section END ################################## */
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
/* get aes status */
#define __AES_IS_BUSY() (SEC_AES->AES_STATE.Bits.BUSY)
/* set aes opcode */
#define __AES_SET_OPCODE(__OPCODE__) (SEC_AES->AES_CTRL.Bits.OPCODE = __OPCODE__)
/* aes work start */
#define __AES_WORK_START() (SEC_AES->AES_CTRL.Bits.START = 1)
/* Exported functions --------------------------------------------------------*/
/* AES config */
void aes_config(enum_AES_MODE_t fe_Mode, enum_ENDIAN_t fe_Endian);
/* AES set key/iv */
void aes_set_encrypt_key(uint8_t *key);
void aes_set_encrypt_iv(uint8_t *iv);
/* AES encrypt/decrypt */
void aes_encrypt(uint8_t *fp_Data_In, uint32_t fu32_Size, uint8_t *fp_Data_Out);
void aes_decrypt(uint8_t *fp_Data_In, uint32_t fu32_Size, uint8_t *fp_Data_Out);
#endif

View File

@ -0,0 +1,466 @@
/*
******************************************************************************
* @file driver_blend.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2022
* @brief Header file of BLEND module.
******************************************************************************
* @attention
*
* Copyright (c) 2022 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_BLEND_H__
#define __DRIVER_BLEND_H__
#include "fr30xx.h"
/** @addtogroup BLEND_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
/*BLEND CTRL REG 0x00*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t BLEND_EN : 1;
uint32_t RGB0_FF_RST : 1;
uint32_t RGB1_FF_RST : 1;
uint32_t MASK_FF_RST : 1;
uint32_t ORGB_FF_RST : 1;
uint32_t RSV : 27;
} Bits;
} REG_BLEND_CTRL_t;
/*BLEND CONFIG REG 0x04*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t BLEND_MODE : 2;
uint32_t RGB0_FORMAT : 2;
uint32_t RGB1_FORMAT : 2;
uint32_t ORGB_FORMAT : 2;
uint32_t ORGB_MODE : 1;
uint32_t RGB0_CAL_EN : 1;
uint32_t RGB1_CAL_EN : 1;
uint32_t MASK_CAL_EN : 1;
uint32_t R_MUL_TC_EN : 1;
uint32_t G_MUL_TC_EN : 1;
uint32_t B_MUL_TC_EN : 1;
uint32_t A_MUL_TC_EN : 1;
uint32_t ORGB_565_R_TC_EN : 1;
uint32_t ORGB_565_G_TC_EN : 1;
uint32_t ORGB_565_B_TC_EN : 1;
uint32_t ORGB_332_R_TC_EN : 1;
uint32_t ORGB_332_G_TC_EN : 1;
uint32_t ORGB_332_B_TC_EN : 1;
uint32_t RSV : 10;
} Bits;
} REG_BLEND_CFG_t;
/*BLEND PIXEL REG 0x08*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t PIXEL_ALPHA : 8;
uint32_t PIXEL_DATA : 24;
} Bits;
} REG_BLEND_PIXEL_t;
/*BLEND SRC ALPHA REG 0x0C*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t SRC_ALPHA : 8;
uint32_t RSV : 24;
} Bits;
} REG_BLEND_SRC_ALPHA_t;
/*BLEND DMAC REG 0x10*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t RGB0_DMA_EN : 1;
uint32_t RGB1_DMA_EN : 1;
uint32_t MASK_DMA_EN : 1;
uint32_t ORGB_DMA_EN : 1;
uint32_t RSV : 28;
} Bits;
} REG_BLEND_DMAC_t;
/*BLEND INFIFO0 THRESHOLD CONTROL REG 0x14*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t RGB0_ALEMPTY_THR : 5;
uint32_t RSV : 3;
uint32_t RGB0_ALFULL_THR : 5;
uint32_t RSV2 : 3;
uint32_t RGB0_DMA_THR : 5;
uint32_t RSV3 : 11;
} Bits;
} REG_BLEND_INFIFO0_THR_CTL_t;
/*BLEND INFIFO1 THRESHOLD CONTROL REG 0x18*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t RGB1_ALEMPTY_THR : 5;
uint32_t RSV : 3;
uint32_t RGB1_ALFULL_THR : 5;
uint32_t RSV2 : 3;
uint32_t RGB1_DMA_THR : 5;
uint32_t RSV3 : 11;
} Bits;
} REG_BLEND_INFIFO1_THR_CTL_t;
/*BLEND INFIFOMASK THRESHOLD CONTROL REG 0x1C*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t MASK_ALEMPTY_THR : 5;
uint32_t RSV : 3;
uint32_t MASK_ALFULL_THR : 5;
uint32_t RSV2 : 3;
uint32_t MASK_DMA_THR : 5;
uint32_t RSV3 : 11;
} Bits;
} REG_BLEND_INFIFOMASK_THR_CTL_t;
/*BLEND OUTFIFO THRESHOLD CONTROL REG 0x20*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t ORGB_ALEMPTY_THR : 5;
uint32_t RSV1 : 3;
uint32_t ORGB_ALFULL_THR : 5;
uint32_t RSV2 : 3;
uint32_t ORGB_DMA_THR : 5;
uint32_t RSV3 : 3;
uint32_t ORGB_FLOW_THR : 5;
uint32_t RSV4 : 3;
} Bits;
} REG_BLEND_OUTFIFO_THR_CTL_t;
/*BLEND INTERRUPT CONTROL REG 0x24*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t RGB0_EMPTY_INT_EN : 1;
uint32_t RGB0_ALEMPTY_INT_EN : 1;
uint32_t RGB0_FULL_INT_EN : 1;
uint32_t RGB0_ALFULL_INT_EN : 1;
uint32_t RSV1 : 4;
uint32_t RGB1_EMPTY_INT_EN : 1;
uint32_t RGB1_ALEMPTY_INT_EN : 1;
uint32_t RGB1_FULL_INT_EN : 1;
uint32_t RGB1_ALFULL_INT_EN : 1;
uint32_t RSV2 : 4;
uint32_t MASK_EMPTY_INT_EN : 1;
uint32_t MASK_ALEMPTY_INT_EN : 1;
uint32_t MASK_FULL_INT_EN : 1;
uint32_t MASK_ALFULL_INT_EN : 1;
uint32_t RSV3 : 4;
uint32_t ORGB_EMPTY_INT_EN : 1;
uint32_t ORGB_ALEMPTY_INT_EN : 1;
uint32_t ORGB_FULL_INT_EN : 1;
uint32_t ORGB_ALFULL_INT_EN : 1;
uint32_t RSV4 : 4;
} Bits;
} REG_BLEND_ISR_CTL_t;
/*BLEND INTERRUPT STATUS REG 0x28*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t RGB0_EMPTY_INT_STS : 1;
uint32_t RGB0_ALEMPTY_INT_STS : 1;
uint32_t RGB0_FULL_INT_STS : 1;
uint32_t RGB0_ALFULL_INT_STS : 1;
uint32_t RSV1 : 4;
uint32_t RGB1_EMPTY_INT_STS : 1;
uint32_t RGB1_ALEMPTY_INT_STS : 1;
uint32_t RGB1_FULL_INT_STS : 1;
uint32_t RGB1_ALFULL_INT_STS : 1;
uint32_t RSV2 : 4;
uint32_t MASK_EMPTY_INT_STS : 1;
uint32_t MASK_ALEMPTY_INT_STS : 1;
uint32_t MASK_FULL_INT_STS : 1;
uint32_t MASK_ALFULL_INT_STS : 1;
uint32_t RSV3 : 4;
uint32_t ORGB_EMPTY_INT_STS : 1;
uint32_t ORGB_ALEMPTY_INT_STS : 1;
uint32_t ORGB_FULL_INT_STS : 1;
uint32_t ORGB_ALFULL_INT_STS : 1;
uint32_t RSV4 : 4;
} Bits;
} REG_BLEND_ISR_STATUS_t;
/*BLEND FIFO STATUS REG 0x2c*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t RGB0_EMPTY : 1;
uint32_t RGB0_ALEMPTY : 1;
uint32_t RGB0_FULL : 1;
uint32_t RGB0_ALFULL : 1;
uint32_t RSV1 : 4;
uint32_t RGB1_EMPTY : 1;
uint32_t RGB1_ALEMPTY : 1;
uint32_t RGB1_FULL : 1;
uint32_t RGB1_ALFULL : 1;
uint32_t RSV2 : 4;
uint32_t MASK_EMPTY : 1;
uint32_t MASK_ALEMPTY : 1;
uint32_t MASK_FULL : 1;
uint32_t MASK_ALFULL : 1;
uint32_t RSV3 : 4;
uint32_t ORGB_EMPTY : 1;
uint32_t ORGB_ALEMPTY : 1;
uint32_t ORGB_FULL : 1;
uint32_t ORGB_ALFULL : 1;
uint32_t RSV4 : 4;
} Bits;
} REG_BLEND_FIFO_STATUS_t;
/*BLEND FIFO COUNT REG 0x38*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t RGB0_FF_COUNT : 6;
uint32_t RSV1 : 2;
uint32_t RGB1_FF_COUNT : 6;
uint32_t RSV2 : 2;
uint32_t MASK_FF_COUNT : 6;
uint32_t RSV3 : 2;
uint32_t ORGB_FF_COUNT : 6;
uint32_t RSV : 2;
} Bits;
} REG_BLEND_FIFO_COUNT_t;
/*BLEND PIXEL_THR REG 0x3C*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t O565_B_THR : 3;
uint32_t O565_G_THR : 2;
uint32_t O565_R_THR : 3;
uint32_t RSV2 : 8;
uint32_t O332_B_THR : 6;
uint32_t O332_G_THR : 5;
uint32_t O332_R_THR : 5;
} Bits;
} REG_BLEND_PIXEL_THR_t;
typedef struct
{
REG_BLEND_CTRL_t CTRL; /* Offset 0x00 */
REG_BLEND_CFG_t CONFIG; /* Offset 0x04 */
REG_BLEND_PIXEL_t PIXEL; /* Offset 0x08*/
REG_BLEND_SRC_ALPHA_t SRC_ALPHA; /* Offset 0x0c */
REG_BLEND_DMAC_t DMAC; /* Offset 0x10 */
REG_BLEND_INFIFO0_THR_CTL_t INFIFO0_THR_CTL; /* Offset 0x14 */
REG_BLEND_INFIFO1_THR_CTL_t INFIFO1_THR_CTL; /* Offset 0x18 */
REG_BLEND_INFIFOMASK_THR_CTL_t INFIFOMASK_THR_CTL; /* Offset 0x1C */
REG_BLEND_OUTFIFO_THR_CTL_t OUTFIFO_THR_CTL; /* Offset 0x20 */
REG_BLEND_ISR_CTL_t ISR_CTL; /* Offset 0x24 */
REG_BLEND_ISR_STATUS_t ISR_STATUS; /* Offset 0x28 */
REG_BLEND_FIFO_STATUS_t FIFO_STATUS; /* Offset 0x2C */
uint32_t RGB0_DATA; /* Offset 0x30 */
uint32_t RGB1_DATA; /* Offset 0x34 */
REG_BLEND_FIFO_COUNT_t FIFO_COUNT; /* Offset 0x38 */
REG_BLEND_PIXEL_THR_t PIXEL_THR; /* Offset 0x3c */
}struct_BLEND_t;
typedef struct
{
uint32_t MASK_DATA;/* Offset 0x00 */
uint32_t ORGB_DATA;/* Offset 0x04 */
}struct_BLEND_AHB1_t;
#define BLEND_AHB0 ((volatile struct_BLEND_t *)BLEND_AHB0_BASE)
#define BLEND_AHB1 ((volatile struct_BLEND_AHB1_t *)BLEND_AHB1_BASE)
#define BLEND_RGB0_EMPTY_INT_STS (1<<0)
#define BLEND_RGB0_ALEMPTY_INT_STS (1<<1)
#define BLEND_RGB1_EMPTY_INT_STS (1<<8)
#define BLEND_RGB1_ALEMPTY_INT_STS (1<<9)
#define BLEND_MASK_EMPTY_INT_STS (1<<16)
#define BLEND_MASK_ALEMPTY_INT_STS (1<<17)
#define BLEND_ORGB_FULL_INT_STS (1<<26)
#define BLEND_ORGB_ALFULL_INT_STS (1<<27)
typedef enum{
BLEND_RGB_TYPE_888 = 0,
BLEND_RGB_TYPE_565 = 1,
}enum_RGB_TYPE_t;
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t INRGB0_FORMAT : 2;
uint32_t INRGB1_FORMAT : 2;
uint32_t OUTRGB_FORMAT : 2;
uint32_t SRC_IS_PURE : 1;
uint32_t SRC_ALPHA : 8;
uint32_t BLEND_MODE : 2;
uint32_t DMA_IN_EN : 1;
uint32_t DMA_OUT_EN : 1;
uint32_t ISR_EN : 1;
uint32_t MASK_CAL_EN : 1;
uint32_t RSV : 11;
} Bits;
}struct_init_t;
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t ALEMPTY_THR : 6;
uint32_t DMA_THR : 6;
uint32_t RSV : 20;
} Bits;
}struct_INFIFO_THR_t;
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t ALFULL_THR : 6;
uint32_t DMA_THR : 6;
uint32_t RSV : 20;
} Bits;
}struct_OUTFIFO_THR_t;
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t PIXEL : 24;
uint32_t RSV : 8;
} Bits;
}struct_PURE_t;
typedef struct __BLEND_HandleTypeDef
{
struct_init_t BlendInit;
struct_PURE_t Pure;
struct_INFIFO_THR_t Infifo0Thr;
struct_INFIFO_THR_t Infifo1Thr;
struct_INFIFO_THR_t InfifoMaskThr;
struct_OUTFIFO_THR_t OutfifoThr;
uint32_t *SrcRgb; /*!< BLEND parameters in interrupt */
uint32_t SrcSize;
uint32_t *BackRgb;
uint32_t BackSize;
uint32_t *MaskRgb;
uint32_t MaskSize;
uint32_t *OutRgb;
uint32_t OutSize;
uint8_t gMaskRem;
uint32_t PixelCount;
uint32_t SrcInIndex; /*!< BLEND RGB data index in handle */
uint32_t BackInIndex;
uint32_t MaskInIndex;
uint32_t DataOutIndex;
void (*Callback)(struct __BLEND_HandleTypeDef *hblend); /*!< BLEND RGB out finish Callback */
}BLEND_HandleTypeDef;
typedef struct{
uint8_t *SrcRgb;
uint8_t *BackRgb;
uint8_t *MaskRgb;
uint8_t *OutRgb;
uint32_t PixelCount;
}BLEND_DataParam_t;
#define __BLEND_INT_RGB0_FIFO_EMPTY_ENABLE() (BLEND_AHB0->ISR_CTL.Bits.RGB0_EMPTY_INT_EN = 1)
#define __BLEND_INT_RGB1_FIFO_EMPTY_ENABLE() (BLEND_AHB0->ISR_CTL.Bits.RGB1_EMPTY_INT_EN = 1)
#define __BLEND_INT_MASK_FIFO_EMPTY_ENABLE() (BLEND_AHB0->ISR_CTL.Bits.MASK_EMPTY_INT_EN = 1)
#define __BLEND_INT_ORGB_FIFO_ALFULL_ENABLE() (BLEND_AHB0->ISR_CTL.Bits.ORGB_ALFULL_INT_EN = 1)
#define __BLEND_INT_RGB0_FIFO_EMPTY_DISABLE() (BLEND_AHB0->ISR_CTL.Bits.RGB0_EMPTY_INT_EN = 0)
#define __BLEND_INT_RGB1_FIFO_EMPTY_DISABLE() (BLEND_AHB0->ISR_CTL.Bits.RGB1_EMPTY_INT_EN = 0)
#define __BLEND_INT_MASK_FIFO_EMPTY_DISABLE() (BLEND_AHB0->ISR_CTL.Bits.MASK_EMPTY_INT_EN = 0)
#define __BLEND_INT_ORGB_FIFO_ALFULL_DISABLE() (BLEND_AHB0->ISR_CTL.Bits.ORGB_ALFULL_INT_EN = 0)
#define __RGB0_FIFO_IS_EMPTY() (BLEND_AHB0->FIFO_STATUS.Bits.RGB0_EMPTY == 1)
#define __RGB0_FIFO_IS_ALEMPTY() (BLEND_AHB0->FIFO_STATUS.Bits.RGB0_ALEMPTY == 1)
#define __RGB0_FIFO_IS_FULL() (BLEND_AHB0->FIFO_STATUS.Bits.RGB0_FULL == 1)
#define __RGB0_FIFO_IS_ALFULL() (BLEND_AHB0->FIFO_STATUS.Bits.RGB0_ALFULL == 1)
#define __RGB1_FIFO_IS_EMPTY() (BLEND_AHB0->FIFO_STATUS.Bits.RGB1_EMPTY == 1)
#define __RGB1_FIFO_IS_ALEMPTY() (BLEND_AHB0->FIFO_STATUS.Bits.RGB1_ALEMPTY == 1)/*set almost empty to do*/
#define __RGB1_FIFO_IS_FULL() (BLEND_AHB0->FIFO_STATUS.Bits.RGB1_FULL == 1)
#define __RGB1_FIFO_IS_ALFULL() (BLEND_AHB0->FIFO_STATUS.Bits.RGB1_ALFULL == 1)
#define __MASK_FIFO_IS_EMPTY() (BLEND_AHB0->FIFO_STATUS.Bits.MASK_EMPTY == 1)
#define __MASK_FIFO_IS_ALEMPTY() (BLEND_AHB0->FIFO_STATUS.Bits.MASK_ALEMPTY == 1)
#define __MASK_FIFO_IS_FULL() (BLEND_AHB0->FIFO_STATUS.Bits.MASK_FULL == 1)
#define __MASK_FIFO_IS_ALFULL() (BLEND_AHB0->FIFO_STATUS.Bits.MASK_ALFULL == 1)
#define __ORGB_FIFO_IS_FULL() (BLEND_AHB0->FIFO_STATUS.Bits.ORGB_FULL == 1)
#define __ORGB_FIFO_IS_ALFULL() (BLEND_AHB0->FIFO_STATUS.Bits.ORGB_ALFULL == 1)
#define __ORGB_FIFO_IS_EMPTY() (BLEND_AHB0->FIFO_STATUS.Bits.ORGB_EMPTY == 1)
#define __ORGB_FIFO_IS_ALEMPTY() (BLEND_AHB0->FIFO_STATUS.Bits.ORGB_ALEMPTY == 1)
#define __ORGB_FIFO_IS_HALF_FULL() (BLEND_AHB0->FIFO_STATUS.Bits.ORGB_HALF_FULL == 1)
/* Initialize the blend module */
void blend_init(BLEND_HandleTypeDef *hblend);
/* Start blend to mix pixel without isr */
void blend_start(BLEND_HandleTypeDef *hblend, BLEND_DataParam_t DataParam);
/* Start blend to mix pixel with isr */
void blend_start_IT(BLEND_HandleTypeDef *hblend, BLEND_DataParam_t DataParam);
/* Blend module handle function in the blend isr */
void blend_IRQHandler(BLEND_HandleTypeDef *hblend);
#endif

View File

@ -0,0 +1,154 @@
/*
******************************************************************************
* @file driver_cache.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2022
* @brief Header file of cache HAL module.
******************************************************************************
* @attention
*
* Copyright (c) 2022 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_CACHE_H__
#define __DRIVER_CACHE_H__
#include "fr30xx.h"
/** @addtogroup CACHE_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
/* Enabling Register 0 */
typedef struct
{
uint32_t ENABLE : 1;
uint32_t FLUSH : 1;
uint32_t BANK_FLUSH : 1;
uint32_t rsv : 29;
} REG_Enabling_t;
/* Control Register */
typedef struct
{
uint32_t BIST_ACTIVE : 1;
uint32_t BIST_END : 1;
uint32_t BIST_OUT : 1;
uint32_t WR_MODE : 2;
uint32_t INST_POL : 1;
uint32_t INST_ACTIVE : 1;
uint32_t ADDR_RANG0_EN : 1;
uint32_t ADDR_RANG0_POL : 1;
uint32_t ADDR_RANG1_EN : 1;
uint32_t ADDR_RANG1_POL : 1;
uint32_t ADDR_RANG2_EN : 1;
uint32_t ADDR_RANG2_POL : 1;
uint32_t ADDR_RANG3_EN : 1;
uint32_t ADDR_RANG3_POL : 1;
uint32_t rsv : 17;
} REG_Cache_Control_t;
/* Address Range 0 defination*/
typedef struct {
uint32_t bank :16;
uint32_t mask :16;
} REG_ADDR_RANGE0_t;
/* Address Range 1 defination*/
typedef struct {
uint32_t rsv_0 :8;
uint32_t bank :8;
uint32_t rsv_1 :8;
uint32_t mask :8;
} REG_ADDR_RANGE1_t;
/* Address Range 2 defination*/
typedef struct {
uint32_t rsv_0 :8;
uint32_t bank :8;
uint32_t rsv_1 :8;
uint32_t mask :8;
} REG_ADDR_RANGE2_t;
/* Address Range 3 defination*/
typedef struct {
uint32_t rsv_0 :8;
uint32_t bank :8;
uint32_t rsv_1 :8;
uint32_t mask :8;
} REG_ADDR_RANGE3_t;
/* -----------------------------------------------*/
/* CACHE Register */
/* -----------------------------------------------*/
typedef struct
{
volatile REG_Enabling_t ENABLING; /* Offset 0x00 */
volatile REG_Cache_Control_t CTRL; /* Offset 0x04 */
volatile uint32_t BANK_FLUSH_ADDR; /* Offset 0x08 */
volatile uint32_t BANK_FLUSH_MASK; /* Offset 0x0C */
volatile REG_ADDR_RANGE0_t ADDR_RANGE0; /* Offset 0x10 */
volatile REG_ADDR_RANGE1_t ADDR_RANGE1; /* Offset 0x14 */
volatile REG_ADDR_RANGE2_t ADDR_RANGE2; /* Offset 0x18 */
volatile REG_ADDR_RANGE3_t ADDR_RANGE3; /* Offset 0x1C */
}struct_CACHE_t;
#define CACHE ((struct_CACHE_t *)AHBC_CACHE_BASE)
/* ################################ Register Section END ################################## */
/**
* @}
*/
/** @addtogroup SPI_Initialization_Config_Section
* @{
*/
/* ################################ Initializatio Config Section Start ################################ */
typedef enum {
CACHE_WR_BYPASS,
CACHE_WR_FLUSH,
CACHE_WR_WRITE_THROUGH,
} enum_CACHE_WR_MODE_T;
typedef enum {
CACHE_POL_NON_CACHABLE,
CACHE_POL_CACHABLE,
} enum_CACHE_POL_T;
/* ################################ Initializatio Config Section END ################################## */
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
#define __CACHE_ENABLE(__CACHE__) (__CACHE__->ENABLING.ENABLE = 1)
#define __CACHE_DISABLE(__CACHE__) (__CACHE__->ENABLING.ENABLE = 0)
#define __CACHE_FLUSH(__CACHE__) (__CACHE__->ENABLING.FLUSH = 1)
#define __CACHE_BANK_FLUSH(__CACHE__) (__CACHE__->ENABLING.BANK_FLUSH = 1)
#define __CACHE_BANK_FLUSH_DONE(__CACHE__) (__CACHE__->ENABLING.BANK_FLUSH == 0)
#define __CACHE_BANK_FLUSH_ADDR_SET(__CACHE__, addr) (__CACHE__->BANK_FLUSH_ADDR = addr)
#define __CACHE_BANK_FLUSH_MASK_SET(__CACHE__, mask) (__CACHE__->BANK_FLUSH_MASK = mask)
#define __CACHE_BIST_START(__CACHE__) (__CACHE__->CTRL.BIST_ACTIVE = 1)
#define __CACHE_BIST_END(__CACHE__) (__CACHE__->CTRL.BIST_END == 1)
#define __CACHE_BIST_PASS(__CACHE__) (__CACHE__->CTRL.BIST_OUT == 0)
#define __CACHE_WR_MODE_SET(__CACHE__, mode) (__CACHE__->CTRL.WR_MODE = mode)
#define __CACHE_WR_MODE_GET(__CACHE__, mode) (__CACHE__->CTRL.WR_MODE)
#define __CACHE_ADDR_RANGEx_ENABLE(__CACHE__, x) (__CACHE__->CTRL.ADDR_RANG##x##_EN = 1)
#define __CACHE_ADDR_RANGEx_DISABLE(__CACHE__, x) (__CACHE__->CTRL.ADDR_RANG##x##_EN = 0)
#define __CACHE_ADDR_RANGEx_POL_SET(__CACHE__, x, __pol) (__CACHE__->CTRL.ADDR_RANG##x##_POL = __pol)
#define __CACHE_ADDR_RANGEx_BANK_SET(__CACHE__, x, __bank) (__CACHE__->ADDR_RANGE##x.bank = (__bank))
#define __CACHE_ADDR_RANGEx_MASK_SET(__CACHE__, x, __mask) (__CACHE__->ADDR_RANGE##x.mask = (__mask))
#endif // __DRIVER_CACHE_H__

View File

@ -0,0 +1,127 @@
/*
******************************************************************************
* @file driver_cali.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2023
* @brief Header file of Calibration HAL module.
******************************************************************************
* @attention
*
* Copyright (c) 2023 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_CALI_H__
#define __DRIVER_CALI_H__
#include "fr30xx.h"
/** @addtogroup CALI_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
/* Control Register */
typedef struct
{
uint32_t EN : 1;
uint32_t UP_MODE : 1;
uint32_t rsv_0 : 30;
}REG_CALI_CTRL_t;
/* ------------------------------------------------*/
/* UART Register */
/* ------------------------------------------------*/
typedef struct
{
volatile REG_CALI_CTRL_t CTRL; /* Offset 0x00 */
volatile uint32_t DONE; /* Offset 0x04 */
volatile uint32_t INT_EN; /* Offset 0x08 */
volatile uint32_t INT_STA; /* Offset 0x0C */
volatile uint32_t LEN; /* Offset 0x10 */
volatile uint32_t RESULT; /* Offset 0x14 */
}struct_CALI_t;
#define CALI ((struct_CALI_t *)CALIB_BASE)
/* ################################ Register Section END ################################## */
/**
* @}
*/
/** @addtogroup CALI_Initialization_Config_Section
* @{
*/
/* ################################ Initialization Config Section Start ################################ */
/* FCR BIT position */
typedef enum
{
CALI_UP_MODE_KEEP = 0x00, /*!< return the oldest unread data */
CALI_UP_MODE_NORMAL = 0x01, /*!< return the latest calibration result */
}enum_CALI_UP_MODE_t;
/*
* @brief Calibration handle Structure definition
*/
typedef struct __Cali_HandleTypeDef
{
enum_CALI_UP_MODE_t mode; /*!< Calibration result fetch mode */
uint16_t rc_cnt; /*!< how many RC cycles used to calibrate */
void (*DoneCallback)(struct __Cali_HandleTypeDef *hcali, /*!< Calibration Done Callback */
uint32_t result);
}CALI_HandleTypeDef;
/* ################################ InitializationbConfig Section END ################################## */
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
/* __CALI_ENABLE */
/* __CALI_DISABLE */
#define __CALI_ENABLE() (CALI->CTRL.EN = 0x01)
#define __CALI_DISABLE() (CALI->CTRL.EN = 0x00)
/* __CALI_UP_MODE_SET */
#define __CALI_UP_MODE_SET(m) (CALI->CTRL.UP_MODE = m)
/* __CALI_INT_ENABLE */
/* __CALI_INT_DISABLE */
#define __CALI_INT_ENABLE() (CALI->INT_EN = 0x01)
#define __CALI_INT_DISABLE() (CALI->INT_EN = 0x00)
/* __CALI_INT_CLR */
#define __CALI_INT_CLR() (CALI->INT_STA = 0x01)
/* __CALI_IS_DONE */
#define __CALI_IS_DONE() (CALI->DONE == 0x01)
/* __CALI_CNT_SET */
#define __CALI_CNT_SET(v) (CALI->LEN = v)
/* __CALI_RESULT_GET */
#define __CALI_RESULT_GET() (CALI->RESULT)
/* Exported functions --------------------------------------------------------*/
/* cali_IRQHandler */
void cali_IRQHandler(CALI_HandleTypeDef *hcali);
/* cali_init */
void cali_init(CALI_HandleTypeDef *hcali);
/* cali_start */
uint32_t cali_start(CALI_HandleTypeDef *hcali);
/* cali_start_IT */
void cali_start_IT(CALI_HandleTypeDef *hcali);
/* cali_stop */
void cali_stop(CALI_HandleTypeDef *hcali);
/* cali_calc_rc_freq */
uint32_t cali_calc_rc_freq(CALI_HandleTypeDef *hcali, uint32_t result);
#endif // __DRIVER_CALI_H__

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,121 @@
/*
******************************************************************************
* @file driver_common.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2020
* @brief driver common header file.
******************************************************************************
* @attention
*
* Copyright (c) 2020 AisinoChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_COMMON_H__
#define __DRIVER_COMMON_H__
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
/* ================================================================================ */
/* ======================= Use Uart to Debug print ======================== */
/* ================================================================================ */
#define UART_DEBUG_ENABLE (1)
#if (UART_DEBUG_ENABLE == 1)
#define freq_printf printf
#else
#define freq_printf(format, ...) ((void)0)
#endif
#include "driver_aes.h"
#include "driver_blend.h"
#include "driver_cache.h"
#include "driver_cali.h"
#include "driver_can.h"
#include "driver_codec.h"
#include "driver_crc.h"
#include "driver_dma.h"
#include "driver_efuse.h"
#include "driver_flash.h"
#include "driver_frspim.h"
#include "driver_gpio.h"
#include "driver_i2s.h"
#include "driver_i2c.h"
#include "driver_ipc.h"
#include "driver_iir.h"
#include "driver_fft.h"
#include "driver_mp3_dec.h"
#include "driver_parallel_interface.h"
#include "driver_pdm.h"
#include "driver_pmu.h"
#include "driver_pmu_iwdt.h"
#include "driver_pmu_rtc.h"
#include "driver_pwm.h"
#include "driver_qspi.h"
#include "driver_adc.h"
#include "driver_sbc_enc.h"
#include "driver_sbc_dec.h"
#include "driver_sd.h"
#include "driver_sd_card.h"
#include "driver_sd_mmc.h"
#include "driver_sha.h"
#include "driver_spi.h"
#include "driver_spdif.h"
#include "driver_tick.h"
#include "driver_timer.h"
#include "driver_trigfunc.h"
#include "driver_trng.h"
#include "driver_uart.h"
#include "driver_yuv2rgb.h"
#include "usb_core.h"
#include "usb_dev.h"
#include "usb_audio.h"
#include "usb_cdc.h"
#include "usb_hid.h"
#include "usb_winusb.h"
#include "usb_mass_storage.h"
#endif

View File

@ -0,0 +1,79 @@
/*
******************************************************************************
* @file driver_crc.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2023
* @brief Header file of CRC module.
******************************************************************************
* @attention
*
* Copyright (c) 2023 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_CRC_H__
#define __DRIVER_CRC_H__
#include "fr30xx.h"
/** @addtogroup CRC_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
#define CRC_START (0x01)
#define CRC_CLEAR (0x08)
typedef struct
{
volatile uint32_t CRC_CTRL; /* Offset 0x00 */
volatile uint32_t CRC_STATUS; /* Offset 0x04 */
volatile uint32_t CRC_FIFO_DATA; /* Offset 0x08*/
volatile uint32_t CRC_RESULT; /* Offset 0x0C */
}struct_CRC_t;
#define CRC ((struct_CRC_t *)CRC_BASE)
/* ################################ Register Section END ################################## */
/**
* @}
*/
/** @addtogroup CRC_Initialization_Config_Section
* @{
*/
/* ################################ Initialization_Config Section Start ################################ */
typedef enum
{
CRC_INITVALUE_0 = 0x08u,
CRC_INITVALUE_1 = 0x18u,
CRC_MULTINOMIAL_16_1021 = 0x02u,
CRC_MULTINOMIAL_16_8005 = 0x04u,
CRC_MULTINOMIAL_32 = 0x06u,
}HAL_CRC_Accumulate;
typedef enum
{ // bit wide | polynomial | init value | Result XOR value | Input invert | Output invert
CRC8 = (CRC_INITVALUE_0), // 8 | 07 | 00 | 00 | fasle | fasle
CRC16_CCITT_FALSE = (CRC_INITVALUE_1 | CRC_MULTINOMIAL_16_1021), // 16 | 1021 | FFFF | FFFF | fasle | fasle
CRC16_XMODEM = (CRC_INITVALUE_0 | CRC_MULTINOMIAL_16_1021), // 16 | 1021 | 0000 | 0000 | fasle | fasle
CRC32_MPEG2 = (CRC_INITVALUE_1 | CRC_MULTINOMIAL_32), // 32 | 04C11DB7 | FFFFFFFF | 00000000 | fasle | fasle
}enum_CRC_MODE_SEL_t;
/* ################################ Initialization_Config Section END ################################## */
/**
* @}
*/
/* Exported functions ---------------------------------------------------------*/
/* Initial crc with initial value and mode */
void crc_init(enum_CRC_MODE_SEL_t fe_crc_mode);
/* CRC Calculate */
uint32_t crc_Calculate(uint8_t *fp_Data, uint32_t fu32_size);
#endif

View File

@ -0,0 +1,482 @@
/*
******************************************************************************
* @file driver_dma.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief Header file of DMA HAL module.
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_DMA_H__
#define __DRIVER_DMA_H__
#include "fr30xx.h"
#define DMA_CHANNELS_MAX (8)
/** @addtogroup DMA_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
/* Linked List Pointer Register for Channel */
typedef struct
{
uint32_t LMS : 2; // Starting Address In Memory.
uint32_t LOC : 30; // List Master Select.
}REG_LLP_t;
/* Control Register for Channel */
typedef struct
{
uint32_t INT_EN : 1; // Interrupt Enable.
uint32_t DST_TR_WIDTH : 3; // Destination Transfer Width.
uint32_t SRC_TR_WIDTH : 3; // Source Transfer Width.
uint32_t DINC : 2; // Destination Address Increment.
uint32_t SINC : 2; // Source Address Increment.
uint32_t DEST_MSIZE : 3; // Destination Burst Transaction Length.
uint32_t SRC_MSIZE : 3; // Source Burst Transaction Length.
uint32_t SRC_GATHER_EN : 1; // Source gather enable.
uint32_t DST_SCATTER_EN : 1; // Destination scatter enable.
uint32_t rsv_0 : 1; //
uint32_t TT_FC : 3; // Transfer Type and Flow Control.
uint32_t DMS : 2; // Destination Master Select.
uint32_t SMS : 2; // Source Master Select.
uint32_t LLP_DST_EN : 1; // Block chaining is enabled on the destination
uint32_t LLP_SRC_EN : 1; // Block chaining is enabled on the source
uint32_t rsv_1 : 3; //
}REG_CTL1_t;
/* Control Register for Channel */
typedef struct
{
uint32_t BLOCK_TS : 24; // Block Transfer Size.
uint32_t rsv_0 : 7;
uint32_t DONE : 1; // Done bit.
}REG_CTL2_t;
/* Configuration Register for Channel */
typedef struct
{
uint32_t rsv_0 : 5;
uint32_t CH_PRIOR : 3; // Channel Priority.
uint32_t CH_SUSP : 1; // Channel Suspend.
uint32_t FIFO_EMPTY : 1; // Channel FIFO status.
uint32_t HS_SEL_DST : 1; // Destination Software or Hardware Handshaking Select.
uint32_t HS_SEL_SRC : 1; // Source Software or Hardware Handshaking Select.
uint32_t LOCK_CH_L : 2;
uint32_t LOCK_B_L : 2;
uint32_t LOCK_CH : 1;
uint32_t LOCK_B : 1;
uint32_t DST_HS_POL : 1; // Destination Handshaking Interface Polarity.
uint32_t SRC_HS_POL : 1; // Source Handshaking Interface Polarity.
uint32_t MAX_ABRST : 10;
uint32_t RELOAD_SRC : 1; // Automatic Source Reload.
uint32_t RELOAD_DST : 1;
}REG_CFG1_t;
/* Configuration Register for Channel */
typedef struct
{
uint32_t FCMODE : 1;
uint32_t FIFO_MODE : 1;
uint32_t PROTCTL : 3;
uint32_t DS_UPD_EN : 1;
uint32_t SS_UPD_EN : 1;
uint32_t SRC_PER : 4;
uint32_t DEST_PER : 4;
uint32_t rsv_0 : 17;
}REG_CFG2_t;
/* Source Gath Register for Channel */
typedef struct
{
uint32_t SGI : 20;
uint32_t SGC : 12;
}REG_SGR_t;
/* Destination Scatter Register for Channel */
typedef struct
{
uint32_t DSI : 20;
uint32_t DSC : 12;
}REG_DSR_t;
/* -------------------------------------------*/
/* DAM Channel Register */
/* -------------------------------------------*/
typedef struct
{
volatile uint32_t SAR; // offset 0x00. Source Address for Channel
volatile uint32_t rsv_0; // offset 0x04
volatile uint32_t DAR; // offset 0x08. Destination Address Register for Channel
volatile uint32_t rsv_1; // offset 0x0C
volatile REG_LLP_t LLP; // offset 0x10. Linked List Pointer Register for Channel
volatile uint32_t rsv_2; // offset 0x14
volatile REG_CTL1_t CTL1; // offset 0x18. Control Register for Channel
volatile REG_CTL2_t CTL2; // offset 0x1C. Control Register for Channel
volatile uint32_t SSTAT; // offset 0x20. Source Status Register for Channel
volatile uint32_t rsv_3; // offset 0x24
volatile uint32_t DSTAT; // offset 0x28. Destination Status Register for Channel
volatile uint32_t rsv_4; // offset 0x2C
volatile uint32_t SSTATAR; // offset 0x30. Source Status Address Register for Channel
volatile uint32_t rsv_5; // offset 0x34
volatile uint32_t DSTATAR; // offset 0x38. Destination Status Address Register for Channel
volatile uint32_t rsv_6; // offset 0x3C
volatile REG_CFG1_t CFG1; // offset 0x40. Configuration Register for Channel
volatile REG_CFG2_t CFG2; // offset 0x44. Configuration Register for Channel
volatile REG_SGR_t SGR; // offset 0x48. Source Gather Register for Channel
volatile uint32_t rsv_7; // offset 0x4C
volatile REG_DSR_t DSR; // offset 0x50. Destination Scatter Register for Channel
volatile uint32_t rsv_8; // offset 0x54
}dma_channel_t;
/* -------------------------------------------*/
/* DAM Interrupt Register */
/* -------------------------------------------*/
typedef struct
{
volatile uint32_t RawTfr;
volatile uint32_t rsv_0;
volatile uint32_t RawBlock;
volatile uint32_t rsv_1;
volatile uint32_t RawSrcTran;
volatile uint32_t rsv_2;
volatile uint32_t RawDstDran;
volatile uint32_t rsv_3;
volatile uint32_t RawErr;
volatile uint32_t rsv_4;
volatile uint32_t StatusTfr;
volatile uint32_t rsv_5;
volatile uint32_t StatusBlock;
volatile uint32_t rsv_6;
volatile uint32_t StatusSrcTran;
volatile uint32_t rsv_7;
volatile uint32_t StatusDstTran;
volatile uint32_t rsv_8;
volatile uint32_t StatusErr;
volatile uint32_t rsv_9;
volatile uint32_t MaskTfr;
volatile uint32_t rsv_10;
volatile uint32_t MaskBlock;
volatile uint32_t rsv_11;
volatile uint32_t MaskSrcTran;
volatile uint32_t rsv_12;
volatile uint32_t MaskDstTran;
volatile uint32_t rsv_13;
volatile uint32_t MaskErr;
volatile uint32_t rsv_14;
volatile uint32_t ClearTfr;
volatile uint32_t rsv_15;
volatile uint32_t ClearBlock;
volatile uint32_t rsv_16;
volatile uint32_t ClearSrcTran;
volatile uint32_t rsv_17;
volatile uint32_t ClearDstTran;
volatile uint32_t rsv_18;
volatile uint32_t ClearErr;
volatile uint32_t rsv_19;
volatile uint32_t StatusInt;
volatile uint32_t rsv_20;
}dma_interrupt_t;
/* ------------------------------------------------*/
/* DAM Software Handshake Register */
/* ------------------------------------------------*/
typedef struct
{
volatile uint32_t ReqSrcReg;
volatile uint32_t rsv_0;
volatile uint32_t ReqDstReg;
volatile uint32_t rsv_1;
volatile uint32_t SglRqSrcReg;
volatile uint32_t rsv_2;
volatile uint32_t SglRqDstReg;
volatile uint32_t rsv_3;
volatile uint32_t LstSrcReg;
volatile uint32_t rsv_4;
volatile uint32_t LstDstReg;
volatile uint32_t rsv_5;
}dma_software_handshake_t;
/* -------------------------------------------*/
/* DAM Miscellaneous Register */
/* -------------------------------------------*/
typedef struct
{
volatile uint32_t DMA_EN : 1;
volatile uint32_t rsv_0 : 31;
}REG_DmaCfg_t;
typedef struct
{
volatile REG_DmaCfg_t DmaCfgReg;
volatile uint32_t rsv_0;
volatile uint32_t ChEnReg;
}dma_miscellaneous_t;
typedef struct
{
dma_channel_t Channels[DMA_CHANNELS_MAX];
dma_interrupt_t Int_Reg;
dma_software_handshake_t Software_Handshake_Reg;
dma_miscellaneous_t Misc_Reg;
}struct_DMA_t;
#define DMA0 ((struct_DMA_t *)DMAC0_BASE)
#define DMA1 ((struct_DMA_t *)DMAC1_BASE)
/* ################################ Register Section END ################################ */
/**
* @}
*/
/** @addtogroup DMA_Initialization_Config_Section
* @{
*/
/* ################################ Initialization, Config Section Start ################################ */
typedef enum
{
DMA_Channel0,
DMA_Channel1,
DMA_Channel2,
DMA_Channel3,
DMA_Channel4,
DMA_Channel5,
DMA_Channel6,
DMA_Channel7,
}dma_channel_select_t;
enum dma_data_flow_t
{
DMA_M2M_DMAC, // Memory to Memory and Flow Controller is dmac
DMA_M2P_DMAC, // Memory to Peripheral and Flow Controller is dmac
DMA_P2M_DMAC, // Peripheral to Memory and Flow Controller is dmac
DMA_P2P_DMAC, // Peripheral to Peripheral and Flow Controller is dmac
DMA_P2M_PER, // Peripheral to Memory and Flow Controller is Peripheral
DMA_P2P_SRCPER, // Peripheral to Peripheral and Flow Controller is Source Peripheral
DMA_M2P_PER, // Memory to Peripheral and Flow Controller is Peripheral
DMA_P2P_DSTPER, // Peripheral to Peripheral and Flow Controller is Destination Peripheral
};
enum dma_addr_inc_t
{
DMA_ADDR_INC_INC, // Increments the source/destination address
DMA_ADDR_INC_DEC, // Decrements the source/destination address
DMA_ADDR_INC_NO_CHANGE, // No change the source/destination address
};
enum dma_transfer_width_t
{
DMA_TRANSFER_WIDTH_8,
DMA_TRANSFER_WIDTH_16,
DMA_TRANSFER_WIDTH_32,
};
typedef enum
{
DMA_BURST_LEN_1,
DMA_BURST_LEN_4,
DMA_BURST_LEN_8,
DMA_BURST_LEN_16,
DMA_BURST_LEN_32,
DMA_BURST_LEN_64,
DMA_BURST_LEN_128,
DMA_BURST_LEN_256,
}dma_burst_len_t;
enum dma_ahb_master_t
{
DMA_AHB_MASTER_1, /* access to 0x00000000~0x1FFFFFFF space */
DMA_AHB_MASTER_2, /* access to 0x20000000~ space */
DMA_AHB_MASTER_3, /* access to 0x20000000~ space */
DMA_AHB_MASTER_4, /* access to 0x20000000~ space */
};
/**
* @brief DMA Initialization Structure definition
*/
typedef struct
{
uint8_t Data_Flow; /* This parameter can be a value of @ref dma_data_flow_t */
uint8_t Request_ID; /* This parameter can be a value of @ref dma_requeat_id_t */
uint8_t Source_Master_Sel; /* This parameter can be a value of @ref dma_ahb_master_t */
uint8_t Desination_Master_Sel; /* This parameter can be a value of @ref dma_ahb_master_t */
uint8_t Source_Inc; /* This parameter can be a value of @ref dma_addr_inc_t */
uint8_t Desination_Inc; /* This parameter can be a value of @ref dma_addr_inc_t */
uint8_t Source_Width; /* This parameter can be a value of @ref dma_transfer_width_t */
uint8_t Desination_Width; /* This parameter can be a value of @ref dma_transfer_width_t */
uint8_t Source_Burst_Len; /* This parameter can be a value of @ref dma_burst_len_t */
uint8_t Desination_Burst_Len; /* This parameter can be a value of @ref dma_burst_len_t */
}dma_InitParameter_t;
/**
* @brief DAM handle Structure definition
*/
typedef struct
{
struct_DMA_t *DMAx; /* DMA registers base address */
dma_channel_select_t Channel; /* DMA registers base address */
/* This parameter can be a value of @ref dma_channel_select_t */
dma_InitParameter_t Init; /* DMA initialization parameters */
}DMA_HandleTypeDef;
/**
* @brief DMA Link List Item Structure
*/
typedef struct DMA_NextLink
{
uint32_t SrcAddr; /* source address */
uint32_t DstAddr; /* desination address */
struct DMA_NextLink *Next; /* Next Link */
REG_CTL1_t CTL1; /* Control Register for Channel */
REG_CTL2_t CTL2; /* Control Register for Channel */
}DMA_LLI_InitTypeDef;
/**
* @brief DMA Initialization Structure definition
*/
typedef struct
{
uint32_t SrcAddr; /* source address */
uint32_t DstAddr; /* desination address */
uint32_t NextLink; /* Next Link Address */
uint32_t Data_Flow; /* This parameter can be a value of @ref dma_data_flow_t */
uint32_t Request_ID; /* This parameter can be a value of @ref dma_requeat_id_t */
uint8_t Source_Master_Sel; /* This parameter can be a value of @ref dma_ahb_master_t */
uint8_t Desination_Master_Sel; /* This parameter can be a value of @ref dma_ahb_master_t */
uint32_t Source_Inc; /* This parameter can be a value of @ref dma_addr_inc_t */
uint32_t Desination_Inc; /* This parameter can be a value of @ref dma_addr_inc_t */
uint32_t Source_Width; /* This parameter can be a value of @ref dma_transfer_width_t */
uint32_t Desination_Width; /* This parameter can be a value of @ref dma_transfer_width_t */
uint32_t Source_Burst_Len; /* This parameter can be a value of @ref dma_burst_len_t */
uint32_t Desination_Burst_Len; /* This parameter can be a value of @ref dma_burst_len_t */
uint32_t Size; /* This parameter can be a 12-bit Size */
uint8_t gather_enable; /* Enable Source Gather or not */
uint8_t scatter_enable; /* Enable Destination Scatter or not */
}dma_LinkParameter_t;
/* ################################ Initialization, Config Section END ################################ */
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
/* set DATA flow selection */
#define __DMA_DATA_FLOW_CONTROL_SET(__DMAC__, __CHANNEL__, SEL) (__DMAC__->Channels[__CHANNEL__].CTL1.TT_FC = SEL)
/* APB Master selection configuration */
#define __DMA_SRC_MASTER_SET(__DMAC__, __CHANNEL__, SEL) (__DMAC__->Channels[__CHANNEL__].CTL1.SMS = SEL)
#define __DMA_DES_MASTER_SET(__DMAC__, __CHANNEL__, SEL) (__DMAC__->Channels[__CHANNEL__].CTL1.DMS = SEL)
/* Address increment configuration */
#define __DMA_SRC_ADDR_INC_SET(__DMAC__, __CHANNEL__, INC) (__DMAC__->Channels[__CHANNEL__].CTL1.SINC = INC)
#define __DMA_DES_ADDR_INC_SET(__DMAC__, __CHANNEL__, INC) (__DMAC__->Channels[__CHANNEL__].CTL1.DINC = INC)
/* Gather function enable,disable */
#define __DMA_GATHER_FUNC_ENABLE(__DMAC__, __CHANNEL__) (__DMAC__->Channels[__CHANNEL__].CTL1.SRC_GATHER_EN = 1)
#define __DMA_GATHER_FUNC_DISABLE(__DMAC__, __CHANNEL__) (__DMAC__->Channels[__CHANNEL__].CTL1.SRC_GATHER_EN = 0)
/* Gather count, Gather interval */
#define __DMA_GATHER_COUNT(__DMAC__, __CHANNEL__, __COUNT__) (__DMAC__->Channels[__CHANNEL__].SGR.SGC = __COUNT__)
#define __DMA_GATHER_INTERVAL(__DMAC__, __CHANNEL__, __INTERVAL__) (__DMAC__->Channels[__CHANNEL__].SGR.SGI = __INTERVAL__)
/* Scatter function enable,disable */
#define __DMA_SCATTER_FUNC_ENABLE(__DMAC__, __CHANNEL__) (__DMAC__->Channels[__CHANNEL__].CTL1.DST_SCATTER_EN = 1)
#define __DMA_SCATTER_FUNC_DISABLE(__DMAC__, __CHANNEL__) (__DMAC__->Channels[__CHANNEL__].CTL1.DST_SCATTER_EN = 0)
/* Scatter count, Gather interval */
#define __DMA_SCATTER_COUNT(__DMAC__, __CHANNEL__, __COUNT__) (__DMAC__->Channels[__CHANNEL__].DSR.DSC = __COUNT__)
#define __DMA_SCATTER_INTERVAL(__DMAC__, __CHANNEL__, __INTERVAL__) (__DMAC__->Channels[__CHANNEL__].DSR.DSI = __INTERVAL__)
/* Exported functions --------------------------------------------------------*/
/* dma_init */
void dma_init(DMA_HandleTypeDef *hdma);
/* dma_start */
void dma_start(DMA_HandleTypeDef *hdma, uint32_t SrcAddr, uint32_t DstAddr, uint32_t Size);
/* dma_start_interrupt */
void dma_start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddr, uint32_t DstAddr, uint32_t Size);
/* dma_linked_list_init */
void dma_linked_list_init(DMA_LLI_InitTypeDef *link, dma_LinkParameter_t *param);
/* dma_linked_list_start */
void dma_linked_list_start(DMA_HandleTypeDef *hdma, DMA_LLI_InitTypeDef *link, dma_LinkParameter_t *param);
/* dma_linked_list_start_IT */
void dma_linked_list_start_IT(DMA_HandleTypeDef *hdma, DMA_LLI_InitTypeDef *link, dma_LinkParameter_t *param);
/* dma_tfr_interrupt_enable */
void dma_tfr_interrupt_enable(DMA_HandleTypeDef *hdma);
/* dma_tfr_interrupt_disable */
void dma_tfr_interrupt_disable(DMA_HandleTypeDef *hdma);
/* dma_get_tfr_Status */
bool dma_get_tfr_Status(DMA_HandleTypeDef *hdma);
/* dma_clear_tfr_Status */
void dma_clear_tfr_Status(DMA_HandleTypeDef *hdma);
/* dma_error_interrupt_enable */
void dma_error_interrupt_enable(DMA_HandleTypeDef *hdma);
/* dma_error_interrupt_disable */
void dma_error_interrupt_disable(DMA_HandleTypeDef *hdma);
/* dma_get_error_Status */
bool dma_get_error_Status(DMA_HandleTypeDef *hdma);
/* dma_clear_error_Status */
void dma_clear_error_Status(DMA_HandleTypeDef *hdma);
#endif

View File

@ -0,0 +1,92 @@
/*
******************************************************************************
* @file driver_efuse.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2022
* @brief Header file of eFuse HAL module.
******************************************************************************
* @attention
*
* Copyright (c) 2022 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_EFUSE_H__
#define __DRIVER_EFUSE_H__
#include "fr30xx.h"
/** @addtogroup eFuse_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
/* Control Register */
/* bit2: Done */
/* bit1: Read/Write */
/* bit0: GO */
#define EFUSE_SISO_READ_MODE (0x01)
#define EFUSE_SISO_WRITE_MODE (0x03)
#define EFUSE_SISO_CHECK_DONE (0x04)
/* ------------------------------------------------*/
/* eFuse SISO Register */
/* ------------------------------------------------*/
typedef struct
{
volatile uint32_t eFuse_Ctrl; /* Offset 0x00 */
volatile uint32_t eFuse_Timing; /* Offset 0x04 */
volatile uint32_t eFuse_Data0; /* Offset 0x08 */
volatile uint32_t eFuse_Data1; /* Offset 0x0C */
volatile uint32_t eFuse_Data2; /* Offset 0x10 */
}struct_eFuse_SISO_t;
#define EFUSE_SISO ((struct_eFuse_SISO_t *)EFUSE_SISO_BASE)
/* Control Register */
/* bit4: Done */
/* bit3: Read */
/* bit2: Write */
/* bit1: AVDDEN */
/* bit0: GO */
#define EFUSE_PIPO_CHECK_DONE (0x10)
#define EFUSE_PIPO_READ_MODE (0x08)
#define EFUSE_PIPO_WRITE_MODE (0x04)
#define EFUSE_PIPO_AVDDEN (0x02)
#define EFUSE_PIPO_GO (0x01)
/* ------------------------------------------------*/
/* eFuse PIPO Register */
/* ------------------------------------------------*/
typedef struct
{
volatile uint32_t eFuse_Ctrl; /* Offset 0x00 */
volatile uint32_t eFuse_Length; /* Offset 0x04 */
volatile uint32_t eFuse_Addr; /* Offset 0x08 */
volatile uint32_t eFuse_WData; /* Offset 0x0C */
volatile uint32_t eFuse_RData; /* Offset 0x10 */
}struct_eFuse_PIPO_t;
#define EFUSE_PIPO ((struct_eFuse_PIPO_t *)EFUSE_PIPO_BASE)
/* ################################ Register Section END ################################## */
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/* eFuse_siso_read */
/* eFuse_siso_write */
void eFuse_siso_read(uint32_t *fp_Data);
void eFuse_siso_write(uint32_t *fp_Data);
void eFuse_pipo_read(uint8_t fu8_Addr, uint8_t *fp_Data);
void eFuse_pipo_write(uint8_t fu8_Addr, uint8_t fu8_Data);
#endif

View File

@ -0,0 +1,80 @@
#ifndef _EXTI_H
#define _EXTI_H
#include <stdint.h>
#include "plf.h"
#include "driver_iomux.h"
enum ext_int_type_t
{
EXT_INT_TYPE_LOW,
EXT_INT_TYPE_HIGH,
EXT_INT_TYPE_POS,
EXT_INT_TYPE_NEG,
};
struct exti_ctrl_t //EXTINTCTL. 0x14
{
uint32_t pa_exti_en: 8; //exti intr connect to gpio PA ctrl
uint32_t pb_exti_en: 8; //exti intr connect to gpio PB ctrl
uint32_t resv: 16;
};
struct exti_status_t //EXTINTSTS 0x18
{
uint32_t pa_exti_sts: 8; //PA exti intr status
uint32_t pb_exti_sts: 8; //PB exti intr status
uint32_t resv: 16;
};
struct exti_type_t //EXTINTTYPE offset@0x1C
{
uint32_t pa0_exti_type: 2; //external intr source sel.
uint32_t pa1_exti_type: 2; //external intr source sel.
uint32_t pa2_exti_type: 2; //external intr source sel.
uint32_t pa3_exti_type: 2; //external intr source sel.
uint32_t pa4_exti_type: 2; //external intr source sel.
uint32_t pa5_exti_type: 2; //external intr source sel.
uint32_t pa6_exti_type: 2; //external intr source sel.
uint32_t pa7_exti_type: 2; //external intr source sel.
uint32_t pb0_exti_type: 2; //external intr source sel.
uint32_t pb1_exti_type: 2; //external intr source sel.
uint32_t pb2_exti_type: 2; //external intr source sel.
uint32_t pb3_exti_type: 2; //external intr source sel.
uint32_t pb4_exti_type: 2; //external intr source sel.
uint32_t pb5_exti_type: 2; //external intr source sel.
uint32_t pb6_exti_type: 2; //external intr source sel.
uint32_t pb7_exti_type: 2; //external intr source sel.
};
struct exti_cnt_t //EXTINTCNT00 offset:0x20
{
uint32_t pre_cnt: 12; //Precaler Value: set the external interrupt source 0 CNT_CLK: CNT_CLK=PCLK/(1+ Precaler Value)
uint32_t des_cnt: 4; //Counter Value. (only useful for level trigger mode)
uint32_t resv: 16;
};
struct exti_reg_t
{
struct exti_ctrl_t exti_ctrl; //EXTINTCTL. 0x14
struct exti_status_t exti_sts; //EXTINTSTS 0x18
struct exti_type_t exti_type; //EXTINTTYPE offset@0x1C
struct exti_cnt_t exti_cnt[16]; //EXTINTCNT00~EXTINTCNT15 offset:0x20~0x
};
extern volatile struct exti_reg_t *extiAB_regs;
extern volatile struct exti_reg_t *extiCD_regs;
extern volatile struct exti_reg_t *extiEF_regs;
extern volatile struct exti_reg_t *extiGH_regs;
void exti_enable(enum system_port_t port,enum system_port_bit_t bit);
void exti_disable(enum system_port_t port,enum system_port_bit_t bit);
uint8_t exti_get_src(enum system_port_t port);
void exti_intr_clr(enum system_port_t port,uint8_t bits);
void exti_set_type(enum system_port_t port,enum system_port_bit_t bit, enum ext_int_type_t type);
void exti_set_debounce_cnt(enum system_port_t port,enum system_port_bit_t bit, uint32_t clk, uint8_t cnt);
#endif //_EXTI_H

View File

@ -0,0 +1,185 @@
/*
******************************************************************************
* @file driver_fft.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2023
* @brief Header file of FFT module.
******************************************************************************
* @attention
*
* Copyright (c) 2023 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_FFT_H__
#define __DRIVER_FFT_H__
#include "fr30xx.h"
/** @addtogroup FFT_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
/*FFT CTRL REG 0x00*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t NP_SEL : 2; // fft sample number point select
uint32_t MODE_SEL : 1; // fft calculate mode select
uint32_t RSV : 29;
} Bits;
} REG_FFT_CTRL_t;
/*FFT DMA CONFIG REG 0x04*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t DMACR : 2; //dma clear
uint32_t RSV1 : 6;
uint32_t DMA_OUT_THR : 8; //dma_out_req start threshold
uint32_t DMA_IN_THR : 8; //dma_in_req start threshold
uint32_t RSV : 8;
} Bits;
} REG_FFT_DMA_t;
/*FFT INTERRUPT CLEAR REG 0x08*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t INT_EN : 1; //FFT interrupt enable
uint32_t RSV1 : 7;
uint32_t INT_STATUS : 1; //FFT interrupt status
uint32_t RSV2 : 22;
} Bits;
} REG_FFT_ISRCR_t;
/*FFT SOFT RESET REG 0x0c*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t NRST : 1; //FFT soft reset
uint32_t RSV : 31;
} Bits;
} REG_FFT_SOFTRST_t;
/*FFT STATUS REG 0x14*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t IDLE : 1; // FFT status is idle
uint32_t CAL_DONE : 1; // FFT calculate done
uint32_t RSV : 30;
} Bits;
} REG_FFT_STATUS_t;
/* -----------------------------------------------*/
/* FFT Registers */
/* -----------------------------------------------*/
typedef struct
{
volatile REG_FFT_CTRL_t FFT_CTRL; /* Offset 0x00 */
volatile REG_FFT_DMA_t FFT_DMA; /* Offset 0x04 */
volatile REG_FFT_ISRCR_t FFT_ISRCR; /* Offset 0x08 */
volatile REG_FFT_SOFTRST_t FFT_SOFTRST_IIRFLT; /* Offset 0x0C */
volatile uint32_t rsv1; /* Offset 0x10 */
volatile REG_FFT_STATUS_t FFT_STATUS; /* Offset 0x14 */
volatile uint32_t rsv2[26]; /* Offser 0x18 ~ 0x7c*/
volatile uint32_t FFT_ACCESSRAM; /* Offset 0x80 */
}struct_FFT_t;
#define FFT ((struct_FFT_t *)FFT_BASE)
/* ################################ Register Section END ################################ */
/**
* @}
*/
/** @addtogroup FFT_Initialization_Config_Section
* @{
*/
/* ################################ Initialization Config Section Start ################################ */
typedef enum
{
FFT_128 = 0,
FFT_256 = 1,
FFT_512 = 2,
}FFT_Samples_t ;
typedef enum
{
FFT_CAL_MODE = 0, /* FFT calculate */
IFFT_CAL_MODE = 1, /* FFT inverse calculation */
}FFT_Cal_Mode_t ;
typedef struct
{
uint32_t FFT_Samples; /*!< Specifies the number of Sample.
This parameter can be a value of @ref fft_samples_t. */
uint32_t FFT_Cal_Mode; /*!< Specifies the FFT calculate mode.
This parameter can be a value of @ref FFT_Cal_Mode_t. */
}struct_FFT_Init_t;
typedef struct
{
struct_FFT_Init_t FFT_Init;
uint32_t BlockCNT;
uint32_t BlockSize;
uint32_t DataIndex;
uint32_t DataOutIndex;
uint32_t *DataIn;
uint32_t *DataOut;
bool FFT_Busy;
}FFT_HandleTypeDef;
/* ################################ Initialization/Config Section END ################################## */
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
/* FFT reset */
#define __FFT_RESET_ENABLE() (FFT->FFT_SOFTRST_IIRFLT.Bits.NRST = 0)
#define __FFT_RESET_DISABLE() (FFT->FFT_SOFTRST_IIRFLT.Bits.NRST = 1)
/* FFT int enable/disable/clear */
#define __FFT_INT_ENALE() (FFT->FFT_ISRCR.Bits.INT_EN = 1)
#define __FFT_INT_DISALE() (FFT->FFT_ISRCR.Bits.INT_EN = 0)
#define __FFT_INT_STATUS_CLEAR() (FFT->FFT_ISRCR.Bits.INT_STATUS = 0)
/* FFT calculate id done */
#define __FFT_CAL_IS_DONE() (FFT->FFT_STATUS.Bits.CAL_DONE == 1)
/* FFT is dile */
#define __FFT_IS_IDLE() (FFT->FFT_STATUS.Bits.IDLE == 1)
/* FFT DMA config */
#define __FFT_DMA_ENABLE() (FFT->FFT_DMA.Bits.DMACR = 3)
#define __FFT_DMA_IN_THR(__THR__) (FFT->FFT_DMA.Bits.DMA_IN_THR = __THR__)
#define __FFT_DMA_OUT_THR(__THR__) (FFT->FFT_DMA.Bits.DMA_OUT_THR = __THR__)
/* Exported functions --------------------------------------------------------*/
/* Initialize the fft module */
void fft_init(FFT_HandleTypeDef *hfft);
/* FFt start */
void fft_start(FFT_HandleTypeDef *hfft, uint32_t *fp_Data_In, uint32_t *fp_Data_Out, uint32_t fu32_BlockCNT);
/* FFT start with isr */
int fft_start_IT(FFT_HandleTypeDef *hfft, uint32_t *fp_Data_In, uint32_t *fp_Data_Out, uint32_t fu32_BlockCNT);
/* FFT interrupt handler */
void fft_IRQHandler(FFT_HandleTypeDef *hfft);
#endif

View File

@ -0,0 +1,125 @@
/*
* flash.h
*
* Created on: 2018-1-25
* Author: owen
*/
#ifndef _DRIVER_FLASH_H
#define _DRIVER_FLASH_H
#include <stdint.h>
#include <stdbool.h>
#include "driver_qspi.h"
#define FLASH_READ_DEVICE_ID 0x90
#define FLASH_READ_IDENTIFICATION 0x9F
#define FLASH_AAI_PROGRAM_OPCODE 0xAF
#define FLASH_PAGE_PROGRAM_OPCODE 0x02
#define FLASH_READ_OPCODE 0x03
#define FLASH_FAST_READ_OPCODE 0x0B
#define FLASH_FAST_DTR_READ_OPCODE 0x0D
#define FLASH_READ_DUAL_OPCODE 0xBB
#define FLASH_READ_DTR_DUAL_OPCODE 0xBD
#define FLASH_READ_DUAL_OPCODE_2 0x3B
#define FLASH_PAGE_DUAL_PROGRAM_OPCODE 0xA2
#define FLASH_PAGE_QUAL_READ_OPCODE 0xEB
#define FLASH_PAGE_DTR_QUAL_READ_OPCODE 0xED
#define FLASH_PAGE_QUAL_READ_OPCODE_2 0x6B
#define FLASH_PAGE_QUAL_PROGRAM_OPCODE 0x32
#define FLASH_CHIP_ERASE_OPCODE 0x60
#define FLASH_SECTORE_ERASE_OPCODE 0x20
#define FLASH_BLOCK_32K_ERASE_OPCODE 0x52
#define FLASH_BLOCK_64K_ERASE_OPCODE 0xD8
#define FLASH_ST_SECTORE_ERASE_OPCODE 0xD8
#define FLASH_ST_BULK_ERASE_OPCODE 0xC7
#define FLASH_WRITE_DISABLE_OPCODE 0x04
#define FLASH_WRITE_ENABLE_OPCODE 0x06
#define FLASH_WRITE_STATUS_REG_OPCODE 0x01
#define FLASH_READ_STATUS_REG_OPCODE 0x05
#define FLASH_READ_STATUS_HIGH_REG_OPCODE 0x35
#define FLASH_SEC_REG_READ_OPCODE (0x48)
#define FLASH_SEC_REG_PROGRAM_OPCODE (0x42)
#define FLASH_SEC_REG_ERASE_OPCODE (0x44)
#define FLASH_ST_ID 0x20
#define FLASH_SST_ID 0xBF
#define FLASH_OP_TYPE_ERASE 0
#define FLASH_OP_TYPE_WRITE 1
enum flash_rd_type_t {
FLASH_RD_TYPE_SINGLE,
FLASH_RD_TYPE_SINGLE_FAST,
FLASH_RD_TYPE_DUAL,
FLASH_RD_TYPE_DUAL_FAST,
FLASH_RD_TYPE_QUAD,
FLASH_RD_TYPE_QUAD_FAST,
FLASH_RD_TYPE_DTR_SINGLE_FAST,
FLASH_RD_TYPE_DTR_DUAL_FAST,
FLASH_RD_TYPE_DTR_QUAD_FAST,
};
enum flash_wr_type_t {
FLASH_WR_TYPE_SINGLE,
FLASH_WR_TYPE_DUAL,
FLASH_WR_TYPE_QUAD,
};
void flash_set_read_fast_quad(struct qspi_regs_t *qspi);
void flash_set_read_quad(struct qspi_regs_t *qspi);
void flash_set_read_fast_dual(struct qspi_regs_t *qspi);
void flash_set_read_dual(struct qspi_regs_t *qspi);
void flash_set_read_fast_single(struct qspi_regs_t *qspi);
void flash_set_read_single(struct qspi_regs_t *qspi);
void flash_set_write_quad(struct qspi_regs_t *qspi);
void flash_set_write_dual(struct qspi_regs_t *qspi);
void flash_set_write_single(struct qspi_regs_t *qspi);
uint16_t flash_read_status(struct qspi_regs_t *qspi, bool read_high);
void flash_write_status(struct qspi_regs_t *qspi, uint16_t status_entity, bool write_high);
void flash_write_status_volatile(struct qspi_regs_t *qspi, uint16_t status, bool write_high);
void flash_write_status_2(struct qspi_regs_t *qspi, uint8_t status);
void flash_write_status_2_volatile(struct qspi_regs_t *qspi, uint8_t status);
uint8_t flash_write(struct qspi_regs_t *qspi, uint32_t offset, uint32_t length, const uint8_t *buffer);
uint8_t flash_read(struct qspi_regs_t *qspi, uint32_t offset, uint32_t length, uint8_t *buffer);
uint8_t flash_erase(struct qspi_regs_t *qspi, uint32_t offset, uint32_t size);
void flash_chip_erase(struct qspi_regs_t *qspi);
void flash_enter_deep_sleep(struct qspi_regs_t *qspi);
void flash_exit_deep_sleep(struct qspi_regs_t *qspi);
void flash_enable_quad(struct qspi_regs_t *qspi);
void flash_set_IO_DRV(struct qspi_regs_t *qspi, uint8_t drv);
void flash_set_capture_delay(struct qspi_regs_t *qspi, uint8_t delay);
void flash_init_controller(struct qspi_regs_t *qspi, enum flash_rd_type_t rd_type, enum flash_wr_type_t wr_type);
uint32_t flash_init(struct qspi_regs_t *qspi);
uint32_t flash_read_id(struct qspi_regs_t *qspi);
void flash_set_baudrate(struct qspi_regs_t *qspi, uint8_t baudrate);
void flash_OTP_read(struct qspi_regs_t *qspi,uint32_t offset, uint32_t length, uint8_t *buffer);
void flash_OTP_write(struct qspi_regs_t *qspi,uint32_t offset, uint32_t length, uint8_t *buffer);
void flash_OTP_erase(struct qspi_regs_t *qspi,uint32_t offset);
/************************************************************************************
* @fn flash_protect_bit_set
*
* @brief set flash protection relevant bits.
*
* @param qspi: qspi controller base address
* bits: flash protection bits in status 1, BIT4:0 is valid.
* cmp: flash protection compare bit in status 2.
* 0xff means this field should be ignored
* BIT7: clear or set CMP bit
* BIT0-2: CMP bit offset in status 2
* wr_volatile: write status registers in volatile mode or not
* status_2_separate: write status 2 together with status 1 or separately
*/
void flash_protect_bit_set(struct qspi_regs_t *qspi, uint8_t bits, uint8_t cmp, uint8_t wr_volatile, uint8_t status_2_separate);
#endif /* _DRIVER_FLASH_H */

View File

@ -0,0 +1,72 @@
/**
****************************************************************************************
*
* @file frspim.h
*
* @brief Common header file for all radios.
*
* Copyright (C) RivieraWaves 2009-2013
*
*
****************************************************************************************
*/
#ifndef FRSPIM_H_
#define FRSPIM_H_
#include <stdint.h>
struct frspim_ctrl_t{
uint32_t go:1; /*Write:0--no action,1--transmit start(hw clear)*/
uint32_t done:1; /*Read:0--idle,1--busy*/
uint32_t sel:2; /*channel select*/
uint32_t len:3; /*TX/RX byte(1:4)*/
uint32_t rsv0:1;
uint32_t op:1; /*1--write,0--read*/
uint32_t rsv1:3;
uint32_t ratio:2; /*sclk = p_clk/(1+ratio)*2*/
uint32_t rsv2:2;
uint32_t addr:8;
uint32_t rsv3:8;
};
struct frspim_wdat_t{
uint32_t wbyte0:8;
uint32_t wbyte1:8;
uint32_t wbyte2:8;
uint32_t wbyte3:8;
};
struct frspim_rdat_t{
uint32_t rbyte0:8;
uint32_t rbyte1:8;
uint32_t rbyte2:8;
uint32_t rbyte3:8;
};
struct frspim_reg_t{
struct frspim_ctrl_t ctrl;
struct frspim_wdat_t wdat;
struct frspim_rdat_t rdat;
};
#define FR_SPI_CODEC_CHAN 1
#define FR_SPI_PMU_CHAN 0
#define ool_write(addr, data) frspim_wr(FR_SPI_PMU_CHAN,(addr),1, (data))
#define ool_read(addr) (uint8_t)frspim_rd(FR_SPI_PMU_CHAN,(addr),1)
#define ool_write16(addr,data) frspim_wr(FR_SPI_PMU_CHAN,(addr),2, (data))
#define ool_read16(addr) (uint16_t)frspim_rd(FR_SPI_PMU_CHAN,(addr),2)
#define ool_write32(addr,data) frspim_wr(FR_SPI_PMU_CHAN,(addr),4, (data))
#define ool_read32(addr) (uint32_t)frspim_rd(FR_SPI_PMU_CHAN,(addr),4)
void frspim_init(uint8_t ratio);
uint32_t frspim_rd (uint8_t chan_num, uint8_t addr, uint8_t len);
void frspim_wr (uint8_t chan_num, uint8_t addr, uint8_t len, uint32_t val);
uint32_t frspim_rd_ram (uint8_t chan_num, uint8_t addr, uint8_t len);
void frspim_wr_ram (uint8_t chan_num, uint8_t addr, uint8_t len, uint32_t val);
#endif

View File

@ -0,0 +1,231 @@
/*
******************************************************************************
* @file driver_gpio.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief Header file of GPIO HAL module.
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_GPIO_H__
#define __DRIVER_GPIO_H__
#include "fr30xx.h"
/** @addtogroup GPIO_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
/* -----------------------------------------------*/
/* GPIO Registers */
/* -----------------------------------------------*/
typedef struct
{
volatile uint32_t GPIO_OutputEN; /* Offset 0x00 */
volatile uint32_t GPIO_IN_DATA; /* Offset 0x04 */
volatile uint32_t GPIO_OUT_DATA; /* Offset 0x08 */
volatile uint32_t GPIO_BIT_SET; /* Offset 0x0C */
volatile uint32_t GPIO_BIT_CLEAR; /* Offset 0x10 */
volatile uint32_t EXTI_EN; /* Offset 0x14 */
volatile uint32_t EXTI_INT_EN; /* Offset 0x18 */
volatile uint32_t EXTI_INT_STATUS; /* Offset 0x1C */
volatile uint32_t EXTI_TYPE; /* Offset 0x20 */
volatile uint32_t EXTI_CNT[16]; /* Offset 0x24 */
}struct_GPIO_t;
#define GPIO_TypeDef struct_GPIO_t
#define GPIOA (( GPIO_TypeDef *)GPIOA_BASE)
#define GPIOB (( GPIO_TypeDef *)GPIOB_BASE)
#define GPIOC (( GPIO_TypeDef *)GPIOC_BASE)
#define GPIOD (( GPIO_TypeDef *)GPIOD_BASE)
/* ################################ Register Section END ################################## */
/**
* @}
*/
/** @addtogroup ADC_Initialization_Config_Section
* @{
*/
/* ################################ Initialization<6F><6E>Config Section Start ################################ */
/** @defgroup GPIO_pins GPIO pins
* @{
*/
#define GPIO_PIN_0 ((uint16_t)0x0001) /* Pin 0 selected */
#define GPIO_PIN_1 ((uint16_t)0x0002) /* Pin 1 selected */
#define GPIO_PIN_2 ((uint16_t)0x0004) /* Pin 2 selected */
#define GPIO_PIN_3 ((uint16_t)0x0008) /* Pin 3 selected */
#define GPIO_PIN_4 ((uint16_t)0x0010) /* Pin 4 selected */
#define GPIO_PIN_5 ((uint16_t)0x0020) /* Pin 5 selected */
#define GPIO_PIN_6 ((uint16_t)0x0040) /* Pin 6 selected */
#define GPIO_PIN_7 ((uint16_t)0x0080) /* Pin 7 selected */
#define GPIO_PIN_8 ((uint16_t)0x0100) /* Pin 8 selected */
#define GPIO_PIN_9 ((uint16_t)0x0200) /* Pin 9 selected */
#define GPIO_PIN_10 ((uint16_t)0x0400) /* Pin 10 selected */
#define GPIO_PIN_11 ((uint16_t)0x0800) /* Pin 11 selected */
#define GPIO_PIN_12 ((uint16_t)0x1000) /* Pin 12 selected */
#define GPIO_PIN_13 ((uint16_t)0x2000) /* Pin 13 selected */
#define GPIO_PIN_14 ((uint16_t)0x4000) /* Pin 14 selected */
#define GPIO_PIN_15 ((uint16_t)0x8000) /* Pin 15 selected */
/**
* @}
*/
/** @defgroup EXTI_line_index
* @{
*/
#define EXTI_LINE_0 ((uint16_t)0x0001) /* EXTI Line index 0 */
#define EXTI_LINE_1 ((uint16_t)0x0002) /* EXTI Line index 1 */
#define EXTI_LINE_2 ((uint16_t)0x0004) /* EXTI Line index 2 */
#define EXTI_LINE_3 ((uint16_t)0x0008) /* EXTI Line index 3 */
#define EXTI_LINE_4 ((uint16_t)0x0010) /* EXTI Line index 4 */
#define EXTI_LINE_5 ((uint16_t)0x0020) /* EXTI Line index 5 */
#define EXTI_LINE_6 ((uint16_t)0x0040) /* EXTI Line index 6 */
#define EXTI_LINE_7 ((uint16_t)0x0080) /* EXTI Line index 7 */
#define EXTI_LINE_8 ((uint16_t)0x0100) /* EXTI Line index 8 */
#define EXTI_LINE_9 ((uint16_t)0x0200) /* EXTI Line index 9 */
#define EXTI_LINE_10 ((uint16_t)0x0400) /* EXTI Line index 10 */
#define EXTI_LINE_11 ((uint16_t)0x0800) /* EXTI Line index 11 */
#define EXTI_LINE_12 ((uint16_t)0x1000) /* EXTI Line index 12 */
#define EXTI_LINE_13 ((uint16_t)0x2000) /* EXTI Line index 13 */
#define EXTI_LINE_14 ((uint16_t)0x4000) /* EXTI Line index 14 */
#define EXTI_LINE_15 ((uint16_t)0x8000) /* EXTI Line index 15 */
/**
* @}
*/
/* GPIO mode */
typedef enum
{
GPIO_MODE_INPUT = 0x1000u, /*!< Input Floating Mode */
GPIO_MODE_INPUT_HRS = 0x1001u, /*!< Input High Resistance Mode */
GPIO_MODE_OUTPUT_PP = 0x1002u, /*!< Output Push Pull Mode */
GPIO_MODE_AF_PP = 0x0002u, /*!< Alternate Function Push Pull Mode */
GPIO_MODE_EXTI_IT_LOW_LEVEL = 0x1100u, /*!< External Interrupt Mode with low level trigger detection */
GPIO_MODE_EXTI_IT_HIGH_LEVEL = 0x1101u, /*!< External Interrupt Mode with high level trigger detection */
GPIO_MODE_EXTI_IT_FALLING = 0x1102u, /*!< External Interrupt Mode with Falling edge trigger detection */
GPIO_MODE_EXTI_IT_RISING = 0x1103u, /*!< External Interrupt Mode with Rising edge trigger detection */
GPIO_MODE_IO_MASK = 0x1000, /*!< GPIO Function Mask */
GPIO_MODE_IT_MASK = 0x0100, /*!< EXTI Function Mask */
}enum_GPIO_MODE_t;
/* GPIO pull */
typedef enum
{
GPIO_NOPULL, /*!< No Pull-up or Pull-down activation */
GPIO_PULLUP, /*!< Pull-up activation */
GPIO_PULLDOWN, /*!< Pull-down activation */
}enum_Pull_t;
/* function selection */
typedef enum
{
GPIO_FUNCTION_0,
GPIO_FUNCTION_1,
GPIO_FUNCTION_2,
GPIO_FUNCTION_3,
GPIO_FUNCTION_4,
GPIO_FUNCTION_5,
GPIO_FUNCTION_6,
GPIO_FUNCTION_7,
GPIO_FUNCTION_8,
GPIO_FUNCTION_9,
GPIO_FUNCTION_A,
GPIO_FUNCTION_B,
GPIO_FUNCTION_C,
GPIO_FUNCTION_D,
GPIO_FUNCTION_E,
GPIO_FUNCTION_F,
}enum_Function_t;
/* GPIO Bit SET and Bit RESET enumeration */
typedef enum
{
GPIO_PIN_CLEAR = 0u,
GPIO_PIN_SET = 1u,
}enum_PinStatus_t;
/* GPIO Drive Current Index */
typedef enum
{
GPIO_DRIVE_1mA,
GPIO_DRIVE_2mA,
GPIO_DRIVE_3mA,
GPIO_DRIVE_4mA,
}enum_GPIO_Drive_Current_t;
/*
* @brief GPIO Init structure definition
*/
typedef struct
{
uint32_t Pin; /*!< Specifies the GPIO pins to be configured.
This parameter can be any value of @ref GPIO_pins */
uint32_t Mode; /*!< Specifies the operating mode for the selected pins.
This parameter can be a value of @ref enum_GPIO_MODE_t */
uint32_t Pull; /*!< Specifies the Pull-up or Pull-Down activation for the selected pins.
This parameter can be a value of @ref enum_Pull_t */
uint32_t Alternate; /*!< Peripheral to be connected to the selected pins.
This parameter can be a value of @ref enum_Function_t */
}GPIO_InitTypeDef;
/* ################################ Initialization<6F><6E>Config Section END ################################## */
/**
* @}
*/
/* Exported functions --------------------------------------------------------*/
/* gpio_init */
void gpio_init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init);
/* gpio_set_portpull */
void gpio_set_portpull(GPIO_TypeDef *GPIOx, uint16_t fu16_Pin, enum_Pull_t fe_Pull);
/* gpio_write_group */
/* gpio_write_pin */
void gpio_write_group(GPIO_TypeDef *GPIOx, uint16_t fu16_GroupStatus);
void gpio_write_pin(GPIO_TypeDef *GPIOx, uint16_t fu16_Pin, enum_PinStatus_t fe_PinStatus);
/* gpio_read_group */
/* gpio_read_pin */
uint16_t gpio_read_group(GPIO_TypeDef *GPIOx);
enum_PinStatus_t gpio_read_pin(GPIO_TypeDef *GPIOx, uint16_t fu16_Pin);
/* gpio_drive_current_config */
/* input schmitt enable/disable */
void gpio_drive_current_config(GPIO_TypeDef *GPIOx, uint16_t fu16_Pin, enum_GPIO_Drive_Current_t fe_GPIO_Drive);
/* exti_interrupt_enable */
/* exti_interrupt_disable */
void exti_interrupt_enable(GPIO_TypeDef *GPIOx, uint16_t fu16_EXTI_Line);
void exti_interrupt_disable(GPIO_TypeDef *GPIOx, uint16_t fu16_EXTI_Line);
/* exti_get_LineStatus */
/* exti_clear_LineStatus */
bool exti_get_LineStatus(GPIO_TypeDef *GPIOx, uint16_t fu16_EXTI_Line);
void exti_clear_LineStatus(GPIO_TypeDef *GPIOx, uint16_t fu16_EXTI_Line);
/* exti_set_FilterCNT */
void exti_set_Filter(GPIO_TypeDef *GPIOx, uint16_t fu16_EXTI_Line, uint8_t fu8_DIV, uint16_t fu16_CNT);
#endif

View File

@ -0,0 +1,370 @@
/*
******************************************************************************
* @file driver_i2c.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief Header file of I2C HAL module.
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_I2C_H__
#define __DRIVER_I2C_H__
#include "fr30xx.h"
/** @addtogroup I2C_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
/* I2C control Register */
typedef struct
{
uint32_t MASTER_MODE : 1;
uint32_t SPEED : 2;
uint32_t ADDR_SLAVE_10BIT : 1;
uint32_t rsv_0 : 1;
uint32_t RESTART_EN : 1;
uint32_t SLAVE_DISABLE : 1;
uint32_t STOP_DET_IF_ADDR_ESSED : 1;
uint32_t TX_EMPTY_CTRL : 1;
uint32_t RX_FIFO_FULL_HLD_CTRL : 1;
uint32_t STOP_DET_IF_MASTER_ACTIVE : 1;
uint32_t BUS_DETEC_FEATURE_CTRL : 1;
uint32_t rsv_1 : 20;
}REG_I2C_CTRL_t;
/* target address Register */
typedef struct
{
uint32_t TAR : 10;
uint32_t rsv_0 : 1;
uint32_t SPECIAL : 1;
uint32_t ADDR_MASTER_10BIT : 1;
uint32_t DEVICE_ID : 1;
uint32_t rsv_1 : 18;
}REG_TAR_t;
/* DATA CMD Register */
typedef struct
{
uint32_t DAT : 8;
uint32_t CMD : 1;
uint32_t STOP : 1;
uint32_t RESTART : 1;
uint32_t FIRST_DATA_BYTE : 1;
uint32_t rsv_0 : 20;
}REG_DATA_CMD_t;
/* enable Register */
typedef struct
{
uint32_t ENABLE : 1;
uint32_t ABORT : 1;
uint32_t TX_CMD_BLOCK : 1;
uint32_t SDA_STUCK_RECOVERY : 1;
uint32_t rsv_0 : 28;
}REG_ENABLE_t;
/* Status Register */
typedef struct
{
uint32_t ACTIVITY : 1;
uint32_t TFNF : 1;
uint32_t TFE : 1;
uint32_t RFNE : 1;
uint32_t RFF : 1;
uint32_t MST_ACTIVITY : 1;
uint32_t SLV_ACTIVITY : 1;
uint32_t MST_HOLD_TX_FIFO_EMPTY : 1;
uint32_t MST_HOLD_RX_FIFO_FULL : 1;
uint32_t SLV_HOLD_TX_FIFO_EMPTY : 1;
uint32_t SLV_HOLD_RX_FIFO_FULL : 1;
uint32_t SDA_STUCK_NOT_RECOVERED : 1;
uint32_t rsv_0 : 20;
}REG_STATUS_t;
/* SDA hold Register */
typedef struct
{
uint32_t SDA_TX_HOLD : 16;
uint32_t SDA_RX_HOLD : 8;
uint32_t rsv_0 : 8;
}REG_SDA_HOLD_t;
/* TX ABRT SOURCE Register */
typedef union
{
struct
{
uint32_t ABRT_7ADDR_NOACK : 1;
uint32_t ABRT_10ADDR1_NOACK : 1;
uint32_t ABRT_10ADDR2_NOACK : 1;
uint32_t ABRT_TXDATA_NOACK : 1;
uint32_t rsv_0 : 2;
uint32_t ABRT_SBYTE_ACKDET : 1;
uint32_t rsv_1 : 1;
uint32_t ABRT_HS_NORSTRT : 1;
uint32_t rsv_2 : 1;
uint32_t ABRT_10B_RD_NORSTRT : 1;
uint32_t ABRT_MASTER_DIS : 1;
uint32_t ARB_LOST : 1;
uint32_t ABRT_SLVFLUSH_TXFIFO : 1;
uint32_t ABRT_SLV_ARBLOST : 1;
uint32_t ABRT_SLVRD_INTX : 1;
uint32_t ABRT_USER_ABRT : 1;
uint32_t ABRT_SDA_STUCK_AT_LOW : 1;
uint32_t rsv_3 : 1;
uint32_t ABRT_DEVICE_SLVADDR_NOACK : 1;
uint32_t ABRT_DEVICE_WRITE : 1;
uint32_t rsv_4 : 2;
uint32_t TX_FLUSH_CNT : 9;
}TX_ABRT_SOURCE_BIT;
uint32_t TX_ABRT_SOURCE_DWORD;
}REG_TX_ABRT_SOURCE_t;
/* DMA control Register */
typedef struct
{
uint32_t RDMAE : 1;
uint32_t TDMAE : 1;
uint32_t rsv_0 : 30;
}REG_DMA_CR_t;
/* -----------------------------------------------*/
/* I2C Register */
/* -----------------------------------------------*/
typedef struct
{
volatile REG_I2C_CTRL_t CTRL; /* Offset 0x00 */
volatile REG_TAR_t TAR; /* Offset 0x04 */
volatile uint32_t SAR; /* Offset 0x08 */
volatile uint32_t HS_MADDR; /* Offset 0x0C */
volatile uint32_t DATA_CMD; /* Offset 0x10 */
volatile uint32_t rsv_0[2];
volatile uint32_t FS_SCL_HCNT; /* Offset 0x1C */
volatile uint32_t FS_SCL_LCNT; /* Offset 0x20 */
volatile uint32_t rsv_1[2];
volatile uint32_t INT_STAT; /* Offest 0x2C */
volatile uint32_t INT_MASK; /* Offest 0x30 */
volatile uint32_t RAW_INT_STAT; /* Offest 0x34 */
volatile uint32_t RX_TL; /* Offest 0x38 */
volatile uint32_t TX_TL; /* Offest 0x3C */
volatile uint32_t CLR_INTR; /* Offest 0x40 */
volatile uint32_t CLR_RX_UNDER; /* Offest 0x44 */
volatile uint32_t CLR_RX_OVER; /* Offest 0x48 */
volatile uint32_t CLR_TX_OVER; /* Offest 0x4C */
volatile uint32_t CLR_RD_REQ; /* Offest 0x50 */
volatile uint32_t CLR_TX_ABRT; /* Offest 0x54 */
volatile uint32_t CLR_RX_DONE; /* Offest 0x58 */
volatile uint32_t CLR_ACTIVITY; /* Offest 0x5C */
volatile uint32_t CLR_STOP_DET; /* Offest 0x60 */
volatile uint32_t CLR_START_DET; /* Offest 0x64 */
volatile uint32_t rsv_2;
volatile REG_ENABLE_t ENABLE; /* Offest 0x6C */
volatile REG_STATUS_t STATUS; /* Offest 0x70 */
volatile uint32_t TXFLR; /* Offest 0x74 */
volatile uint32_t RXFLR; /* Offest 0x78 */
volatile REG_SDA_HOLD_t SDA_HOLD; /* Offest 0x7C */
volatile REG_TX_ABRT_SOURCE_t TX_ABRT_SOURCE; /* Offest 0x80 */
volatile uint32_t SLV_DATA_NACK; /* Offest 0x84 */
volatile REG_DMA_CR_t DMA_CTRL; /* Offest 0x88 */
volatile uint32_t DMATDL; /* Offest 0x8C */
volatile uint32_t DMARDL; /* Offest 0x90 */
volatile uint32_t SDA_SETUP; /* Offest 0x94 */
volatile uint32_t rsv_3[2];
volatile uint32_t FS_SPKLEN; /* Offest 0xA0 */
volatile uint32_t rsv_4;
volatile uint32_t CLR_RESTART_DET; /* Offest 0xA8 */
volatile uint32_t SCL_STUCK_LOW_TIMEOUT; /* Offest 0xAC */
volatile uint32_t SDA_STUCK_LOW_TIMEOUT; /* Offest 0xB0 */
volatile uint32_t CLR_SCL_STUCK_DET; /* Offest 0xB4 */
}struct_I2C_t;
#define I2C0 ((struct_I2C_t *)I2C0_BASE)
#define I2C1 ((struct_I2C_t *)I2C1_BASE)
#define I2C2 ((struct_I2C_t *)I2C2_BASE)
#define I2C3 ((struct_I2C_t *)I2C3_BASE)
#define I2C4 ((struct_I2C_t *)I2C4_BASE)
#define I2C5 ((struct_I2C_t *)I2C5_BASE)
/* ################################ Register Section END ################################## */
/**
* @}
*/
/** @addtogroup I2C_Initialization_Config_Section
* @{
*/
/* ################################ Initialization<6F><6E>Config Section Start ################################ */
/* interrupt index */
typedef enum
{
INT_RX_UNDER = 0x00000001,
INT_RX_OVER = 0x00000002,
INT_RX_FULL = 0x00000004,
INT_TX_OVER = 0x00000008,
INT_TX_EMPTY = 0x00000010,
INT_RD_REQ = 0x00000020,
INT_TX_ABRT = 0x00000040,
INT_RX_DONE = 0x00000080,
INT_ACTIVITY = 0x00000100,
INT_STOP_DET = 0x00000200,
INT_START_DET = 0x00000400,
INT_RESTART_DET = 0x00001000,
INT_MASTER_ON_HOLD = 0x00002000,
INT_SCL_STUCK_AT_LOW = 0x00004000,
}enum_INT_Index_t;
/* interrupt index */
typedef enum
{
CMD_WRITE = 0x0000,
CMD_READ = 0x0100,
CMD_STOP = 0x0200,
CMD_RESTART = 0x0400,
}enum_CMD_t;
/* I2C Mode */
typedef enum
{
I2C_MODE_MASTER_7BIT = 0x01,
I2C_MODE_MASTER_10BIT = 0x11,
I2C_MODE_SLAVE_7BIT = 0x00,
I2C_MODE_SLAVE_10BIT = 0x10,
I2C_MASK_MASTER = 0x01,
I2C_MASK_10BIT = 0x10,
}enum_I2C_MODE_t;
/*
* @brief I2C Init Structure definition
*/
typedef struct
{
uint32_t I2C_Mode; /* This parameter can be a value of @ref enum_I2C_MODE_t */
uint32_t SCL_HCNT; /* This parameter can be a 16-bit value. The minimum limit is 6 */
uint32_t SCL_LCNT; /* SCL high/low level hold time. The minimum limit is 8 */
uint32_t Slave_Address; /* This parameter can be a 7-bit or 10-bit address */
}struct_I2CInit_t;
/*
* @brief I2C handle Structure definition
*/
typedef struct
{
struct_I2C_t *I2Cx; /*!< I2C registers base address */
struct_I2CInit_t Init; /*!< I2C communication parameters */
volatile uint32_t u32_TxSize; /*!< I2C Transmit parameters in interrupt */
volatile uint32_t u32_TxCount;
volatile uint8_t *p_TxData;
volatile bool b_TxBusy;
volatile uint32_t u32_RxSize; /*!< I2C Receive parameters in interrupt */
volatile uint32_t u32_RxCount;
volatile uint8_t *p_RxData;
volatile bool b_RxBusy;
}I2C_HandleTypeDef;
/* ################################ Initialization<6F><6E>Config Section END ################################## */
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
#define __I2C_ENABLE(__I2Cx__) (__I2Cx__->ENABLE.ENABLE = 1)
#define __I2C_DISABLE(__I2Cx__) (__I2Cx__->ENABLE.ENABLE = 0)
/* master transfe abort */
#define __I2C_MASTER_TRAN_ABORT(__I2Cx__) (__I2Cx__->ENABLE.ABORT = 1)
/* master Block/start the transmission */
#define __I2C_MASTER_BLOCK_TRAN(__I2Cx__) (__I2Cx__->ENABLE.TX_CMD_BLOCK = 1)
#define __I2C_MASTER_START_TRAN(__I2Cx__) (__I2Cx__->ENABLE.TX_CMD_BLOCK = 0)
/* get the number of valid data in RxFIFO/TxFIFO */
#define __I2C_GET_TxFIFO_VALID_NUM(__I2Cx__) (__I2Cx__->TXFLR)
#define __I2C_GET_RxFIFO_VALID_NUM(__I2Cx__) (__I2Cx__->RXFLR)
/* Get Tx abort source */
#define __I2C_GET_TX_ABRT_SOURCE(__I2Cx__) (__I2Cx__->TX_ABRT_SOURCE.TX_ABRT_SOURCE_DWORD)
#define __I2C_IS_TX_ABRT(__I2Cx__) (__I2Cx__->RAW_INT_STAT & INT_TX_ABRT)
/* get I2C Status */
#define __I2C_IS_BUSY(__I2Cx__) (__I2Cx__->STATUS.ACTIVITY)
#define __I2C_IS_MASTER_BUSY(__I2Cx__) (__I2Cx__->STATUS.MST_ACTIVITY)
#define __I2C_IS_SLAVE_BUSY(__I2Cx__) (__I2Cx__->STATUS.SLV_ACTIVITY)
#define __I2C_IS_TxFIFO_FULL(__I2Cx__) (__I2Cx__->STATUS.TFNF == 0)
#define __I2C_IS_TxFIFO_EMPTY(__I2Cx__) (__I2Cx__->STATUS.TFE)
#define __I2C_IS_RxFIFO_FULL(__I2Cx__) (__I2Cx__->STATUS.RFF)
#define __I2C_IS_RxFIFO_EMPTY(__I2Cx__) (__I2Cx__->STATUS.RFNE == 0)
#define __I2C_IS_MST_HOLD_TX_FIFO_EMPTY(__I2Cx__) (__I2Cx__->STATUS.MST_HOLD_TX_FIFO_EMPTY)
#define __I2C_IS_MST_HOLD_RX_FIFO_FULL(__I2Cx__) (__I2Cx__->STATUS.MST_HOLD_RX_FIFO_FULL)
#define __I2C_IS_SLV_HOLD_TX_FIFO_EMPTY(__I2Cx__) (__I2Cx__->STATUS.SLV_HOLD_TX_FIFO_EMPTY)
#define __I2C_IS_SLV_HOLD_RX_FIFO_FULL(__I2Cx__) (__I2Cx__->STATUS.SLV_HOLD_RX_FIFO_FULL)
#define __I2C_IS_SDA_STUCK_NOT_RECOVERED(__I2Cx__) (__I2Cx__->STATUS.SDA_STUCK_NOT_RECOVERED)
/* RxFIFO/TxFIFO Threshold level */
#define __I2C_RxFIFO_THRESHOLD_LEVEL(__I2Cx__, __LEVEL__) (__I2Cx__->RX_TL = __LEVEL__)
#define __I2C_TxFIFO_THRESHOLD_LEVEL(__I2Cx__, __LEVEL__) (__I2Cx__->TX_TL = __LEVEL__)
/* SCL High/Low count, */
#define __I2C_SCL_HIGH_COUNT(__I2Cx__, __COUNT__) (__I2Cx__->FS_SCL_HCNT = __COUNT__)
#define __I2C_SCL_LOW_COUNT(__I2Cx__, __COUNT__) (__I2Cx__->FS_SCL_LCNT = __COUNT__)
#define __I2C_SDA_HOLD(__I2Cx__, __COUNT__) (__I2Cx__->SDA_HOLD.SDA_TX_HOLD = __COUNT__)
#define __I2C_SDA_SETUP(__I2Cx__, __COUNT__) (__I2Cx__->SDA_SETUP = __COUNT__)
/* Slave send ACK/NACK */
#define __I2C_SLAVE_SEND_NACK(__I2Cx__) (__I2Cx__->SLV_DATA_NACK = 1)
#define __I2C_SLAVE_SEND_ACK(__I2Cx__) (__I2Cx__->SLV_DATA_NACK = 0)
/* Exported functions ---------------------------------------------------------*/
/* i2c_IRQHandler */
void i2c_IRQHandler(I2C_HandleTypeDef *hi2c);
/* i2c_init */
void i2c_init(I2C_HandleTypeDef *hi2c);
/* Master transmit/receive */
bool i2c_master_transmit(I2C_HandleTypeDef *hi2c, uint16_t fu16_DevAddress, uint8_t *fp_Data, uint32_t fu32_Size);
bool i2c_master_receive(I2C_HandleTypeDef *hi2c, uint16_t fu16_DevAddress, uint8_t *fp_Data, uint32_t fu32_Size);
bool i2c_master_transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t fu16_DevAddress, uint8_t *fp_Data, uint32_t fu32_Size);
bool i2c_master_receive_IT(I2C_HandleTypeDef *hi2c, uint16_t fu16_DevAddress, uint8_t *fp_Data, uint32_t fu32_Size);
bool i2c_slave_transmit(I2C_HandleTypeDef *hi2c, uint8_t *fp_Data, uint32_t fu32_Size);
bool i2c_slave_receive(I2C_HandleTypeDef *hi2c, uint8_t *fp_Data, uint32_t fu32_Size);
bool i2c_slave_transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *fp_Data, uint32_t fu32_Size);
bool i2c_slave_receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *fp_Data, uint32_t fu32_Size);
/* memory write/read */
bool i2c_memory_write(I2C_HandleTypeDef *hi2c, uint16_t fu16_DevAddress, uint16_t fu16_MemAddress, uint8_t *fp_Data, uint32_t fu32_Size);
bool i2c_memory_read(I2C_HandleTypeDef *hi2c, uint16_t fu16_DevAddress, uint16_t fu16_MemAddress, uint8_t *fp_Data, uint32_t fu32_Size);
bool i2c_memory_is_busy(I2C_HandleTypeDef *hi2c, uint16_t fu16_DevAddress);
/* interrupt function */
void i2c_int_enable(I2C_HandleTypeDef *hi2c, enum_INT_Index_t fe_INT_Index);
void i2c_int_disable(I2C_HandleTypeDef *hi2c, enum_INT_Index_t fe_INT_Index);
bool i2c_is_int_enable(I2C_HandleTypeDef *hi2c, enum_INT_Index_t fe_INT_Index);
bool i2c_get_int_status(I2C_HandleTypeDef *hi2c, enum_INT_Index_t fe_INT_Index);
void i2c_clear_int_status(I2C_HandleTypeDef *hi2c, enum_INT_Index_t fe_INT_Index);
/* sensor write/read */
bool i2c_sensor_write(I2C_HandleTypeDef *hi2c, uint16_t fu16_DevAddress, uint32_t fu32_RegAddress, uint8_t fu8_AddressLength, uint8_t *fp_Data, uint32_t fu32_Size);
bool i2c_sensor_read(I2C_HandleTypeDef *hi2c, uint16_t fu16_DevAddress, uint32_t fu32_RegAddress, uint8_t fu8_AddressLength, uint8_t *fp_Data, uint32_t fu32_Size);
#endif

View File

@ -0,0 +1,409 @@
/*
******************************************************************************
* @file driver_i2s.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief Header file of I2S HAL module.
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_I2S_H__
#define __DRIVER_I2S_H__
#include "fr30xx.h"
/** @addtogroup I2S_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
/* I2S control 0 Register */
typedef struct
{
uint32_t MSTSLV : 1;
uint32_t LR_WD_EN : 1;
uint32_t INTEN : 1;
uint32_t LR_WD_SWAP : 1;
uint32_t RXFF_R_EN : 1;
uint32_t RXFF_L_EN : 1;
uint32_t TXFF_R_EN : 1;
uint32_t TXFF_L_EN : 1;
uint32_t RXFF_R_CLR : 1;
uint32_t RXFF_L_CLR : 1;
uint32_t TXFF_R_CLR : 1;
uint32_t TXFF_L_CLR : 1;
uint32_t rsv_0 : 4;
uint32_t SBC_ACCESS : 1;
uint32_t rsv_1 : 15;
}REG_I2S_CTRL0_t;
/* frame divder Register */
typedef struct
{
uint32_t BCLKDIV : 16;
uint32_t FRMDIV : 16;
}REG_FRM_DIV_t;
/* I2S control 1 Register */
typedef struct
{
uint32_t I2S_EN : 1;
uint32_t I2S_FRMINV : 1;
uint32_t I2S_BCLKINV : 1;
uint32_t I2S_LP : 1;
uint32_t I2S_HLSEL : 1;
uint32_t A2DP_SYNC_DISABLE : 1;
uint32_t rsv_0 : 1;
uint32_t I2S_NORMAL : 1;
uint32_t I2S_ADJUST : 1;
uint32_t I2S_LSB1ST : 1;
uint32_t rsv_1 : 2;
uint32_t I2S_DATA_LENGTH : 3;
uint32_t rsv_2 : 1;
uint32_t I2SFBOFF : 16;
}REG_I2S_CTRL1_t;
/* FIFO config right Register */
typedef struct
{
uint32_t TXFF_AEMPTY : 8;
uint32_t TXFF_AFULL : 8;
uint32_t RXFF_AEMPTY : 8;
uint32_t RXFF_AFULL : 8;
}REG_FIFO_CFG_t;
/* DMA config Register */
typedef struct
{
uint32_t DMACR_L_TX : 1;
uint32_t DMACR_R_TX : 1;
uint32_t DMACR_L_RX : 1;
uint32_t DMACR_R_RX : 1;
uint32_t rsv_0 : 4;
uint32_t DMARDLR : 5;
uint32_t rsv_1 : 3;
uint32_t DMATDLR : 5;
uint32_t rsv_2 : 11;
}REG_I2S_DMA_CFG_t;
/* PCM general Register */
typedef struct
{
uint32_t PCM_EN : 1;
uint32_t PCM_LRSWAP : 1;
uint32_t PCM_BYTESWAP : 1;
uint32_t PCM_PLL_EN : 1;
uint32_t PCM_MONO_STEREO : 1;
uint32_t PCM_MONO_LR_SEL : 1;
uint32_t PCM_LOOPBACK : 1;
uint32_t PCM_CLKINV : 1;
uint32_t PCM_SLVBFMST : 1;
uint32_t PCM_SET_FRAME : 1;
uint32_t rsv_0 : 22;
}REG_PCM_GENCTRL_t;
/* PCM PHY CTRL Register */
typedef struct
{
uint32_t PCM_FSYNCSHP : 3;
uint32_t rsv_0 : 1;
uint32_t PCM_DOUTCFG : 2;
uint32_t rsv_1 : 2;
uint32_t PCM_LRCHPOL : 1;
uint32_t PCM_IOM : 1;
uint32_t PCM_LSB1ST : 1;
uint32_t rsv_2 : 1;
uint32_t PCM_SAMPSZ : 1;
uint32_t PCM_SAMPTYPE : 1;
uint32_t rsv_3 : 2;
uint32_t PCM_SLOTNB : 3;
uint32_t rsv_4 : 1;
uint32_t PCM_FIRSTACTSLOT : 2;
uint32_t rsv_5 : 10;
}REG_PCM_PHYCTRL_t;
/* PCM PHY CTRL Register */
typedef struct
{
uint32_t PCM_LSAMPPAD : 16;
uint32_t PCM_RSAMPPAD : 16;
}REG_PCM_PADDING_t;
/* PCM MUTE Register */
typedef struct
{
uint32_t PCM_MUTE_PATT : 16;
uint32_t rsv_0 : 15;
uint32_t PCM_MUTE_EN : 1;
}REG_PCM_MUTE_t;
/* -----------------------------------------------*/
/* I2S Register */
/* -----------------------------------------------*/
typedef struct
{
volatile REG_I2S_CTRL0_t CTRL0; /* Offset 0x00 */
volatile REG_FRM_DIV_t FrmDiv; /* Offset 0x04 */
volatile REG_I2S_CTRL1_t CTRL1; /* Offset 0x08 */
volatile uint32_t DATA_L; /* Offset 0x0C */
volatile uint32_t DATA_R; /* Offset 0x10 */
volatile uint32_t INT_STATUS; /* Offset 0x14 */
volatile uint32_t INT_STATUS_EN; /* Offset 0x18 */
volatile REG_FIFO_CFG_t FIFO_CFG_L; /* Offset 0x1C */
volatile REG_FIFO_CFG_t FIFO_CFG_R; /* Offset 0x20 */
volatile REG_I2S_DMA_CFG_t DMA_CFG; /* Offset 0x24 */
volatile REG_PCM_GENCTRL_t PCM_GENCTRL; /* Offset 0x28 */
volatile REG_PCM_PHYCTRL_t PCM_RHYCTRL; /* Offset 0x2C */
volatile REG_PCM_PADDING_t PCM_PADDING; /* Offset 0x30 */
volatile REG_PCM_MUTE_t PCM_MUTE; /* Offset 0x34 */
}struct_I2S_t;
#define I2S0 ((struct_I2S_t *)I2S0_BASE)
#define I2S1 ((struct_I2S_t *)I2S1_BASE)
#define I2S2 ((struct_I2S_t *)I2S2_BASE)
/* ################################ Register Section END ################################## */
/**
* @}
*/
/** @addtogroup I2S_Initialization_Config_Section
* @{
*/
/* ################################ Initialization<6F><6E>Config Section Start ################################ */
#define I2S_FIFO_DEPTH (32)
#define I2S_FIFO_HALF_DEPTH (I2S_FIFO_DEPTH >> 1)
/* FIFO Status start */
#define I2S_RX_FIFOS_FULL (0x00001)
#define I2S_RX_FIFOS_HALF_FULL (0x00002)
#define I2S_RX_FIFOS_EMPTY (0x00004)
#define I2S_RX_L_FIFO_FULL (0x00008)
#define I2S_RX_L_FIFO_HALF_FULL (0x00010)
#define I2S_RX_L_FIFO_EMPTY (0x00020)
#define I2S_RX_R_FIFO_FULL (0x00040)
#define I2S_RX_R_FIFO_HALF_FULL (0x00080)
#define I2S_RX_R_FIFO_EMPTY (0x00100)
#define I2S_TX_FIFOS_FULL (0x00200)
#define I2S_TX_FIFOS_ALMOST_EMPTY (0x00400)
#define I2S_TX_FIFOS_EMPTY (0x00800)
#define I2S_TX_L_FIFO_FULL (0x01000)
#define I2S_TX_L_FIFO_ALMOST_EMPTY (0x02000)
#define I2S_TX_L_FIFO_EMPTY (0x04000)
#define I2S_TX_R_FIFO_FULL (0x08000)
#define I2S_TX_R_FIFO_ALMOST_EMPTY (0x10000)
#define I2S_TX_R_FIFO_EMPTY (0x20000)
#define I2S_ALL_FIFO_STATUS (0x3FFFF)
/* FIFO Status end */
/* I2S Mode */
typedef enum
{
I2S_MODE_MASTER,
I2S_MODE_SLAVE,
}enum_I2S_Mode_t;
/* I2S Standard */
typedef enum
{
I2S_STANDARD_PHILIPS,
I2S_STANDARD_MSB,
I2S_STANDARD_LSB,
I2S_STANDARD_PCM,
}enum_I2S_Standard_t;
/* I2S Data Format */
typedef enum
{
I2S_DATA_FORMAT_8BIT,
I2S_DATA_FORMAT_16BIT,
I2S_DATA_FORMAT_20BIT,
I2S_DATA_FORMAT_24BIT,
I2S_DATA_FORMAT_32BIT,
}enum_I2S_DataFormat_t;
/* I2S Audio Frequency */
typedef enum
{
I2S_AUDIOFREQ_192000,
I2S_AUDIOFREQ_96000,
I2S_AUDIOFREQ_48000,
I2S_AUDIOFREQ_44100,
I2S_AUDIOFREQ_32000,
I2S_AUDIOFREQ_22050,
I2S_AUDIOFREQ_16000,
I2S_AUDIOFREQ_11025,
I2S_AUDIOFREQ_8000,
}enum_I2S_Audio_Frequency_t;
/*
* @brief I2S Init Structure definition
*/
typedef struct
{
uint32_t Mode; /*!< Specifies the I2S operating mode.
This parameter can be a value of @ref enum_I2S_Mode_t */
uint32_t Standard; /*!< Specifies the communication standard.
This parameter can be a value of @ref enum_I2S_Standard_t */
uint32_t DataFormat; /*!< Specifies the data format.
This parameter can be a value of @ref enum_I2S_DataFormat_t */
uint32_t BCLKDIV; /*!< Specifies the clock dividor used to generate bclk.
This parameter can be a even value of between 0x000 ~ 0xFFF. */
uint32_t ChannelLength; /*!< Specifies the channel length.
This parameter can be a even value of between 0x000 ~ 0xFFF. */
uint32_t AudioFreq; /*!< Specifies the frequency selected for the I2S communication.
This parameter can be a value of @ref I2S_Audio_Frequency */
}struct_I2SInit_t;
/*
* @brief PCM Init Structure definition
*/
typedef struct
{
#if defined(__ICCARM__)
uint32_t dummy; /* used to avoid compile error in IAR */
#endif
}struct_PCMInit_t;
/*
* @brief I2S handle Structure definition
*/
typedef struct __I2S_HandleTypeDef
{
struct_I2S_t *I2Sx; /*!< I2S registers base address */
struct_I2SInit_t Init; /*!< I2S communication parameters */
struct_PCMInit_t PCM_Init; /*!< PCM communication parameters */
volatile bool b_TxBusy;
void (*TxIntCallback)(struct __I2S_HandleTypeDef *hi2s); /*!< Tx Interrupt Callback */
volatile bool b_RxBusy;
void (*RxIntCallback)(struct __I2S_HandleTypeDef *hi2s); /*!< Rx Interrupt Callback */
}I2S_HandleTypeDef;
/* ################################ Initialization<6F><6E>Config Section END ################################## */
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
/* I2s and PCM Enable/Disable */
#define __I2S_ENABLE(__I2Sx__) (__I2Sx__->CTRL1.I2S_EN = 1)
#define __I2S_DISABLE(__I2Sx__) (__I2Sx__->CTRL1.I2S_EN = 0)
#define __I2S_PCM_ENABLE(__I2Sx__) do{ __I2Sx__->PCM_GENCTRL.PCM_PLL_EN = 1; \
__I2Sx__->PCM_GENCTRL.PCM_EN = 1;}while(0)
#define __I2S_PCM_DISABLE(__I2Sx__) do{ __I2Sx__->PCM_GENCTRL.PCM_PLL_EN = 0; \
__I2Sx__->PCM_GENCTRL.PCM_EN = 0;}while(0)
/* RxFIFO/TxFIFO clear */
#define __I2S_TxFIFO_CLR(__I2Sx__) do{ __I2Sx__->CTRL0.TXFF_R_CLR = 1; \
__I2Sx__->CTRL0.TXFF_L_CLR = 1;}while(0)
#define __I2S_RxFIFO_CLR(__I2Sx__) do{ __I2Sx__->CTRL0.RXFF_R_CLR = 1; \
__I2Sx__->CTRL0.RXFF_L_CLR = 1;}while(0)
/* TxFIFO/RxFIFO enable */
#define __I2S_TxFIFO_EN(__I2Sx__) do{ __I2Sx__->CTRL0.TXFF_L_EN = 1; \
__I2Sx__->CTRL0.TXFF_R_EN = 1; }while(0)
#define __I2S_RxFIFO_EN(__I2Sx__) do{ __I2Sx__->CTRL0.RXFF_L_EN = 1; \
__I2Sx__->CTRL0.RXFF_R_EN = 1;}while(0)
/* TxFIFO Data from sbcdecode or cpu*/
#define __I2S_TXFIFO_SOURCE_SBC_DECODE(__I2Sx__) (__I2Sx__->CTRL0.SBC_ACCESS = 1)
#define __I2S_TXFIFO_SOURCE_CPU(__I2Sx__) (__I2Sx__->CTRL0.SBC_ACCESS = 0)
/* enable channels Operate Simultaneously*/
#define __I2S_LR_WD_ENABLE(__I2Sx__) (__I2Sx__->CTRL0.LR_WD_EN = 1)
#define __I2S_LR_WD_DISABLE(__I2Sx__) (__I2Sx__->CTRL0.LR_WD_EN = 0)
#define __I2S_WD_SWAP_HIGH16SIZE_RIGHT(__I2Sx__) (__I2Sx__->CTRL0.LR_WD_SWAP = 1)
#define __I2S_WD_SWAP_HIGH16SIZE_LEFT(__I2Sx__) (__I2Sx__->CTRL0.LR_WD_SWAP = 0)
/* Status interrupt enable and disable */
#define __I2S_INT_ENABLE(__I2Sx__, __STATUS__) do{ __I2Sx__->CTRL0.INTEN = 1; \
__I2Sx__->INT_STATUS_EN |= __STATUS__;}while(0)
#define __I2S_INT_DISABLE(__I2Sx__, __STATUS__) do{ __I2Sx__->CTRL0.INTEN = 0; \
__I2Sx__->INT_STATUS_EN &= ~__STATUS__;}while(0)
#define __I2S_INT_IS_ENANLE(__I2Sx__, __STATUS__) (__I2Sx__->INT_STATUS_EN & __STATUS__)
/* Get interrupt status */
#define __I2S_GET_INT_STATUS(__I2Sx__) (__I2Sx__->INT_STATUS)
/* Left/Right Rxfifo txfifo full/empty level */
#define __I2S_L_RxFIFO_FULL_LEVEL(__I2Sx__, __LEVEL__) (__I2Sx__->FIFO_CFG_L.RXFF_AFULL = __LEVEL__)
#define __I2S_L_RxFIFO_EMPTY_LEVEL(__I2Sx__, __LEVEL__) (__I2Sx__->FIFO_CFG_L.RXFF_AEMPTY = __LEVEL__)
#define __I2S_L_TxFIFO_FULL_LEVEL(__I2Sx__, __LEVEL__) (__I2Sx__->FIFO_CFG_L.TXFF_AFULL = __LEVEL__)
#define __I2S_L_TxFIFO_EMPTY_LEVEL(__I2Sx__, __LEVEL__) (__I2Sx__->FIFO_CFG_L.TXFF_AEMPTY = __LEVEL__)
#define __I2S_R_RxFIFO_FULL_LEVEL(__I2Sx__, __LEVEL__) (__I2Sx__->FIFO_CFG_R.RXFF_AFULL = __LEVEL__)
#define __I2S_R_RxFIFO_EMPTY_LEVEL(__I2Sx__, __LEVEL__) (__I2Sx__->FIFO_CFG_R.RXFF_AEMPTY = __LEVEL__)
#define __I2S_R_TxFIFO_FULL_LEVEL(__I2Sx__, __LEVEL__) (__I2Sx__->FIFO_CFG_R.TXFF_AFULL = __LEVEL__)
#define __I2S_R_TxFIFO_EMPTY_LEVEL(__I2Sx__, __LEVEL__) (__I2Sx__->FIFO_CFG_R.TXFF_AEMPTY = __LEVEL__)
/* BCLK Inverted Output */
#define __I2S_BCLK_INV_ENABLE(__I2Sx__) (__I2Sx__->CTRL1.I2S_BCLKINV = 1)
#define __I2S_BCLK_INV_DISABLE(__I2Sx__) (__I2Sx__->CTRL1.I2S_BCLKINV = 0)
/* Frame Inverted Output */
#define __I2S_FRAME_INV_ENABLE(__I2Sx__) (__I2Sx__->CTRL1.I2S_FRMINV = 1)
#define __I2S_FRAME_INV_DISABLE(__I2Sx__) (__I2Sx__->CTRL1.I2S_FRMINV = 0)
/* PCMCLK Inverted Output */
#define __I2S_PCMCLK_INV_ENABLE(__I2Sx__) (__I2Sx__->PCM_GENCTRL.PCM_CLKINV = 1)
#define __I2S_PCMCLK_INV_DISABLE(__I2Sx__) (__I2Sx__->PCM_GENCTRL.PCM_CLKINV = 0)
/* PCM SLOTS SET */
#define __I2S_PCM_SLOTS_SET(__I2Sx__, __LEVEL__) (__I2Sx__->PCM_RHYCTRL.PCM_SLOTNB = __LEVEL__)
#define __I2S_PCM_FIRSTSLOTS_SET(__I2Sx__, __CONFIGURE__) (__I2Sx__->PCM_RHYCTRL.PCM_FIRSTACTSLOT = __CONFIGURE__)
/* PCM SAMPLE SIZE SELECT */
#define __I2S_PCM_SAMPLESIZE_8BIT(__I2Sx__) (__I2Sx__->PCM_RHYCTRL.PCM_SAMPSZ = 0)
#define __I2S_PCM_SAMPLESIZE_16BIT(__I2Sx__) (__I2Sx__->PCM_RHYCTRL.PCM_SAMPSZ = 1)
/* DMA Request Level */
#define __I2S_TX_DMA_EMPTY_LEVEL(__I2Sx__, __LEVEL__) (__I2Sx__->DMA_CFG.DMATDLR = __LEVEL__)
#define __I2S_RX_DMA_EMPTY_LEVEL(__I2Sx__, __LEVEL__) (__I2Sx__->DMA_CFG.DMARDLR = __LEVEL__)
/* Exported functions --------------------------------------------------------*/
/* i2s_init */
void i2s_init(I2S_HandleTypeDef *hi2s);
/* i2s_init */
void i2s_deinit(I2S_HandleTypeDef *hi2s);
/* i2s_transmit_IT */
bool i2s_transmit_IT(I2S_HandleTypeDef *hi2s);
/* i2s_receive_IT */
bool i2s_receive_IT(I2S_HandleTypeDef *hi2s);
/* i2s_IRQHandler */
void i2s_IRQHandler(I2S_HandleTypeDef *hi2s);
/* i2s_read_data */
uint32_t i2s_read_data(I2S_HandleTypeDef *hi2s, uint32_t *buffer, uint32_t samples);
/* i2s_send_data */
uint32_t i2s_send_data(I2S_HandleTypeDef *hi2s, uint32_t *buffer, uint32_t samples);
/* i2s_transmit_DMA */
void i2s_transmit_DMA(I2S_HandleTypeDef *hi2s);
/* i2s_receive_DMA */
void i2s_receive_DMA(I2S_HandleTypeDef *hi2s);
#endif

View File

@ -0,0 +1,152 @@
/*
******************************************************************************
* @file driver_iir.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2022
* @brief Header file of IIR module.
******************************************************************************
* @attention
*
* Copyright (c) 2023 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_IIR_H__
#define __DRIVER_IIR_H__
#include "fr30xx.h"
/** @addtogroup IIR_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
/* IIR CTRL */
typedef struct
{
uint32_t N_DIV : 7;
uint32_t rsv_0 : 1;
uint32_t ORDER_SEL : 2;
uint32_t rsv_1 : 6;
uint32_t NODE_SEL : 2;
uint32_t rsv_2 : 6;
uint32_t NBYTE_SEL : 2;
uint32_t ESV4 : 6;
} REG_IIR_CTRL_t;
/* IIR THR FIFO */
typedef struct
{
uint32_t THR_TX_FIFO : 6;
uint32_t rsv_0 : 10;
uint32_t THR_RX_FIFO : 6;
uint32_t rsv_1 : 10;
} REG_IIR_THR_FIFO_t;
typedef struct
{
volatile uint32_t IIR_COEF[20]; /* Offser 0x00-0x4c*/
volatile REG_IIR_CTRL_t IIR_CTRL; /* Offset 0x50*/
volatile REG_IIR_THR_FIFO_t IIR_THR_FIFO; /* Offset 0x54*/
volatile uint32_t rsv_0;
volatile uint32_t rsv_1;
volatile uint32_t IIR_SOFTRST; /* Offset 0x60*/
volatile uint32_t rsv_2[5];
volatile uint32_t IIR_STATUS; /* Offset 0x78*/
volatile uint32_t rsv_3;
volatile uint32_t IIR_FIFO; /* Offset 0x80*/
}struct_IIR_t;
#define IIR_FILTER ((struct_IIR_t *)IIR_BASE)
/* ################################ Register Section END ################################## */
/**
* @}
*/
/** @addtogroup IIR_Initialization_Config_Section
* @{
*/
/* ################################ Initialization_Config Section Start ################################ */
/* FIFO Status */
typedef enum
{
TX_FIFO_FULL = 0x01,
TX_FIFO_EMPTY = 0x02,
TX_FIFO_AL_EMPTY = 0x04,
RX_FIFO_FULL = 0x08,
RX_FIFO_EMPTY = 0x10,
RX_FIFO_AL_FULL = 0x20,
}enum_IIR_INT_Index_t;
/* Nbytes Select */
typedef enum{
IIR_BYTE_1,
IIR_BYTE_2,
IIR_BYTE_3,
IIR_BYTE_ALL,
}enum_Nbytes_sel_t;
/* Node Select */
typedef enum{
THE_FIRST_STAGE_OUTPUT,
THE_SENCOND_STAGE_OUTPUT,
THE_THIRD_STAGE_OUTPUT,
THE_FOURTH_STAGE_OUTPUT,
}enum_Node_Sel_t;
/* Order Select */
typedef enum{
ORDER_2,
ORDER_4,
ORDER_6,
ORDER_8,
}enum_Order_Sel_t;
typedef struct
{
uint32_t IIRCoef[20]; /*!< Specifies the internal Feedback coefficient.
This parameter The value can be a value 0~0xFFFFFF*/
uint8_t N_Div; /*!< Specifies the internal read/write tx and rx FIFO is relative The frequency division factor of the system clock.
This parameter The value should be greater than 2*(order_sel + 1)*5 */
uint8_t Order_Sel; /*!< Specifies the internal Filter order configuration.
This parameter can be a value of @ref enum_Order_Sel_t */
uint8_t Node_Sel; /*!< Specifies the internal Filter order configuration.
This parameter can be a value of @ref enum_Node_Sel_t */
uint8_t Nbytes_Sel; /*!< Specifies the internal Filter order configuration.
This parameter can be a value of @ref enum_Nbytes_sel_t */
}IIR_InitTypeDef;
/* ################################ Initialization_Config Section END ################################## */
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
/* RxFIFO/TxFIFO Threshold level */
#define __IIR_RxFIFO_THRESHOLD_LEVEL(__LEVEL__) (IIR_FILTER->IIR_THR_FIFO.THR_RX_FIFO = __LEVEL__)
#define __IIR_TxFIFO_THRESHOLD_LEVEL(__LEVEL__) (IIR_FILTER->IIR_THR_FIFO.THR_TX_FIFO = __LEVEL__)
/* SOFTRST Set and Clear */
#define __IIR_SOFTRST_SET() (IIR_FILTER->IIR_SOFTRST = 0)
#define __IIR_SOFTRST_CLEAR() (IIR_FILTER->IIR_SOFTRST = 1)
/* Get FIFO status */
#define __IIR_GET_FIFO_STATUS(__STATUS__) (IIR_FILTER->IIR_STATUS & __STATUS__)
/* Exported functions ---------------------------------------------------------*/
/* iir_init */
void iir_init(IIR_InitTypeDef *hiir);
/* iir_filter_start */
void iir_filter_start(uint32_t *fp_Data_In, uint32_t *fp_Data_Out, uint32_t fu32_Size);
#endif

View File

@ -0,0 +1,936 @@
/**
* Copyright (c) 2019, Freqchip
*
* All rights reserved.
*
*
*/
#ifndef DRIVER_IOMUX_H
#define DRIVER_IOMUX_H
/**********************************************************************************************************************************
PX/MUX 4'h0 4'h1 4'h2 4'h3 4'h4 4'h5 4'h6 4'h7 4'h8 4'ha
PORTA0 gpio_a0 I2C0_CLK I2S_CLK PWM0 SSP0_CLK UART0_RXD UART1_RXD CLK_OUT PDM_CLK
PORTA1 gpio_a1 I2C0_DAT I2S_FRM PWM1 SSP0_CSN UART0_TXD UART1_TXD ant_ctl[0] PDM_DATA
PORTA2 gpio_a2 I2C1_CLK I2S_DOUT PWM2 SSP0_DOUT UART0_RXD UART1_RXD ant_ctl[0] PDM_CLK
PORTA3 gpio_a3 I2C1_DAT I2S_DIN PWM3 SSP0_DIN UART0_TXD UART1_TXD ant_ctl[1] PDM_DATA
PORTA4 gpio_a4 I2C0_CLK I2S_CLK PWM4 SSP0_CLK UART0_RXD UART1_RXD CLK_OUT PDM_CLK
PORTA5 gpio_a5 I2C0_DAT I2S_FRM PWM5 SSP0_CSN UART0_TXD UART1_TXD ant_ctl[1] PDM_DATA
PORTA6 gpio_a6 I2C1_CLK I2S_DOUT PWM0 SSP0_DOUT UART0_RXD UART1_RXD CLK_OUT PDM_CLK
PORTA7 gpio_a7 I2C1_DAT I2S_DIN PWM1 SSP0_DIN UART0_TXD UART1_TXD ant_ctl[0] PDM_DATA
PORTB0 gpio_b0 I2C0_CLK I2S_CLK PWM0 SSP0_CLK UART0_RXD UART1_RXD ble_tx PDM_CLK
PORTB1 gpio_b1 I2C0_DAT I2S_FRM PWM1 SSP0_CSN UART0_TXD UART1_TXD ble_rx PDM_DATA
PORTB2 gpio_b2 I2C1_CLK I2S_DOUT PWM2 SSP0_DOUT UART0_RXD UART1_RXD wlan_tx/in PDM_CLK
PORTB3 gpio_b3 I2C1_DAT I2S_DIN PWM3 SSP0_DIN UART0_TXD UART1_TXD wlan_rx/in PDM_DATA
PORTB4 gpio_b4 I2C0_CLK I2S_CLK PWM4 SSP0_CLK UART0_RXD UART1_RXD CLK_OUT PDM_CLK
PORTB5 gpio_b5 I2C0_DAT I2S_FRM PWM5 SSP0_CSN UART0_TXD UART1_TXD ant_ctl[0] PDM_DATA
PORTB6 gpio_b6 I2C1_CLK I2S_DOUT PWM2 SSP0_DOUT UART0_RXD UART1_RXD ant_ctl[1] PDM_CLK
PORTB7 gpio_b7 I2C1_DAT I2S_DIN PWM3 SSP0_DIN UART0_TXD UART1_TXD CLK_OUT PDM_DATA
PORTC0 gpio_c0 I2C0_CLK I2S_CLK PWM0 SSP0_CLK UART0_RXD UART1_RXD SWV PDM_CLK
PORTC1 gpio_c1 I2C0_DAT I2S_FRM PWM1 SSP0_CSN UART0_TXD UART1_TXD SWV PDM_DATA
PORTC2 gpio_c2 I2C1_CLK I2S_DOUT PWM2 SSP0_DOUT UART0_RXD UART1_RXD SWV PDM_CLK
PORTC3 gpio_c3 I2C1_DAT I2S_DIN PWM3 SSP0_DIN UART0_TXD UART1_TXD SWV PDM_DATA
PORTC4 gpio_c4 I2C0_CLK I2S_CLK PWM4 SSP0_CLK UART0_RXD UART1_RXD ant_ctl[1] PDM_CLK
PORTC5 gpio_c5 I2C0_DAT I2S_FRM PWM5 SSP0_CSN UART0_TXD UART1_TXD SWV PDM_DATA
PORTC6 gpio_c6 I2C1_CLK I2S_DOUT PWM4 SSP0_DOUT UART0_RXD UART1_RXD SW_TCK PDM_CLK
PORTC7 gpio_c7 I2C1_DAT I2S_DIN PWM5 SSP0_DIN UART0_TXD UART1_TXD SW_DIO PDM_DATA
PORTD0 gpio_d0 I2C0_CLK I2S_CLK PWM0 SSP0_CLK UART0_RXD UART1_RXD ble_tx PDM_CLK
PORTD1 gpio_d1 I2C0_DAT I2S_FRM PWM1 SSP0_CSN UART0_TXD UART1_TXD ble_rx PDM_DATA
PORTD2 gpio_d2 I2C1_CLK I2S_DOUT PWM2 SSP0_DOUT UART0_RXD UART1_RXD wlan_tx/in PDM_CLK
PORTD3 gpio_d3 I2C1_DAT I2S_DIN PWM3 SSP0_DIN UART0_TXD UART1_TXD wlan_rx/in PDM_DATA
PORTD4 gpio_d4 I2C0_CLK I2S_CLK PWM4 SSP0_CLK UART0_RXD UART1_RXD ant_ctl[0] PDM_CLK ADC0
PORTD5 gpio_d5 I2C0_DAT I2S_FRM PWM5 SSP0_CSN UART0_TXD UART1_TXD ant_ctl[0] PDM_DATA ADC1
PORTD6 gpio_d6 I2C1_CLK I2S_DOUT PWM0 SSP0_DOUT UART0_RXD UART1_RXD CLK_OUT PDM_CLK ADC2
PORTD7 gpio_d7 I2C1_DAT I2S_DIN PWM1 SSP0_DIN UART0_TXD UART1_TXD ant_ctl[1] PDM_DATA ADC3
*************************************************************************************************************************************/
#if 1
#define PORTA0_FUNC_A0 0x00
#define PORTA0_FUNC_CM0_A0 0x01
#define PORTA0_FUNC_CM0_UART_RXD 0x02
#define PORTA0_FUNC_UART0_RXD 0x03
#define PORTA0_FUNC_SPIM0_CLK 0x04
#define PORTA0_FUNC_SPIS0_CLK 0x05
#define PORTA0_FUNC_PDM0_CLK 0x06
#define PORTA0_FUNC_I2C0_CLK 0x07
#define PORTA0_FUNC_PWM0 0x08
#define PORTA0_FUNC_TIM0_PAUSE 0x09
#define PORTA1_FUNC_A1 0x00
#define PORTA1_FUNC_CM0_A1 0x01
#define PORTA1_FUNC_CM0_UART_TXD 0x02
#define PORTA1_FUNC_UART0_TXD 0x03
#define PORTA1_FUNC_SPIM0_CSN 0x04
#define PORTA1_FUNC_SPIS0_CSN 0x05
#define PORTA1_FUNC_PDM0_SDA 0x06
#define PORTA1_FUNC_I2C0_SDA 0x07
#define PORTA1_FUNC_PWM1 0x08
#define PORTA1_FUNC_TIM1_PAUSE 0x09
#define PORTA2_FUNC_A2 0x00
#define PORTA2_FUNC_CM0_A2 0x01
#define PORTA2_FUNC_CM0_I2C_CLK 0x02
#define PORTA2_FUNC_UART2_RXD 0x03
#define PORTA2_FUNC_SPIM0_MOSI 0x04
#define PORTA2_FUNC_SPIS0_MOSI 0x05
#define PORTA2_FUNC_PDM1_CLK 0x06
#define PORTA2_FUNC_I2C1_CLK 0x07
#define PORTA2_FUNC_PWM2 0x08
#define PORTA2_FUNC_TIM0_TOG 0x09
#define PORTA2_FUNC_SPIM8_0_IO0 0x0A
#define PORTA3_FUNC_A3 0x00
#define PORTA3_FUNC_CM0_A3 0x01
#define PORTA3_FUNC_CM0_I2C_SDA 0x02
#define PORTA3_FUNC_UART2_TXD 0x03
#define PORTA3_FUNC_SPIM0_MISO 0x04
#define PORTA3_FUNC_SPIS0_MISO 0x05
#define PORTA3_FUNC_PDM1_SDA 0x06
#define PORTA3_FUNC_I2C1_SDA 0x07
#define PORTA3_FUNC_PWM3 0x08
#define PORTA3_FUNC_TIM1_TOG 0x09
#define PORTA3_FUNC_SPIM8_0_IO1 0x0A
#define PORTA4_FUNC_A4 0x00
#define PORTA4_FUNC_CM0_A0 0x01
#define PORTA4_FUNC_CM0_SPI_CLK 0x02
#define PORTA4_FUNC_UART2_CTS 0x03
#define PORTA4_FUNC_SPIM1_CLK 0x04
#define PORTA4_FUNC_SPIS1_CLK 0x05
#define PORTA4_FUNC_PDM0_CLK 0x06
#define PORTA4_FUNC_I2C0_CLK 0x07
#define PORTA4_FUNC_PWM4 0x08
#define PORTA4_FUNC_TIM0_PAUSE 0x09
#define PORTA4_FUNC_SPIM8_0_IO2 0x0A
#define PORTA5_FUNC_A5 0x00
#define PORTA5_FUNC_CM0_A1 0x01
#define PORTA5_FUNC_CM0_SPI_CSN 0x02
#define PORTA5_FUNC_UART2_RTS 0x03
#define PORTA5_FUNC_SPIM1_CSN 0x04
#define PORTA5_FUNC_SPIS1_FRM 0x05
#define PORTA5_FUNC_PDM0_SDA 0x06
#define PORTA5_FUNC_I2C0_SDA 0x07
#define PORTA5_FUNC_PWM5 0x08
#define PORTA5_FUNC_TIM1_PAUSE 0x09
#define PORTA5_FUNC_SPIM8_0_IO3 0x0A
#define PORTA6_FUNC_A6 0x00
#define PORTA6_FUNC_CM0_A2 0x01
#define PORTA6_FUNC_CM0_SPI_MOSI 0x02
#define PORTA6_FUNC_UART0_RXD 0x03
#define PORTA6_FUNC_SPIM1_MOSI 0x04
#define PORTA6_FUNC_SPIS1_MOSI 0x05
#define PORTA6_FUNC_PDM1_CLK 0x06
#define PORTA6_FUNC_I2C1_CLK 0x07
#define PORTA6_FUNC_PWM6 0x08
#define PORTA6_FUNC_TIM0_TOG 0x09
#define PORTA6_FUNC_SPIM8_0_CLK 0x0A
#define PORTA7_FUNC_A7 0x00
#define PORTA7_FUNC_CM0_A3 0x01
#define PORTA7_FUNC_CM0_SPI_MIS0 0x02
#define PORTA7_FUNC_UART0_TXD 0x03
#define PORTA7_FUNC_SPIM1_MISO 0x04
#define PORTA7_FUNC_SPIS1_MISO 0x05
#define PORTA7_FUNC_PDM1_SDA 0x06
#define PORTA7_FUNC_I2C1_SDA 0x07
#define PORTA7_FUNC_PWM7 0x08
#define PORTA7_FUNC_TIM1_TOG 0x09
#define PORTA7_FUNC_SPIM8_0_CSN 0x0A
#define PORTB0_FUNC_B0 0x00
#define PORTB0_FUNC_CM0_A0 0x01
#define PORTB0_FUNC_CM0_UART_RXD 0x02
#define PORTB0_FUNC_UART0_RXD 0x03
#define PORTB0_FUNC_SPIM1_CLK 0x04
#define PORTB0_FUNC_SPIS1_CLK 0x05
#define PORTB0_FUNC_PDM0_CLK 0x06
#define PORTB0_FUNC_I2C0_CLK 0x07
#define PORTB0_FUNC_PWM0 0x08
#define PORTB0_FUNC_TIM0_PAUSE 0x09
#define PORTB0_FUNC_SPIM8_0_IO0 0x0A
#define PORTB0_FUNC_PSRAM_QSPI_MIO0 0x0B
#define PORTB1_FUNC_B1 0x00
#define PORTB1_FUNC_CM0_A1 0x01
#define PORTB1_FUNC_CM0_UART_TXD 0x02
#define PORTB1_FUNC_UART0_TXD 0x03
#define PORTB1_FUNC_SPIM1_CSN 0x04
#define PORTB1_FUNC_SPIS1_FRM 0x05
#define PORTB1_FUNC_PDM0_SDA 0x06
#define PORTB1_FUNC_I2C0_SDA 0x07
#define PORTB1_FUNC_PWM1 0x08
#define PORTB1_FUNC_TIM1_PAUSE 0x09
#define PORTB1_FUNC_SPIM8_0_IO1 0x0A
#define PORTB1_FUNC_PSRAM_QSPI_MIO1 0x0B
#define PORTB2_FUNC_B2 0x00
#define PORTB2_FUNC_CM0_A2 0x01
#define PORTB2_FUNC_CM0_I2C_CLK 0x02
#define PORTB2_FUNC_UART2_RXD 0x03
#define PORTB2_FUNC_SPIM1_MOSI 0x04
#define PORTB2_FUNC_SPIS1_MOSI 0x05
#define PORTB2_FUNC_PDM1_CLK 0x06
#define PORTB2_FUNC_I2C1_CLK 0x07
#define PORTB2_FUNC_PWM2 0x08
#define PORTB2_FUNC_TIM0_TOG 0x09
#define PORTB2_FUNC_SPIM8_0_IO2 0x0A
#define PORTB2_FUNC_PSRAM_QSPI_MIO2 0x0B
#define PORTB3_FUNC_B3 0x00
#define PORTB3_FUNC_CM0_A3 0x01
#define PORTB3_FUNC_CM0_I2C_SDA 0x02
#define PORTB3_FUNC_UART2_TXD 0x03
#define PORTB3_FUNC_SPIM1_MISO 0x04
#define PORTB3_FUNC_SPIS1_MISO 0x05
#define PORTB3_FUNC_PDM1_SDA 0x06
#define PORTB3_FUNC_I2C1_SDA 0x07
#define PORTB3_FUNC_PWM3 0x08
#define PORTB3_FUNC_TIM1_TOG 0x09
#define PORTB3_FUNC_SPIM8_0_IO3 0x0A
#define PORTB3_FUNC_PSRAM_QSPI_MIO3 0x0B
#define PORTB4_FUNC_B4 0x00
#define PORTB4_FUNC_CM0_A0 0x01
#define PORTB4_FUNC_CM0_SPI_CLK 0x02
#define PORTB4_FUNC_UART2_CTS 0x03
#define PORTB4_FUNC_SPIM0_CLK 0x04
#define PORTB4_FUNC_SPIS0_CLK 0x05
#define PORTB4_FUNC_PDM0_CLK 0x06
#define PORTB4_FUNC_I2C0_CLK 0x07
#define PORTB4_FUNC_PWM4 0x08
#define PORTB4_FUNC_TIM1_PAUSE 0x09
#define PORTB4_FUNC_SPIM8_0_IO4 0x0A
#define PORTB4_FUNC_PSRAM_QSPI_MIO4 0x0B
#define PORTB5_FUNC_B5 0x00
#define PORTB5_FUNC_CM0_A1 0x01
#define PORTB5_FUNC_CM0_SPI_CSN 0x02
#define PORTB5_FUNC_UART2_RTS 0x03
#define PORTB5_FUNC_SPIM0_CSN 0x04
#define PORTB5_FUNC_SPIS0_CSN 0x05
#define PORTB5_FUNC_PDM0_SDA 0x06
#define PORTB5_FUNC_I2C0_SDA 0x07
#define PORTB5_FUNC_PWM5 0x08
#define PORTB5_FUNC_TIM1_PAUSE 0x09
#define PORTB5_FUNC_SPIM8_0_IO5 0x0A
#define PORTB5_FUNC_PSRAM_QSPI_MIO5 0x0B
#define PORTB6_FUNC_B6 0x00
#define PORTB6_FUNC_CM0_A2 0x01
#define PORTB6_FUNC_CM0_SPI_MOSI 0x02
#define PORTB6_FUNC_UART0_RXD 0x03
#define PORTB6_FUNC_SPIM0_MOSI 0x04
#define PORTB6_FUNC_SPIS0_MOSI 0x05
#define PORTB6_FUNC_PDM1_CLK 0x06
#define PORTB6_FUNC_I2C1_CLK 0x07
#define PORTB6_FUNC_PWM6 0x08
#define PORTB6_FUNC_TIM0_TOG 0x09
#define PORTB6_FUNC_SPIM8_0_IO6 0x0A
#define PORTB6_FUNC_PSRAM_QSPI_MIO6 0x0B
#define PORTB7_FUNC_B7 0x00
#define PORTB7_FUNC_CM0_A3 0x01
#define PORTB7_FUNC_CM0_SPI_MISO 0x02
#define PORTB7_FUNC_UART0_TXD 0x03
#define PORTB7_FUNC_SPIM0_MISO 0x04
#define PORTB7_FUNC_SPIS0_MISO 0x05
#define PORTB7_FUNC_PDM1_SDA 0x06
#define PORTB7_FUNC_I2C1_SDA 0x07
#define PORTB7_FUNC_PWM7 0x08
#define PORTB7_FUNC_TIM1_TOG 0x09
#define PORTB7_FUNC_SPIM8_0_IO7 0x0A
#define PORTB7_FUNC_PSRAM_QSPI_MIO7 0x0B
#define PORTC0_FUNC_C0 0x00
#define PORTC0_FUNC_CM0_A0 0x01
#define PORTC0_FUNC_CM0_SWCK 0x02
#define PORTC0_FUNC_UART0_RXD 0x03
#define PORTC0_FUNC_SPIM0_CLK 0x04
#define PORTC0_FUNC_SPIS0_CLK 0x05
#define PORTC0_FUNC_PDM0_CLK 0x06
#define PORTC0_FUNC_I2C0_CLK 0x07
#define PORTC0_FUNC_PWM0 0x08
#define PORTC0_FUNC_TIM0_PAUSE 0x09
#define PORTC0_FUNC_SPIM8_0_CLK 0x0A
#define PORTC0_FUNC_PSRAM_QSPI_CLK 0x0B
#define PORTC1_FUNC_C1 0x00
#define PORTC1_FUNC_CM0_A1 0x01
#define PORTC1_FUNC_CM0_SWIO 0x02
#define PORTC1_FUNC_UART0_TXD 0x03
#define PORTC1_FUNC_SPIM0_CSN 0x04
#define PORTC1_FUNC_SPIS0_CSN 0x05
#define PORTC1_FUNC_PDM0_SDA 0x06
#define PORTC1_FUNC_I2C0_SDA 0x07
#define PORTC1_FUNC_PWM1 0x08
#define PORTC1_FUNC_TIM1_PAUSE 0x09
#define PORTC1_FUNC_SPIM8_0_CSN 0x0A
#define PORTC1_FUNC_PSRAM_QSPI_N_SS 0x0B
#define PORTC2_FUNC_C2 0x00
#define PORTC2_FUNC_CM0_A2 0x01
#define PORTC2_FUNC_CM0_SWCK 0x02
#define PORTC2_FUNC_UART2_RXD 0x03
#define PORTC2_FUNC_SPIM0_MOSI 0x04
#define PORTC2_FUNC_SPIS0_MOSI 0x05
#define PORTC2_FUNC_PDM1_CLK 0x06
#define PORTC2_FUNC_I2C1_CLK 0x07
#define PORTC2_FUNC_PWM2 0x08
#define PORTC2_FUNC_TIM0_TOG 0x09
#define PORTC2_FUNC_SPIM8_0_IO0 0x0A
#define PORTC2_FUNC_PSRAM_QSPI_MIO0 0x0B
#define PORTC3_FUNC_C3 0x00
#define PORTC3_FUNC_CM0_A3 0x01
#define PORTC3_FUNC_CM0_SWIO 0x02
#define PORTC3_FUNC_UART2_TXD 0x03
#define PORTC3_FUNC_SPIM0_MISO 0x04
#define PORTC3_FUNC_SPIS0_MISO 0x05
#define PORTC3_FUNC_PDM1_SDA 0x06
#define PORTC3_FUNC_I2C1_SDA 0x07
#define PORTC3_FUNC_PWM3 0x08
#define PORTC3_FUNC_TIM1_TOG 0x09
#define PORTC3_FUNC_SPIM8_0_IO1 0x0A
#define PORTC3_FUNC_PSRAM_QSPI_MIO1 0x0B
#define PORTC4_FUNC_C4 0x00
#define PORTC4_FUNC_CM0_A0 0x01
#define PORTC4_FUNC_CM33_1_SWCK 0x02
#define PORTC4_FUNC_UART2_CTS 0x03
#define PORTC4_FUNC_SPIM1_CLK 0x04
#define PORTC4_FUNC_SPIS1_CLK 0x05
#define PORTC4_FUNC_PDM0_CLK 0x06
#define PORTC4_FUNC_I2C0_CLK 0x07
#define PORTC4_FUNC_PWM4 0x08
#define PORTC4_FUNC_TIM0_PAUSE 0x09
#define PORTC4_FUNC_SPIM8_0_IO2 0x0A
#define PORTC4_FUNC_PSRAM_QSPI_MIO2 0x0B
#define PORTC5_FUNC_C5 0x00
#define PORTC5_FUNC_CM0_A1 0x01
#define PORTC5_FUNC_CM33_1_SWIO 0x02
#define PORTC5_FUNC_UART2_RTS 0x03
#define PORTC5_FUNC_SPIM1_CSN 0x04
#define PORTC5_FUNC_SPIS1_FRM 0x05
#define PORTC5_FUNC_PDM0_SDA 0x06
#define PORTC5_FUNC_I2C0_SDA 0x07
#define PORTC5_FUNC_PWM5 0x08
#define PORTC5_FUNC_TIM1_PAUSE 0x09
#define PORTC5_FUNC_SPIM8_0_IO3 0x0A
#define PORTC5_FUNC_PSRAM_QSPI_MIO3 0x0B
#define PORTC6_FUNC_C6 0x00
#define PORTC6_FUNC_CM0_A2 0x01
#define PORTC6_FUNC_CM33_0_SWCK 0x02
#define PORTC6_FUNC_UART0_RXD 0x03
#define PORTC6_FUNC_SPIM1_MOSI 0x04
#define PORTC6_FUNC_SPIS1_MOSI 0x05
#define PORTC6_FUNC_PDM1_CLK 0x06
#define PORTC6_FUNC_I2C1_CLK 0x07
#define PORTC6_FUNC_PWM6 0x08
#define PORTC6_FUNC_TIM0_TOG 0x09
#define PORTC6_FUNC_SPIM8_0_CLK 0x0A
#define PORTC6_FUNC_PSRAM_QSPI_CLK 0x0B
#define PORTC7_FUNC_C7 0x00
#define PORTC7_FUNC_CM0_A3 0x01
#define PORTC7_FUNC_CM33_0_SWIO 0x02
#define PORTC7_FUNC_UART0_TXD 0x03
#define PORTC7_FUNC_SPIM1_MISO 0x04
#define PORTC7_FUNC_SPIS1_MISO 0x05
#define PORTC7_FUNC_PDM1_SDA 0x06
#define PORTC7_FUNC_I2C1_SDA 0x07
#define PORTC7_FUNC_PWM7 0x08
#define PORTC7_FUNC_TIM1_TOG 0x09
#define PORTC7_FUNC_SPIM8_0_CSN 0x0A
#define PORTC7_FUNC_PSRAM_QSPI_N_SS 0x0B
#define PORTD0_FUNC_D0 0x00
#define PORTD0_FUNC_CM0_A0 0x01
#define PORTD0_FUNC_CM0_UART_RXD 0x02
#define PORTD0_FUNC_UART0_RXD 0x03
#define PORTD0_FUNC_SPIM1_CLK 0x04
#define PORTD0_FUNC_SPIS1_CLK 0x05
#define PORTD0_FUNC_PDM0_CLK 0x06
#define PORTD0_FUNC_I2C0_CLK 0x07
#define PORTD0_FUNC_PWM0 0x08
#define PORTD0_FUNC_TIM0_PAUSE 0x09
#define PORTD0_FUNC_SPIM8_0_IO4 0x0A
#define PORTD0_FUNC_PSRAM_QSPI_MIO0 0x0B
#define PORTD1_FUNC_D1 0x00
#define PORTD1_FUNC_CM0_A1 0x01
#define PORTD1_FUNC_CM0_UART_TXD 0x02
#define PORTD1_FUNC_UART0_TXD 0x03
#define PORTD1_FUNC_SPIM1_CSN 0x04
#define PORTD1_FUNC_SPIS1_FRM 0x05
#define PORTD1_FUNC_PDM0_SDA 0x06
#define PORTD1_FUNC_I2C0_SDA 0x07
#define PORTD1_FUNC_PWM1 0x08
#define PORTD1_FUNC_TIM1_PAUSE 0x09
#define PORTD1_FUNC_SPIM8_0_IO5 0x0A
#define PORTD1_FUNC_PSRAM_QSPI_MIO1 0x0B
#define PORTD2_FUNC_D2 0x00
#define PORTD2_FUNC_CM0_A2 0x01
#define PORTD2_FUNC_CM0_I2C_CLK 0x02
#define PORTD2_FUNC_UART2_RXD 0x03
#define PORTD2_FUNC_SPIM1_MOSI 0x04
#define PORTD2_FUNC_SPIS1_MOSI 0x05
#define PORTD2_FUNC_PDM1_CLK 0x06
#define PORTD2_FUNC_I2C1_CLK 0x07
#define PORTD2_FUNC_PWM2 0x08
#define PORTD2_FUNC_TIM0_TOG 0x09
#define PORTD2_FUNC_SPIM8_0_IO6 0x0A
#define PORTD2_FUNC_PSRAM_QSPI_MIO2 0x0B
#define PORTD3_FUNC_D3 0x00
#define PORTD3_FUNC_CM0_A3 0x01
#define PORTD3_FUNC_CM0_I2C_SDA 0x02
#define PORTD3_FUNC_UART2_TXD 0x03
#define PORTD3_FUNC_SPIM1_MISO 0x04
#define PORTD3_FUNC_SPIS1_MISO 0x05
#define PORTD3_FUNC_PDM1_SDA 0x06
#define PORTD3_FUNC_I2C1_SDA 0x07
#define PORTD3_FUNC_PWM3 0x08
#define PORTD3_FUNC_TIM1_TOG 0x09
#define PORTD3_FUNC_SPIM8_0_IO7 0x0A
#define PORTD3_FUNC_PSRAM_QSPI_MIO3 0x0B
#define PORTD4_FUNC_D4 0x00
#define PORTD4_FUNC_CM0_A0 0x01
#define PORTD4_FUNC_CM0_SPI_CLK 0x02
#define PORTD4_FUNC_UART2_CTS 0x03
#define PORTD4_FUNC_SPIM0_CLK 0x04
#define PORTD4_FUNC_SPIS0_CLK 0x05
#define PORTD4_FUNC_PDM0_CLK 0x06
#define PORTD4_FUNC_I2C2_CLK 0x07
#define PORTD4_FUNC_PWM4 0x08
#define PORTD4_FUNC_TIM0_PAUSE 0x09
#define PORTD4_FUNC_PSRAM_QSPI_MIO4 0x0B
#define PORTD5_FUNC_D5 0x00
#define PORTD5_FUNC_CM0_A1 0x01
#define PORTD5_FUNC_CM0_SPI_CSN 0x02
#define PORTD5_FUNC_UART2_RTS 0x03
#define PORTD5_FUNC_SPIM0_CSN 0x04
#define PORTD5_FUNC_SPIS0_CSN 0x05
#define PORTD5_FUNC_PDM0_SDA 0x06
#define PORTD5_FUNC_I2C2_SDA 0x07
#define PORTD5_FUNC_PWM5 0x08
#define PORTD5_FUNC_TIM1_PAUSE 0x09
#define PORTD5_FUNC_PSRAM_QSPI_MIO5 0x0B
#define PORTD6_FUNC_D6 0x00
#define PORTD6_FUNC_CM0_A2 0x01
#define PORTD6_FUNC_CM0_SPI_MOSI 0x02
#define PORTD6_FUNC_UART0_RXD 0x03
#define PORTD6_FUNC_SPIM0_MOSI 0x04
#define PORTD6_FUNC_SPIS0_MOSI 0x05
#define PORTD6_FUNC_PDM1_CLK 0x06
#define PORTD6_FUNC_I2C3_CLK 0x07
#define PORTD6_FUNC_PWM6 0x08
#define PORTD6_FUNC_TIM0_TOG 0x09
#define PORTD6_FUNC_PSRAM_QSPI_MIO6 0x0B
#define PORTD7_FUNC_D7 0x00
#define PORTD7_FUNC_CM0_A3 0x01
#define PORTD7_FUNC_CM0_SPI_MISO 0x02
#define PORTD7_FUNC_UART0_TXD 0x03
#define PORTD7_FUNC_SPIM0_MISO 0x04
#define PORTD7_FUNC_SPIS0_MISO 0x05
#define PORTD7_FUNC_PDM1_SDA 0x06
#define PORTD7_FUNC_I2C3_SDA 0x07
#define PORTD7_FUNC_PWM7 0x08
#define PORTD7_FUNC_TIM1_TOG 0x09
#define PORTD7_FUNC_PSRAM_QSPI_MIO7 0x0B
#define PORTE0_FUNC_E0 0x00
#define PORTE0_FUNC_CM0_A4 0x01
#define PORTE0_FUNC_CM1_UART_RXD 0x02
#define PORTE0_FUNC_UART1_RXD 0x03
#define PORTE0_FUNC_SPIM2_CLK 0x04
#define PORTE0_FUNC_SPIS0_CLK 0x05
#define PORTE0_FUNC_PDM2_CLK 0x06
#define PORTE0_FUNC_I2C2_CLK 0x07
#define PORTE0_FUNC_PWM8 0x08
#define PORTE0_FUNC_TIM2_PAUSE 0x09
#define PORTE0_FUNC_SPIM8_1_IO0 0x0A
#define PORTE1_FUNC_E1 0x00
#define PORTE1_FUNC_CM0_A5 0x01
#define PORTE1_FUNC_CM1_UART_TXD 0x02
#define PORTE1_FUNC_UART1_TXD 0x03
#define PORTE1_FUNC_SPIM2_CSN 0x04
#define PORTE1_FUNC_SPIS0_CSN 0x05
#define PORTE1_FUNC_PDM2_SDA 0x06
#define PORTE1_FUNC_I2C2_SDA 0x07
#define PORTE1_FUNC_PWM9 0x08
#define PORTE1_FUNC_TIM3_PAUSE 0x09
#define PORTE1_FUNC_SPIM8_1_IO1 0x0A
#define PORTE2_FUNC_E2 0x00
#define PORTE2_FUNC_CM0_A6 0x01
#define PORTE2_FUNC_CM1_UART_RXD 0x02
#define PORTE2_FUNC_UART3_RXD 0x03
#define PORTE2_FUNC_SPIM2_MOSI 0x04
#define PORTE2_FUNC_SPIS0_MOSI 0x05
#define PORTE2_FUNC_PDM3_CLK 0x06
#define PORTE2_FUNC_I2C3_CLK 0x07
#define PORTE2_FUNC_PWM10 0x08
#define PORTE2_FUNC_TIM2_TOG 0x09
#define PORTE2_FUNC_SPIM8_1_IO2 0x0A
#define PORTE3_FUNC_E3 0x00
#define PORTE3_FUNC_CM0_A7 0x01
#define PORTE3_FUNC_CM1_UART_TXD 0x02
#define PORTE3_FUNC_UART3_TXD 0x03
#define PORTE3_FUNC_SPIM2_MISO 0x04
#define PORTE3_FUNC_SPIS0_MISO 0x05
#define PORTE3_FUNC_PDM3_SDA 0x06
#define PORTE3_FUNC_I2C3_SDA 0x07
#define PORTE3_FUNC_PWM11 0x08
#define PORTE3_FUNC_TIM3_TOG 0x09
#define PORTE3_FUNC_SPIM8_1_IO3 0x0A
#define PORTE4_FUNC_E4 0x00
#define PORTE4_FUNC_CM0_A4 0x01
#define PORTE4_FUNC_CM0_SPI_CLK 0x02
#define PORTE4_FUNC_UART3_CTS 0x03
#define PORTE4_FUNC_SPIM2_CLK 0x04
#define PORTE4_FUNC_SPIS1_CLK 0x05
#define PORTE4_FUNC_PDM2_CLK 0x06
#define PORTE4_FUNC_I2C2_CLK 0x07
#define PORTE4_FUNC_PWM12 0x08
#define PORTE4_FUNC_TIM2_PAUSE 0x09
#define PORTE4_FUNC_SPIM8_1_IO4 0x0A
#define PORTE5_FUNC_E5 0x00
#define PORTE5_FUNC_CM0_A5 0x01
#define PORTE5_FUNC_CM0_SPI_CSN 0x02
#define PORTE5_FUNC_UART3_RTS 0x03
#define PORTE5_FUNC_SPIM2_CSN 0x04
#define PORTE5_FUNC_SPIS1_FRM 0x05
#define PORTE5_FUNC_PDM2_SDA 0x06
#define PORTE5_FUNC_I2C2_SDA 0x07
#define PORTE5_FUNC_PWM13 0x08
#define PORTE5_FUNC_TIM3_PAUSE 0x09
#define PORTE5_FUNC_SPIM8_1_IO5 0x0A
#define PORTE6_FUNC_E6 0x00
#define PORTE6_FUNC_CM0_A6 0x01
#define PORTE6_FUNC_CM0_SPI_MOSI 0x02
#define PORTE6_FUNC_UART1_RXD 0x03
#define PORTE6_FUNC_SPIM2_MOSI 0x04
#define PORTE6_FUNC_SPIS1_MOSI 0x05
#define PORTE6_FUNC_PDM3_CLK 0x06
#define PORTE6_FUNC_I2C3_CLK 0x07
#define PORTE6_FUNC_PWM14 0x08
#define PORTE6_FUNC_TIM2_TOG 0x09
#define PORTE6_FUNC_SPIM8_1_IO6 0x0A
#define PORTE7_FUNC_E7 0x00
#define PORTE7_FUNC_CM0_A7 0x01
#define PORTE7_FUNC_CM0_SPI_MISO 0x02
#define PORTE7_FUNC_UART1_TXD 0x03
#define PORTE7_FUNC_SPIM2_MISO 0x04
#define PORTE7_FUNC_SPIS1_MISO 0x05
#define PORTE7_FUNC_PDM3_SDA 0x06
#define PORTE7_FUNC_I2C3_SDA 0x07
#define PORTE7_FUNC_PWM15 0x08
#define PORTE7_FUNC_TIM3_TOG 0x09
#define PORTE7_FUNC_SPIM8_1_IO7 0x0A
#define PORTF0_FUNC_F0 0x00
#define PORTF0_FUNC_CM0_A4 0x01
#define PORTF0_FUNC_CM0_SPI_CLK 0x02
#define PORTF0_FUNC_UART1_RXD 0x03
#define PORTF0_FUNC_SPIM2_CLK 0x04
#define PORTF0_FUNC_SPIS1_CLK 0x05
#define PORTF0_FUNC_PDM2_CLK 0x06
#define PORTF0_FUNC_I2C2_CLK 0x07
#define PORTF0_FUNC_PWM8 0x08
#define PORTF0_FUNC_TIM2_PAUSE 0x09
#define PORTF0_FUNC_SPIM8_1_CLK 0x0A
#define PORTF1_FUNC_F1 0x00
#define PORTF1_FUNC_CM0_A5 0x01
#define PORTF1_FUNC_CM0_SPI_CSN 0x02
#define PORTF1_FUNC_UART1_TXD 0x03
#define PORTF1_FUNC_SPIM2_CSN 0x04
#define PORTF1_FUNC_SPIS1_FRM 0x05
#define PORTF1_FUNC_PDM2_SDA 0x06
#define PORTF1_FUNC_I2C2_SDA 0x07
#define PORTF1_FUNC_PWM9 0x08
#define PORTF1_FUNC_TIM3_PAUSE 0x09
#define PORTF1_FUNC_SPIM8_1_CSN 0x0A
#define PORTF2_FUNC_F2 0x00
#define PORTF2_FUNC_CM0_A6 0x01
#define PORTF2_FUNC_CM0_SPI_MOSI 0x02
#define PORTF2_FUNC_UART3_RXD 0x03
#define PORTF2_FUNC_SPIM2_MOSI 0x04
#define PORTF2_FUNC_SPIS1_MOSI 0x05
#define PORTF2_FUNC_PDM3_CLK 0x06
#define PORTF2_FUNC_I2C3_CLK 0x07
#define PORTF2_FUNC_PWM10 0x08
#define PORTF2_FUNC_TIM2_TOG 0x09
#define PORTF2_FUNC_SPIM8_1_IO0 0x0A
#define PORTF3_FUNC_F3 0x00
#define PORTF3_FUNC_CM0_A7 0x01
#define PORTF3_FUNC_CM0_SPI_MISO 0x02
#define PORTF3_FUNC_UART3_TXD 0x03
#define PORTF3_FUNC_SPIM2_MISO 0x04
#define PORTF3_FUNC_SPIS1_MISO 0x05
#define PORTF3_FUNC_PDM3_SDA 0x06
#define PORTF3_FUNC_I2C3_SDA 0x07
#define PORTF3_FUNC_PWM11 0x08
#define PORTF3_FUNC_TIM3_TOG 0x09
#define PORTF3_FUNC_SPIM8_1_IO1 0x0A
#define PORTF4_FUNC_F4 0x00
#define PORTF4_FUNC_CM0_A4 0x01
#define PORTF4_FUNC_CM1_UART_RXD 0x02
#define PORTF4_FUNC_UART3_CTS 0x03
#define PORTF4_FUNC_SPIM2_CLK 0x04
#define PORTF4_FUNC_SPIS0_CLK 0x05
#define PORTF4_FUNC_PDM2_CLK 0x06
#define PORTF4_FUNC_I2C4_CLK 0x07
#define PORTF4_FUNC_PWM12 0x08
#define PORTF4_FUNC_TIM2_PAUSE 0x09
#define PORTF4_FUNC_SPIM8_1_IO2 0x0A
#define PORTF5_FUNC_F5 0x00
#define PORTF5_FUNC_CM0_A5 0x01
#define PORTF5_FUNC_CM1_UART_TXD 0x02
#define PORTF5_FUNC_UART3_RTS 0x03
#define PORTF5_FUNC_SPIM2_CSN 0x04
#define PORTF5_FUNC_SPIS0_CSN 0x05
#define PORTF5_FUNC_PDM2_SDA 0x06
#define PORTF5_FUNC_I2C4_SDA 0x07
#define PORTF5_FUNC_PWM13 0x08
#define PORTF5_FUNC_TIM3_PAUSE 0x09
#define PORTF5_FUNC_SPIM8_1_IO3 0x0A
#define PORTF6_FUNC_F6 0x00
#define PORTF6_FUNC_CM0_A6 0x01
#define PORTF6_FUNC_CM1_UART_RXD 0x02
#define PORTF6_FUNC_UART1_RXD 0x03
#define PORTF6_FUNC_SPIM2_MOSI 0x04
#define PORTF6_FUNC_SPIS0_MOSI 0x05
#define PORTF6_FUNC_PDM3_CLK 0x06
#define PORTF6_FUNC_I2C2_CLK 0x07
#define PORTF6_FUNC_PWM14 0x08
#define PORTF6_FUNC_TIM2_TOG 0x09
#define PORTF6_FUNC_SPIM8_1_CLK 0x0A
#define PORTF7_FUNC_F7 0x00
#define PORTF7_FUNC_CM0_A7 0x01
#define PORTF7_FUNC_CM1_UART_TXD 0x02
#define PORTF7_FUNC_UART1_TXD 0x03
#define PORTF7_FUNC_SPIM2_MISO 0x04
#define PORTF7_FUNC_SPIS0_MISO 0x05
#define PORTF7_FUNC_PDM3_SDA 0x06
#define PORTF7_FUNC_I2C2_SDA 0x07
#define PORTF7_FUNC_PWM15 0x08
#define PORTF7_FUNC_TIM3_TOG 0x09
#define PORTF7_FUNC_SPIM8_1_CSN 0x0A
#define PORTG0_FUNC_G0 0x00
#define PORTG0_FUNC_CM0_A4 0x01
#define PORTG0_FUNC_CM1_UART_RXD 0x02
#define PORTG0_FUNC_UART1_RXD 0x03
#define PORTG0_FUNC_SPIM2_CLK 0x04
#define PORTG0_FUNC_SPIS0_CLK 0x05
#define PORTG0_FUNC_PDM2_CLK 0x06
#define PORTG0_FUNC_I2C3_CLK 0x07
#define PORTG0_FUNC_PWM8 0x08
#define PORTG0_FUNC_TIM2_PAUSE 0x09
#define PORTG0_FUNC_SPIM8_1_IO4 0x0A
#define PORTG1_FUNC_G1 0x00
#define PORTG1_FUNC_CM0_A5 0x01
#define PORTG1_FUNC_CM1_UART_TXD 0x02
#define PORTG1_FUNC_UART1_TXD 0x03
#define PORTG1_FUNC_SPIM2_CSN 0x04
#define PORTG1_FUNC_SPIS0_CSN 0x05
#define PORTG1_FUNC_PDM2_SDA 0x06
#define PORTG1_FUNC_I2C3_SDA 0x07
#define PORTG1_FUNC_PWM9 0x08
#define PORTG1_FUNC_TIM3_PAUSE 0x09
#define PORTG1_FUNC_SPIM8_1_IO5 0x0A
#define PORTG2_FUNC_G2 0x00
#define PORTG2_FUNC_CM0_A6 0x01
#define PORTG2_FUNC_CM1_UART_RXD 0x02
#define PORTG2_FUNC_UART3_RXD 0x03
#define PORTG2_FUNC_SPIM2_MOSI 0x04
#define PORTG2_FUNC_SPIS0_MOSI 0x05
#define PORTG2_FUNC_PDM3_CLK 0x06
#define PORTG2_FUNC_I2C4_CLK 0x07
#define PORTG2_FUNC_PWM10 0x08
#define PORTG2_FUNC_TIM2_TOG 0x09
#define PORTG2_FUNC_SPIM8_1_IO6 0x0A
#define PORTG3_FUNC_G3 0x00
#define PORTG3_FUNC_CM0_A7 0x01
#define PORTG3_FUNC_CM1_UART_TXD 0x02
#define PORTG3_FUNC_UART3_TXD 0x03
#define PORTG3_FUNC_SPIM2_MISO 0x04
#define PORTG3_FUNC_SPIS0_MISO 0x05
#define PORTG3_FUNC_PDM3_SDA 0x06
#define PORTG3_FUNC_I2C4_SDA 0x07
#define PORTG3_FUNC_PWM11 0x08
#define PORTG3_FUNC_TIM3_TOG 0x09
#define PORTG3_FUNC_SPIM8_1_IO7 0x0A
#define PORTG4_FUNC_G4 0x00
#define PORTG4_FUNC_CM0_A4 0x01
#define PORTG4_FUNC_CM0_SPI_CLK 0x02
#define PORTG4_FUNC_UART3_CTS 0x03
#define PORTG4_FUNC_SPIM2_CLK 0x04
#define PORTG4_FUNC_SPIS1_CLK 0x05
#define PORTG4_FUNC_PDM2_CLK 0x06
#define PORTG4_FUNC_I2C3_CLK 0x07
#define PORTG4_FUNC_PWM12 0x08
#define PORTG4_FUNC_TIM2_PAUSE 0x09
#define PORTG4_FUNC_SPIM8_1_IO0 0x0A
#define PORTG5_FUNC_G5 0x00
#define PORTG5_FUNC_CM0_A5 0x01
#define PORTG5_FUNC_CM0_SPI_CSN 0x02
#define PORTG5_FUNC_UART3_RTS 0x03
#define PORTG5_FUNC_SPIM2_CSN 0x04
#define PORTG5_FUNC_SPIS1_FRM 0x05
#define PORTG5_FUNC_PDM2_SDA 0x06
#define PORTG5_FUNC_I2C3_SDA 0x07
#define PORTG5_FUNC_PWM13 0x08
#define PORTG5_FUNC_TIM3_PAUSE 0x09
#define PORTG5_FUNC_SPIM8_1_IO1 0x0A
#define PORTG6_FUNC_G6 0x00
#define PORTG6_FUNC_CM0_A6 0x01
#define PORTG6_FUNC_CM0_SPI_MOSI 0x02
#define PORTG6_FUNC_UART1_RXD 0x03
#define PORTG6_FUNC_SPIM2_MOSI 0x04
#define PORTG6_FUNC_SPIS1_MOSI 0x05
#define PORTG6_FUNC_PDM3_CLK 0x06
#define PORTG6_FUNC_I2C4_CLK 0x07
#define PORTG6_FUNC_PWM14 0x08
#define PORTG6_FUNC_TIM2_TOG 0x09
#define PORTG6_FUNC_SPIM8_1_IO2 0x0A
#define PORTG7_FUNC_G7 0x00
#define PORTG7_FUNC_CM0_A7 0x01
#define PORTG7_FUNC_CM0_SPI_MISO 0x02
#define PORTG7_FUNC_UART1_TXD 0x03
#define PORTG7_FUNC_SPIM2_MISO 0x04
#define PORTG7_FUNC_SPIS1_MISO 0x05
#define PORTG7_FUNC_PDM3_SDA 0x06
#define PORTG7_FUNC_I2C4_SDA 0x07
#define PORTG7_FUNC_PWM15 0x08
#define PORTG7_FUNC_TIM3_TOG 0x09
#define PORTG7_FUNC_SPIM8_1_IO3 0x0A
#define PORTH0_FUNC_H0 0x00
#define PORTH0_FUNC_CM0_A4 0x01
#define PORTH0_FUNC_CM0_SPI_CLK 0x02
#define PORTH0_FUNC_UART1_RXD 0x03
#define PORTH0_FUNC_SPIM2_CLK 0x04
#define PORTH0_FUNC_SPIS1_CLK 0x05
#define PORTH0_FUNC_PDM2_CLK 0x06
#define PORTH0_FUNC_I2C3_CLK 0x07
#define PORTH0_FUNC_PWM8 0x08
#define PORTH0_FUNC_TIM2_PAUSE 0x09
#define PORTH0_FUNC_SPIM8_1_CLK 0x0A
#define PORTH1_FUNC_H1 0x00
#define PORTH1_FUNC_CM0_A5 0x01
#define PORTH1_FUNC_CM0_SPI_CSN 0x02
#define PORTH1_FUNC_UART1_TXD 0x03
#define PORTH1_FUNC_SPIM2_CSN 0x04
#define PORTH1_FUNC_SPIS1_FRM 0x05
#define PORTH1_FUNC_PDM2_SDA 0x06
#define PORTH1_FUNC_I2C3_SDA 0x07
#define PORTH1_FUNC_PWM9 0x08
#define PORTH1_FUNC_TIM3_PAUSE 0x09
#define PORTH1_FUNC_SPIM8_1_CSN 0x0A
#define PORTH2_FUNC_H2 0x00
#define PORTH2_FUNC_CM0_A6 0x01
#define PORTH2_FUNC_CM0_SPI_MOSI 0x02
#define PORTH2_FUNC_UART3_RXD 0x03
#define PORTH2_FUNC_SPIM2_MOSI 0x04
#define PORTH2_FUNC_SPIS1_MOSI 0x05
#define PORTH2_FUNC_PDM3_CLK 0x06
#define PORTH2_FUNC_I2C4_CLK 0x07
#define PORTH2_FUNC_PWM10 0x08
#define PORTH2_FUNC_TIM2_TOG 0x09
#define PORTH2_FUNC_SPIM8_1_IO0 0x0A
#define PORTH3_FUNC_H3 0x00
#define PORTH3_FUNC_CM0_A7 0x01
#define PORTH3_FUNC_CM0_SPI_MISO 0x02
#define PORTH3_FUNC_UART3_TXD 0x03
#define PORTH3_FUNC_SPIM2_MISO 0x04
#define PORTH3_FUNC_SPIS1_MISO 0x05
#define PORTH3_FUNC_PDM3_SDA 0x06
#define PORTH3_FUNC_I2C4_SDA 0x07
#define PORTH3_FUNC_PWM11 0x08
#define PORTH3_FUNC_TIM3_TOG 0x09
#define PORTH3_FUNC_SPIM8_1_IO1 0x0A
#define PORTH4_FUNC_H4 0x00
#define PORTH4_FUNC_CM0_A4 0x01
#define PORTH4_FUNC_CM1_UART_RXD 0x02
#define PORTH4_FUNC_UART3_CTS 0x03
#define PORTH4_FUNC_SPIM2_CLK 0x04
#define PORTH4_FUNC_SPIS0_CLK 0x05
#define PORTH4_FUNC_PDM2_CLK 0x06
#define PORTH4_FUNC_I2C3_CLK 0x07
#define PORTH4_FUNC_PWM12 0x08
#define PORTH4_FUNC_TIM2_PAUSE 0x09
#define PORTH4_FUNC_SPIM8_1_IO2 0x0A
#define PORTH5_FUNC_H5 0x00
#define PORTH5_FUNC_CM0_A5 0x01
#define PORTH5_FUNC_CM1_UART_TXD 0x02
#define PORTH5_FUNC_UART3_RTS 0x03
#define PORTH5_FUNC_SPIM2_CSN 0x04
#define PORTH5_FUNC_SPIS0_CSN 0x05
#define PORTH5_FUNC_PDM2_SDA 0x06
#define PORTH5_FUNC_I2C3_SDA 0x07
#define PORTH5_FUNC_PWM13 0x08
#define PORTH5_FUNC_TIM3_PAUSE 0x09
#define PORTH5_FUNC_SPIM8_1_IO3 0x0A
#define PORTH6_FUNC_H6 0x00
#define PORTH6_FUNC_CM0_A6 0x01
#define PORTH6_FUNC_CM1_UART_RXD 0x02
#define PORTH6_FUNC_UART1_RXD 0x03
#define PORTH6_FUNC_SPIM2_MOSI 0x04
#define PORTH6_FUNC_SPIS0_MOSI 0x05
#define PORTH6_FUNC_PDM3_CLK 0x06
#define PORTH6_FUNC_I2C4_CLK 0x07
#define PORTH6_FUNC_PWM14 0x08
#define PORTH6_FUNC_TIM2_TOG 0x09
#define PORTH7_FUNC_H7 0x00
#define PORTH7_FUNC_CM0_A7 0x01
#define PORTH7_FUNC_CM1_UART_TXD 0x02
#define PORTH7_FUNC_UART1_TXD 0x03
#define PORTH7_FUNC_SPIM2_MISO 0x04
#define PORTH7_FUNC_SPIS0_MISOI 0x05
#define PORTH7_FUNC_PDM3_SDA 0x06
#define PORTH7_FUNC_I2C4_SDA 0x07
#define PORTH7_FUNC_PWM15 0x08
#define PORTH7_FUNC_TIM3_TOG 0x09
#define GPIO_PA0 (1<<0)
#define GPIO_PA1 (1<<1)
#define GPIO_PA2 (1<<2)
#define GPIO_PA3 (1<<3)
#define GPIO_PA4 (1<<4)
#define GPIO_PA5 (1<<5)
#define GPIO_PA6 (1<<6)
#define GPIO_PA7 (1<<7)
#define GPIO_PB0 (1<<8)
#define GPIO_PB1 (1<<9)
#define GPIO_PB2 (1<<10)
#define GPIO_PB3 (1<<11)
#define GPIO_PB4 (1<<12)
#define GPIO_PB5 (1<<13)
#define GPIO_PB6 (1<<14)
#define GPIO_PB7 (1<<15)
#define GPIO_PC0 (1<<16)
#define GPIO_PC1 (1<<17)
#define GPIO_PC2 (1<<18)
#define GPIO_PC3 (1<<19)
#define GPIO_PC4 (1<<20)
#define GPIO_PC5 (1<<21)
#define GPIO_PC6 (1<<22)
#define GPIO_PC7 (1<<23)
#define GPIO_PD0 (1<<24)
#define GPIO_PD1 (1<<25)
#define GPIO_PD2 (1<<26)
#define GPIO_PD3 (1<<27)
#define GPIO_PD4 (1<<28)
#define GPIO_PD5 (1<<29)
#define GPIO_PD6 (1<<30)
#define GPIO_PD7 ((uint32_t)1<<31)
#define GPIO_PE0 (1<<0)
#define GPIO_PE1 (1<<1)
#define GPIO_PE2 (1<<2)
#define GPIO_PE3 (1<<3)
#define GPIO_PE4 (1<<4)
#define GPIO_PE5 (1<<5)
#define GPIO_PE6 (1<<6)
#define GPIO_PE7 (1<<7)
#define GPIO_PF0 (1<<8)
#define GPIO_PF1 (1<<9)
#define GPIO_PF2 (1<<10)
#define GPIO_PF3 (1<<11)
#define GPIO_PF4 (1<<12)
#define GPIO_PF5 (1<<13)
#define GPIO_PF6 (1<<14)
#define GPIO_PF7 (1<<15)
#define GPIO_PG0 (1<<16)
#define GPIO_PG1 (1<<17)
#define GPIO_PG2 (1<<18)
#define GPIO_PG3 (1<<19)
#define GPIO_PG4 (1<<20)
#define GPIO_PG5 (1<<21)
#define GPIO_PG6 (1<<22)
#define GPIO_PG7 (1<<23)
#define GPIO_PH0 (1<<24)
#define GPIO_PH1 (1<<25)
#define GPIO_PH2 (1<<26)
#define GPIO_PH3 (1<<27)
#define GPIO_PH4 (1<<28)
#define GPIO_PH5 (1<<29)
#define GPIO_PH6 (1<<30)
#define GPIO_PH7 ((uint32_t)1<<31)
#endif
enum system_port_t
{
GPIO_PORT_A,
GPIO_PORT_B,
GPIO_PORT_C,
GPIO_PORT_D,
GPIO_PORT_E,
GPIO_PORT_F,
GPIO_PORT_G,
GPIO_PORT_H,
};
enum system_port_bit_t
{
GPIO_BIT_0,
GPIO_BIT_1,
GPIO_BIT_2,
GPIO_BIT_3,
GPIO_BIT_4,
GPIO_BIT_5,
GPIO_BIT_6,
GPIO_BIT_7,
};
#define SET_FEILD(reg,field,pos,value) (reg) = ( (reg) & ~(field<<(pos)) | (value<<(pos)))
#endif // DRIVER_IOMUX_H

View File

@ -0,0 +1,173 @@
/*
******************************************************************************
* @file driver_ipc.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief Header file of IPC HAL module.
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_IPC_H__
#define __DRIVER_IPC_H__
#include "fr30xx.h"
/*IPC CTRL REG 0x00*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t CH0_IN_EN : 1; //Channel 0 input message enable
uint32_t CH1_IN_EN : 1; //Channel 1 input message enable
uint32_t CH2_IN_EN : 1; //Channel 2 input message enable
uint32_t CH3_IN_EN : 1; //Channel 3 input message enable
uint32_t CH0_OUT_EN : 1; //Channel 0 output message enable
uint32_t CH1_OUT_EN : 1; //Channel 1 output message enable
uint32_t CH2_OUT_EN : 1; //Channel 2 output message enable
uint32_t CH3_OUT_EN : 1; //Channel 3 output message enable
uint32_t RSV : 24;
} Bits;
} REG_IPC_CTRL_t;
/*IPC Message Pending REG 0x04*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t CH0_IN : 1;//Channel 0 input message pending
uint32_t CH1_IN : 1;//Channel 1 input message pending
uint32_t CH2_IN : 1;//Channel 2 input message pending
uint32_t CH3_IN : 1;//Channel 3 input message pending
uint32_t CH0_OUT : 1;//Channel 0 output message pending
uint32_t CH1_OUT : 1;//Channel 1 output message pending
uint32_t CH2_OUT : 1;//Channel 2 output message pending
uint32_t CH3_OUT : 1;//Channel 3 output message pending
uint32_t RSV : 24;
} Bits;
} REG_IPC_MSG_PENDING_t;
/*IPC Message IN Clear REG 0x28*/
typedef volatile struct
{
uint32_t CH0_IN : 1;//write 1 to clear Channel 0 input message interrupt
uint32_t CH1_IN : 1;//write 1 to clear Channel 1 input message interrupt
uint32_t CH2_IN : 1;//write 1 to clear Channel 2 input message interrupt
uint32_t CH3_IN : 1;//write 1 to clear Channel 3 input message interrupt
uint32_t RSV : 28;
} REG_IPC_MSG_CLR_t;
/*IPC ISR Interrupt Enable REG 0x2C*/
typedef volatile union
{
uint32_t Word;
struct {
uint32_t CH0_IN : 1;//Channel 0 input enable
uint32_t CH1_IN : 1;//Channel 1 input enable
uint32_t CH2_IN : 1;//Channel 2 input enable
uint32_t CH3_IN : 1;//Channel 3 input enable
uint32_t CH0_OUT : 1;//Channel 0 output enable
uint32_t CH1_OUT : 1;//Channel 1 output enable
uint32_t CH2_OUT : 1;//Channel 2 output enable
uint32_t CH3_OUT : 1;//Channel 3 output enable
uint32_t RSV1 : 24;
} Bits;
} REG_IPC_ISR_EN_t;
/*IPC MSG Interrupt Status REG 0x30*/
typedef volatile union
{
uint32_t Word;
struct {
uint32_t CH0_IN : 1;//Channel 0 input interrupt status
uint32_t CH1_IN : 1;//Channel 1 input interrupt status
uint32_t CH2_IN : 1;//Channel 2 input interrupt status
uint32_t CH3_IN : 1;//Channel 3 input interrupt status
uint32_t CH0_OUT : 1;//Channel 0 output interrupt status
uint32_t CH1_OUT : 1;//Channel 1 output interrupt status
uint32_t CH2_OUT : 1;//Channel 2 output interrupt status
uint32_t CH3_OUT : 1;//Channel 3 output interrupt status
uint32_t RSV1 : 24;
} Bits;
} REG_IPC_ISR_STA_t;
/*IPC MSG Interrupt Raw Status REG 0x34*/
typedef volatile union
{
uint32_t Word;
struct {
uint32_t CH0_IN : 1;//Channel 0 input raw interrupt status
uint32_t CH1_IN : 1;//Channel 1 input raw interrupt status
uint32_t CH2_IN : 1;//Channel 2 input raw interrupt status
uint32_t CH3_IN : 1;//Channel 3 input raw interrupt status
uint32_t CH0_OUT : 1;//Channel 0 output raw interrupt status
uint32_t CH1_OUT : 1;//Channel 1 output raw interrupt status
uint32_t CH2_OUT : 1;//Channel 2 output raw interrupt status
uint32_t CH3_OUT : 1;//Channel 3 output raw interrupt status
uint32_t RSV1 : 24;
} Bits;
} REG_IPC_ISR_RAW_STA_t;
typedef struct
{
volatile REG_IPC_CTRL_t IPC_CTRL; /* Offset 0x00 */
volatile REG_IPC_MSG_PENDING_t IPC_PENDING; /* Offset 0x04 */
volatile uint32_t IPC_MSG_IN0; /* Offset 0x08 */
volatile uint32_t IPC_MSG_IN1; /* Offset 0x0C */
volatile uint32_t IPC_MSG_IN2; /* Offset 0x10 */
volatile uint32_t IPC_MSG_IN3; /* Offset 0x14 */
volatile uint32_t IPC_MSG_OUT0; /* Offset 0x18 */
volatile uint32_t IPC_MSG_OUT1; /* Offset 0x1C */
volatile uint32_t IPC_MSG_OUT2; /* Offset 0x20 */
volatile uint32_t IPC_MSG_OUT3; /* Offset 0x24 */
volatile REG_IPC_MSG_CLR_t IPC_MSG_CLR; /* Offset 0x28 */
volatile REG_IPC_ISR_EN_t IPC_ISR_EN; /* Offset 0x2C */
volatile REG_IPC_ISR_STA_t IPC_ISR_STA; /* Offset 0x30 */
volatile REG_IPC_ISR_RAW_STA_t IPC_ISR_RAW_STA; /* Offset 0x34 */
}struct_IPC_t;
#define IPC_MCU ((struct_IPC_t *)IPC_BASE)
#define IPC_DSP ((struct_IPC_t *)DSP_IPC_BASE)
#define IPC_INT_STATUS_CH0_IN (1<<0)
#define IPC_INT_STATUS_CH1_IN (1<<1)
#define IPC_INT_STATUS_CH2_IN (1<<2)
#define IPC_INT_STATUS_CH3_IN (1<<3)
#define IPC_INT_STATUS_CH0_OUT (1<<4)
#define IPC_INT_STATUS_CH1_OUT (1<<5)
#define IPC_INT_STATUS_CH2_OUT (1<<6)
#define IPC_INT_STATUS_CH3_OUT (1<<7)
typedef enum{
IPC_CH_0 = (1<<0),
IPC_CH_1 = (1<<1),
IPC_CH_2 = (1<<2),
IPC_CH_3 = (1<<3),
}enum_IPC_Chl_Sel_t;
typedef struct __IPC_HandleTypeDef
{
struct_IPC_t *IPCx;
uint8_t TxEnableChannels;
uint8_t RxEnableChannels;
uint8_t TxOngoingChannels;
void (*TxCallback)(struct __IPC_HandleTypeDef *hipc, enum_IPC_Chl_Sel_t ch); /*!< Tx Callback */
void (*RxCallback)(struct __IPC_HandleTypeDef *hipc, enum_IPC_Chl_Sel_t ch, uint32_t msg); /*!< Rx Callback */
}IPC_HandleTypeDef;
void ipc_IRQHandler(IPC_HandleTypeDef *hipc);
void ipc_init(IPC_HandleTypeDef *hipc);
void ipc_msg_send(IPC_HandleTypeDef *hipc, enum_IPC_Chl_Sel_t ch, uint32_t msg);
#endif

View File

@ -0,0 +1,243 @@
/*
******************************************************************************
* @file driver_mp3_dec.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief Header file of MP3 DECODER module.
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_MP3_DEC_H__
#define __DRIVER_MP3_DEC_H__
#include "fr30xx.h"
/** @addtogroup MP3_DEC_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
/* MP3 DECODER CTRL REG 0x00*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t OPERA_EN : 1;//this bit enables the mp3d 0->no effect 1->operation enable
uint32_t OPERA_START : 1;//this bit enables to start the mp3d 0->no effect 1->start mp3 decoder
uint32_t ISR_EN : 1;//this bit enables the interrupt request 0->disable interrupt requeset 1->enable...
uint32_t RESTART_DEC : 1;//this bit enables to restart the mp3d
uint32_t RESET_PCM_FIFO : 1;//this bit enables to reset the pcm fifo
uint32_t DAI_EN : 1;//this bit enables direct audio interface
uint32_t ISSUE_NEW_FILE : 1;//this bit enables to issue new mp3 file
uint32_t RSV : 24;//
uint32_t MP3D_SOFTRST : 1;//this bit enable to reset the mp3d controller
} Bits;
} REG_MP3D_CTRL_t;
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t SOURCE_CMPLETION_ISR_EN : 1;//this bit enables source complete interrupt
uint32_t PCM_BUFFER_UNDERRUN_ISR_EN : 1;//this bit enables pcm buffer underrun interrupt
uint32_t PCM_BUFFER_FULL_ISR_EN : 1;//this bit enables pcm buffer full interrupt
uint32_t MP3_FRAME_LOCKED_ISR_EN : 1;//this bit enables mp3 frame locked interrupt
uint32_t RSV : 28;//
} Bits;
} REG_MP3D_INTMASK_t;
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t SOURCE_CMPLETION_ISR : 1;//this bit indicates the source decoding is complete 0->no effect 1->decode complete
uint32_t PCM_BUFFER_UNDERRUN_ISR : 1;//this bit indicates the pcm buffer is underrun 0->no effect 1->pcm buffer is underrun
uint32_t PCM_BUFFER_FULL_ISR : 1;//this bit indicates the pcm buffer is full
uint32_t MP3_FRAME_LOCKED_ISR : 1;//this bit indicates the mp3 frame is locked
uint32_t RSV : 28;//
} Bits;
} REG_MP3D_INTSTA_t;
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t VOLUME : 5;//volume control range from 0 to 31,0->no volume gain,31->maximum volume gain
uint32_t RSV : 27;//
} Bits;
} REG_MP3D_VOL_t;
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t EQ_60HZ_BAND : 6;//equalizer coefficients,60Hz band
uint32_t EQ_170HZ_BAND : 6;//equalizer coefficients,170Hz band
uint32_t EQ_310HZ_BAND : 6;//equalizer coefficients,310Hz band
uint32_t EQ_600HZ_BAND : 6;//equalizer coefficients,600Hz band
uint32_t EQ_1KHZ_BAND : 6;//equalizer coefficients,1KHz band
uint32_t RSV : 2;//
} Bits;
} REG_MP3D_EQ0_t;
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t EQ_3kHZ_BAND : 6;//equalizer coefficients,3KHz band
uint32_t EQ_6kHZ_BAND : 6;//equalizer coefficients,6KHz band
uint32_t EQ_12kHZ_BAND : 6;//equalizer coefficients,12KHz band
uint32_t EQ_14kHZ_BAND : 6;//equalizer coefficients,14KHz band
uint32_t EQ_16KHZ_BAND : 6;//equalizer coefficients,16KHz band
uint32_t RSV : 2;//
} Bits;
} REG_MP3D_EQ1_t;
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t MP3_STREAM_AUDIO_VER : 2;//MP3 stream audio version 11172 or 13818
uint32_t MP3_STREAM_ERROR_PROTECT : 1;//mp3 stream error protection
uint32_t MP3_STREAM_BIT_RATE : 4;//mp3 stream bit rate
uint32_t MP3_STREAM_SAMPLE_RATE : 2;//mp3 stream sample rate
uint32_t MP3_STREAM_AUDIO_MODE : 2;//mp3 stream audio mode
uint32_t MP3_STREAM_AUDIO_MODE_EXTEN : 2;//mp3 stream audio mode extension
uint32_t MP3_STREAM_COPYRIGHT : 1;//mp3 stream copyright
uint32_t MP3_STREAM_ORIGINAL : 1;//mp3 stream original
uint32_t MP3_STREAM_AUDIO_EMPHASIS : 2;//mp3 stream emphasis
uint32_t MP3_FRAME_LOCKED : 1;//mp3 frame locked bit[16:0] valid only when frame locked
uint32_t MP3_MAIN_DONE : 1;//mp3 huffman main done
uint32_t MP3_MAIN_EXHAUST : 1;//mp3 huffman main exhaust
uint32_t RSV : 12;//
} Bits;
} REG_MP3D_INFO_t;
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t MP3_DATA_SOURCE_SIZE : 16;//mp3 data source buffer size
uint32_t RSV : 16;//
} Bits;
} REG_MP3D_SSIZE_t;
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t MP3_PCM_BUFFER_SIZE : 16;//mp3 pcm buffer size (32 bit align)
uint32_t RSV : 16;//
} Bits;
} REG_MP3D_PSIZE_t;
typedef struct
{
volatile REG_MP3D_CTRL_t MP3D_CTRL; /* Offset 0x00 */
volatile REG_MP3D_INTMASK_t MP3D_INTMASK; /* Offset 0x04 */
volatile REG_MP3D_INTSTA_t MP3D_INTSTA; /* Offset 0x08 */
volatile REG_MP3D_VOL_t MP3D_VOL; /* Offset 0x0C */
volatile REG_MP3D_EQ0_t MP3D_EQ0; /* Offset 0x10*/
volatile REG_MP3D_EQ1_t MP3D_EQ1; /* Offset 0x14 */
volatile REG_MP3D_INFO_t MP3D_INFO; /* Offser 0x18*/
volatile uint32_t MP3D_SADDR; /* Offser 0x1C*/
volatile REG_MP3D_SSIZE_t MP3D_SSIZE; /* Offser 0x20*/
volatile uint32_t MP3D_PADDR; /* Offser 0x24*/
volatile REG_MP3D_PSIZE_t MP3D_PSIZE; /* Offser 0x28*/
volatile uint32_t RSV[3]; /*Offser 0x2C-0x34*/
volatile uint32_t MP3D_FRMCNT; /* Offser 0x38*/
}struct_MP3D_t;
typedef struct{
volatile uint32_t audio_ver;
volatile uint32_t error_protection;
volatile uint32_t bit_rate;
volatile uint32_t sample_rate;
volatile uint32_t audio_mode;
volatile uint32_t mode_extension;
volatile uint32_t copyright;
volatile uint32_t original;
volatile uint32_t audio_emphasis;
volatile uint32_t frame_locked;
volatile uint32_t main_done;
volatile uint32_t main_exhaust;
}struct_MP3D_stream_info_t;
typedef enum{
SOURCE_COMPLETE_ISR = 0,
PCM_BUF_UNDERRUN_ISR,
PCM_BUF_FULL_ISR,
MP3_FRAME_LOCKED_ISR,
}enum_mp3d_isr_t;
#define MP3D ((struct_MP3D_t *)MP3_DEC_BASE)
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t DAI_EN : 1;
uint32_t ISR_EN : 1;
uint32_t VOL : 5;
} Bits;
} struct_MP3Dec_Init_t;
typedef struct __MP3_DEC_HandleTypeDef
{
struct_MP3Dec_Init_t mp3dec_ctrl_Init;
REG_MP3D_EQ0_t mp3dec_eq0_Init;
REG_MP3D_EQ1_t mp3dec_eq1_Init;
uint8_t *MP3Enced_Data;
uint32_t MP3Enced_Index;
uint32_t FrameLen;
uint32_t LeftLen;
void (*Callback)(struct __MP3_DEC_HandleTypeDef *hSbcDec); /*!< MP3 decode finish Callback */
}MP3_DEC_HandleTypeDef;
#define __MP3D_SOFTRST() (MP3D->MP3D_CTRL.Bits.MP3D_SOFTRST = 1)
#define __MP3D_PCM_FIFO_RESET() (MP3D->MP3D_CTRL.Bits.RESET_PCM_FIFO = 1)
#define __MP3D_ISSUE_NEW_FILE() (MP3D->MP3D_CTRL.Bits.ISSUE_NEW_FILE = 1)
#define __MP3D_OPERA_ENABLE() (MP3D->MP3D_CTRL.Bits.OPERA_EN = 1)
#define __MP3D_SET_FRMCNT(frmcnt) (MP3D->MP3D_FRMCNT = frmcnt)
#define __MP3D_GET_FRMCNT (MP3D->MP3D_FRMCNT)
#define __MP3D_GET_INTSTA (MP3D->MP3D_INTSTA.Word)
#define __MP3D_CHECK_NEED_SEC() (MP3D->MP3D_INTSTA.Bits.SOURCE_CMPLETION_ISR == 1)
#define __MP3D_RESTART() (MP3D->MP3D_CTRL.Bits.RESTART_DEC = 1)
#define __MP3D_PCM_BUFF_FULL_ISR_IS_SET() (MP3D->MP3D_INTSTA.Bits.PCM_BUFFER_FULL_ISR == 1)
#define __MP3D_SRC_COMPLETE_ISR_IS_SET() (MP3D->MP3D_INTSTA.Bits.SOURCE_CMPLETION_ISR == 1)
#define __MP3D_COMPLETE_ISR_DISABLE() (MP3D->MP3D_INTMASK.Bits.SOURCE_CMPLETION_ISR_EN = 0)
#define __MP3D_COMPLETE_ISR_ENABLE() (MP3D->MP3D_INTMASK.Bits.SOURCE_CMPLETION_ISR_EN = 1)
/* mp3 decoder init */
void mp3_dec_init(MP3_DEC_HandleTypeDef *hmp3dec, uint32_t *pcm_buff, uint32_t pcm_buf_size);
/* mp3 decoder play data without isr */
void mp3_dec_playdata(MP3_DEC_HandleTypeDef *hmp3dec, uint8_t *fp_Data, uint32_t fu32_Size);
/* mp3 decoder get stream information */
void mp3d_get_stream_info(struct_MP3D_stream_info_t *info);
/* mp3 decoder failed */
int mp3d_check_dec_failed(void);
/* mp3 decoder handle function in mp3 decoder isr */
void mp3dec_IRQHandler(MP3_DEC_HandleTypeDef *hmp3dec);
/* mp3 decoder play data with isr */
void mp3_dec_playdata_IT(MP3_DEC_HandleTypeDef *hmp3dec, uint8_t *fp_Data, uint32_t fu32_Size);
#endif

View File

@ -0,0 +1,263 @@
/*
******************************************************************************
* @file driver_parallel_interface.H
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief Header file of parallel_interface HAL module.
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_PARALLEL_INTERFACE_H__
#define __DRIVER_PARALLEL_INTERFACE_H__
#include "fr30xx.h"
/** @addtogroup Parallel_Interface_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
/* parallel interface config */
typedef struct
{
uint32_t DC_POLARITY : 1;
uint32_t CS_POLARITY : 1;
uint32_t MODE : 1;
uint32_t PARA_WIDTH : 1;
uint32_t rsv_0 : 28;
}REG_INTERFACE_CFG_t;
/* Write/Read clock Config */
typedef struct
{
uint32_t WRITE_CLK_CFG : 3;
uint32_t rsv_0 : 1;
uint32_t READ_CLK_CFG : 4;
uint32_t WR_L_LEN : 3;
uint32_t rsv_1 : 1;
uint32_t WR_H_LEN : 3;
uint32_t rsv_2 : 17;
}REG_WR_CLK_t;
/* Data transmission Configuration */
typedef struct
{
uint32_t DATA_TRANS_SEQ_0 : 2;
uint32_t DATA_TRANS_SEQ_1 : 2;
uint32_t DATA_TRANS_SEQ_2 : 2;
uint32_t DATA_TRANS_SEQ_3 : 2;
uint32_t rsv_1 :24;
}REG_DATA_CFG_t;
/* DMA Configuration */
typedef struct
{
uint32_t DMA_TX_LEVEL : 5;
uint32_t DMA_ENABLE : 1;
uint32_t rsv_0 : 26;
}REG_DMA_t;
/* -------------------------------------------*/
/* parallel Register */
/* -------------------------------------------*/
typedef struct
{
volatile REG_INTERFACE_CFG_t INTF_CFG; /* offset 0x00 */
volatile uint32_t CSX; /* offset 0x04 */
volatile REG_WR_CLK_t CRM; /* offset 0x08 */
volatile uint32_t BUS_STATUS; /* offset 0x0C */
volatile uint32_t CFG; /* offset 0x10 */
volatile uint32_t DATA_WR_LEN; /* offset 0x14 */
volatile REG_DATA_CFG_t DATA_CFG; /* offset 0x18 */
volatile uint32_t TX_FIFO; /* offset 0x1C */
volatile uint32_t RD_REQ; /* offset 0x20 */
volatile uint32_t DAT_RD; /* offset 0x24 */
volatile uint32_t TXFF_AEMP_LV; /* offset 0x28 */
volatile uint32_t TXFF_CLR; /* offset 0x2C */
volatile uint32_t INT_CONTROL; /* offset 0x30 */
volatile uint32_t INT_STATUS; /* offset 0x34 */
volatile REG_DMA_t DMA; /* offset 0x38 */
}struct_Parallel_t;
#define PARALLEL0 ((struct_Parallel_t *)PARALLEL_BASE)
/* ################################ Register Section END ################################ */
/**
* @}
*/
/** @addtogroup Parallel_Interface_Initialization_Config_Section
* @{
*/
/* ################################ Initialization_Config Section Start ################################ */
/** @defgroup PARALLEL_FIFO PARALLEL FIFO
* @{
*/
#define PARALLEL_FIFO_DEPTH 32
/**
* @}
*/
/* mode select */
typedef enum
{
MODE_8080,
MODE_6800,
}enum_Parallel_MODE_t;
/* data bus width */
typedef enum
{
DATA_BUS_8_BIT,
DATA_BUS_16_BIT,
}enum_DATA_BUS_t;
/* read clock division */
typedef enum
{
RDCLK_DIV_1,
RDCLK_DIV_2,
RDCLK_DIV_3,
RDCLK_DIV_4,
RDCLK_DIV_6,
RDCLK_DIV_8,
RDCLK_DIV_16,
RDCLK_DIV_32,
RDCLK_DIV_64,
}enum_RDCLK_DIV_t;
/* write clock division */
typedef enum
{
WDCLK_DIV_1,
WDCLK_DIV_2,
WDCLK_DIV_3,
WDCLK_DIV_4,
WDCLK_DIV_6,
WDCLK_DIV_8,
}enum_WDCLK_DIV_t;
/* interrupt index */
typedef enum
{
INT_TXFIFO_FULL = 0x00000001,
INT_TXFIFO_EMPTY = 0x00000002,
INT_TXFIFO_LEVEMPT = 0x00000004,
}enum_INT_t;
/**
* @brief parallel Initialization Structure definition
*/
typedef struct
{
uint32_t ParallelMode; /* This parameter can be a value of @ref enum_Parallel_MODE_t */
uint32_t DataBusSelect; /* This parameter can be a value of @ref enum_DATA_BUS_t */
uint32_t ReadClock; /* This parameter can be a value of @ref enum_RDCLK_DIV_t */
uint32_t WriteClock; /* This parameter can be a value of @ref enum_WDCLK_DIV_t */
}str_ParallelInit_t;
/**
* @brief parallel handle Structure definition
*/
typedef struct
{
struct_Parallel_t *PARALLELx; /*!< PARALLEL registers base address */
str_ParallelInit_t Init; /*!< PARALLEL communication parameters */
}PARALLEL_HandTypeDef;
/* ################################ Initialization_Config Section END ################################ */
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
/* Parallel tx fifo level */ /* fu8_level: 0 ~ 31 */
#define __PARALLEL_TX_FIFO_ALMOST_EMPTY_LEVEL(__PARALLELx__, __LEVEL__) (__PARALLELx__->TXFF_AEMP_LV = __LEVEL__)
/* Parallel tx fifo reset */
/* Parallel tx fifo release */
#define __PARALLEL_TX_FIFO_RESET(__PARALLELx__) (__PARALLELx__->TXFF_CLR = 0x07)
#define __PARALLEL_TX_FIFO_RELEASE(__PARALLELx__) (__PARALLELx__->TXFF_CLR = 0x00)
/* Parallel writer CMD */
#define __PARALLEL_WR_CMD(__PARALLELx__ , __CMD__) (__PARALLELx__->CFG = __CMD__)
#define __PARALLEL_WR_PARAM(__PARALLELx__ , __DATA__) (__PARALLELx__->CFG = 0x10000 | __DATA__)
/* Parallel get interrupt status */
#define __PARALLEL_INT_STATUS(__PARALLELx__) (__PARALLELx__->INT_STATUS)
/* Parallel interrupt Status enable/disable */
#define __PARALLEL_INT_STATUS_ENABLE(__PARALLELx__, __STATUS__) (__PARALLELx__->INT_CONTROL |= (__STATUS__))
#define __PARALLEL_INT_STATUS_DISABLE(__PARALLELx__, __STATUS__) (__PARALLELx__->INT_CONTROL &= ~(__STATUS__))
#define __PARALLEL_INT_STATUS_ALL_ENABLE(__PARALLELx__, __STATUS__) (__PARALLELx__->INT_CONTROL = 0x0F)
#define __PARALLEL_INT_STATUS_ALL_DISABLE(__PARALLELx__, __STATUS__) (__PARALLELx__->INT_CONTROL = 0x00)
/* Parallel bus status */
#define __PARALLEL_IS_BUS_BUSY(__PARALLELx__) (__PARALLELx__->BUS_STATUS)
/* Parallel bus status */
#define __PARALLEL_RD_REQ(__PARALLELx__) (__PARALLELx__->RD_REQ = 0x1)
/* Parallel_dma_requset_level */ /* fu8_level: 0 ~ 31 */
#define __PARALLEL_DMA_TX_LEVEL(__PARALLELx__, __LEVEL__) (__PARALLELx__->DMA.DMA_TX_LEVEL = __LEVEL__)
/* Parallel_dma ENABLE and DISABLE */
#define __PARALLEL_DMA_ENABLE(__PARALLELx__) (__PARALLELx__->DMA.DMA_ENABLE = 1)
#define __PARALLEL_DMA_DISABLE(__PARALLELx__) (__PARALLELx__->DMA.DMA_ENABLE = 0)
/* Parallel_cs_set */
/* Parallel_cs_release */
#define __PARALLEL_CS_SET(__PARALLELx__) (__PARALLELx__->CSX = 0)
#define __PARALLEL_CS_RELEASE(__PARALLELx__) (__PARALLELx__->CSX = 1)
/* Parallel_set_bus_8bit */
/* Parallel_set_bus_16bit */
#define __PARALLEL_SET_BUS_8BIT(__PARALLELx__) (__PARALLELx__->INTF_CFG.PARA_WIDTH = DATA_BUS_8_BIT)
#define __PARALLEL_SET_BUS_16BIT(__PARALLELx__) (__PARALLELx__->INTF_CFG.PARA_WIDTH = DATA_BUS_16_BIT)
/* Parallel_wrclk_div */
/* Parallel_rdclk_div */
#define __PARALLEL_WRCLK_DIV(__PARALLELx__, __WDCLK_DIV__) (__PARALLELx__->CRM.WRITE_CLK_CFG = __WDCLK_DIV__)
#define __PARALLEL_RDCLK_DIV(__PARALLELx__, __RDCLK_DIV__) (__PARALLELx__->CRM.READ_CLK_CFG = __RDCLK_DIV__)
/* Parallel_wrclk_HighLength */
/* Parallel_wrclk_LowLength */
#define __PARALLEL_WRCLK_HIGHLENGTH(__PARALLELx__, __LENGTH__) (__PARALLELx__->CRM.WR_H_LEN = __LENGTH__)
#define __PARALLEL_WRCLK_LOWLENGTH(__PARALLELx__, __LENGTH__) (__PARALLELx__->CRM.WR_L_LEN = __LENGTH__)
/* Parallel_CS_Polarity */ /* fb_Polarity: 1: high active */
/* Parallel_DC_Polarity */ /* 0: low active */
#define __PARALLEL_CS_POLARITY(__PARALLELx__, __POLARITY__) (__PARALLELx__->INTF_CFG.CS_POLARITY = __POLARITY__)
#define __PARALLEL_DC_POLARITY(__PARALLELx__, __FB_POLARITY__) (__PARALLELx__->INTF_CFG.DC_POLARITY = __POLARITY__)
/* __PARALLEL_Set_WR_LEN */
#define __PARALLEL_SET_WR_LEN(__PARALLELx__, __LEVEL__) (__PARALLELx__->DATA_WR_LEN = __LEVEL__)
/* Exported functions ---------------------------------------------------------------*/
/* parallel_init */
void parallel_init(PARALLEL_HandTypeDef *hparallel);
/* Parallel_write_cmd */
/* Parallel_write_param */
/* Parallel_write_data */
void Parallel_write_cmd(PARALLEL_HandTypeDef *hparallel, uint8_t fp8_CMD);
void Parallel_write_param(PARALLEL_HandTypeDef *hparallel, uint16_t fu16_Data);
void Parallel_write_data(PARALLEL_HandTypeDef *hparallel, uint32_t *fp32_WriteBuffer, uint32_t fu32_WriteNum);
/* Parallel_read_data_8bit */
/* Parallel_read_data_16bit */
void Parallel_read_data_8bit(PARALLEL_HandTypeDef *hparallel, uint8_t fu8_Param, uint8_t *fp8_ReadBuffer, uint32_t fu32_ReadNum);
void Parallel_read_data_16bit(PARALLEL_HandTypeDef *hparallel, uint8_t fu8_Param, uint16_t *fp16_ReadBuffer, uint32_t fu32_ReadNum);
#endif

View File

@ -0,0 +1,255 @@
/*
******************************************************************************
* @file driver_pdm.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2022
* @brief Header file of pdm HAL module.
******************************************************************************
* @attention
*
* Copyright (c) 2022 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_PDM_H__
#define __DRIVER_PDM_H__
#include "fr30xx.h"
#include <math.h>
/** @addtogroup PDM_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
/* PDM config register */
typedef struct
{
uint32_t EN : 1;
uint32_t CLK_EN : 1;
uint32_t RST : 1;
uint32_t DAT_INV : 1;
uint32_t CLK_INV : 1;
uint32_t USB_MODE : 1;
uint32_t SAMPLE_RATE : 4;
uint32_t OSR_MODE : 2;
uint32_t MONO : 1;
uint32_t CH_SEL : 1;
uint32_t LR_SWAP : 1;
uint32_t HPF_EN : 1;
uint32_t rsv_0 : 16;
}REG_PDMConfig_t;
/* PDM FIFO Reset Register */
typedef union{
struct {
uint32_t PUSH_RST : 1;
uint32_t POP_RST : 1;
uint32_t RST : 1;
uint32_t rsv : 29;
} s;
uint32_t rst;
}REG_PDMFFReset_t;
/* PDM interrupt Register */
typedef struct{
uint32_t FF_FULL : 1;
uint32_t FF_AFULL : 1;
uint32_t FF_EMPTY : 1;
uint32_t rsv : 29;
}REG_PDMFFInt_t;
/* PDM interrupt Register */
typedef struct{
uint32_t TRIG_LVL : 6;
uint32_t EN : 1;
uint32_t rsv : 25;
}REG_PDMDMA_t;
/* -----------------------------------------------*/
/* PDM Register */
/* -----------------------------------------------*/
typedef struct
{
volatile REG_PDMConfig_t Config; /* Offset 0x00 */
volatile uint32_t FF_AFLL_LVL; /* Offset 0x04 */
volatile REG_PDMFFReset_t FF_RST; /* Offset 0x08 */
volatile REG_PDMFFInt_t INT_EN; /* Offset 0x0C */
volatile REG_PDMFFInt_t INT_STA; /* Offset 0x10 */
volatile REG_PDMFFInt_t INT_RAW_STA; /* Offset 0x14 */
volatile uint32_t VOL_L; /* Offset 0x18 */
volatile uint32_t VOL_R; /* Offset 0x1C */
volatile uint32_t rsv1; /* Offset 0x20 */
volatile uint32_t DATA; /* Offset 0x24 */
volatile REG_PDMDMA_t DMA_CFG; /* Offset 0x28 */
}struct_PDM_t;
#define PDM0 ((struct_PDM_t *)PDM0_BASE)
#define PDM1 ((struct_PDM_t *)PDM1_BASE)
#define PDM2 ((struct_PDM_t *)PDM2_BASE)
/* ################################ Register Section END ################################## */
/**
* @}
*/
/** @addtogroup PDM_Initialization_Config_Section
* @{
*/
/* ################################ Initialization Config Section Start ################################ */
/* PDM Sample Rate */
typedef enum
{
PDM_SAMPLE_RATE_8000 = 0x00,
PDM_SAMPLE_RATE_12000 = 0x01,
PDM_SAMPLE_RATE_16000 = 0x02,
PDM_SAMPLE_RATE_24000 = 0x03,
PDM_SAMPLE_RATE_32000 = 0x04,
PDM_SAMPLE_RATE_48000 = 0x05,
PDM_SAMPLE_RATE_96000 = 0x06,
PDM_SAMPLE_RATE_192000 = 0x07,
PDM_SAMPLE_RATE_8012 = 0x08,
PDM_SAMPLE_RATE_11025 = 0x09,
PDM_SAMPLE_RATE_22050 = 0x0A,
PDM_SAMPLE_RATE_44100 = 0x0B,
PDM_SAMPLE_RATE_88200 = 0x0C,
PDM_SAMPLE_RATE_176400 = 0x0D,
PDM_SAMPLE_RATE_44_1K_SET = 0x08,
}enum_PDM_SampleRate_t;
/* PDM Clock Mode Selection */
typedef enum{
PDM_CLOCK_MODE_NORMAL, /* clock from AUPLL2 */
PDM_CLOCK_MODE_USB, /* clock is 24MHz */
}enum_PDM_ClockMode_t;
/* PDM Over Sample Mode */
typedef enum{
PDM_OSM_0, // oversampling low level support to all SampleRate.
PDM_OSM_1, // oversampling middle level support up to 96K.
PDM_OSM_2, // oversampling high level support up to 48K.
}enum_PDM_OverSampleMode_t;
/* PDM Channel Selection in Mono mode */
typedef enum{
PDM_MONO_LEFT, /* Mono selcet left */
PDM_MONO_RIGHT, /* Mono selcet right */
PDM_STEREO, /* stereo */
}enum_PDM_ChannelMode_t;
/* PDM Volume */
typedef enum{
PDM_VOL_0,
PDM_VOL_1,
PDM_VOL_2,
PDM_VOL_3,
PDM_VOL_4,
PDM_VOL_5,
PDM_VOL_6,
PDM_VOL_7,
PDM_VOL_8,
PDM_VOL_9,
PDM_VOL_10,
PDM_VOL_11,
PDM_VOL_12,
PDM_VOL_13,
PDM_VOL_14,
PDM_VOL_15,
PDM_VOL_MAX
}enum_PDM_Volume_t;
/*
* @brief PDM Init Structure definition
*/
typedef struct
{
uint8_t SampleRate; /* This parameter can be a value of @ref enum_PDM_SampleRate_t */
uint8_t OverSampleMode; /* This parameter can be a value of @ref enum_PDM_OverSampleMode_t */
uint8_t ChannelMode; /* This parameter can be a value of @ref enum_PDM_ChannelMode_t */
int8_t Volume; /* This parameter can be a value with dB as unit */
uint8_t FIFO_FullThreshold; /* This parameter can be a 5 bit value */
}struct_PDMInit_t;
/*
* @brief PDM handle Structure definition
*/
typedef struct __PDM_HandleTypeDef
{
struct_PDM_t *PDMx; /*!< PDM registers base address */
struct_PDMInit_t Init; /*!< PDM communication parameters */
void (*RxCallback)(struct __PDM_HandleTypeDef *hpdm);
bool b_RxBusy;
void *p_RxData;
}PDM_HandleTypeDef;
/* ################################ Initialization Config Section END ################################## */
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
#define PDM_FIFO_DEPTH 64
#define PDM_FIFO_H_FULL (PDM_FIFO_DEPTH / 2)
#define PDM_VOL_dB(x) (uint32_t)(pow(10.0, (x)/20.0) * 0x2000)
/* PDM enable/disable */
#define __PDM_ENABLE(__PDMx__) (__PDMx__->Config.EN = 1)
#define __PDM_DISABLE(__PDMx__) (__PDMx__->Config.EN = 0)
/* PDM clock enable/disable */
#define __PDM_CLK_ENABLE(__PDMx__) (__PDMx__->Config.CLK_EN = 1)
#define __PDM_CLK_DISABLE(__PDMx__) (__PDMx__->Config.CLK_EN = 0)
#define __PDM_SWAP_ENABLE(__PDMx__) (__PDMx__->Config.LR_SWAP = 1)
#define __PDM_SWAP_DISABLE(__PDMx__) (__PDMx__->Config.LR_SWAP = 0)
/* PDM clock mode. 0: from AUPLL. 1: from 24M */
#define __PDM_CLK_MODE(__PDMx__, __MODE__) (__PDMx__->Config.USB_MODE = __MODE__)
/* PDM FIFO interrupt enable/disable */
#define __PDM_FIFO_FULL_INT_ENABLE(__PDMx__) (__PDMx__->INT_EN.FF_FULL = 1)
#define __PDM_FIFO_EMPTY_INT_ENABLE(__PDMx__) (__PDMx__->INT_EN.FF_EMPTY = 1)
#define __PDM_FIFO_ALMOST_FULL_INT_ENABLE(__PDMx__) (__PDMx__->INT_EN.FF_AFULL = 1)
#define __PDM_FIFO_FULL_INT_DISABLE(__PDMx__) (__PDMx__->INT_EN.FF_FULL = 0)
#define __PDM_FIFO_EMPTY_INT_DISABLE(__PDMx__) (__PDMx__->INT_EN.FF_EMPTY = 0)
#define __PDM_FIFO_ALMOST_FULL_INT_DISABLE(__PDMx__) (__PDMx__->INT_EN.FF_AFULL = 0)
/* PDM FIFO status */
#define __PDM_IS_FIFO_FULL(__PDMx__) (__PDMx__->INT_RAW_STA.FF_FULL)
#define __PDM_IS_FIFO_EMPTY(__PDMx__) (__PDMx__->INT_RAW_STA.FF_EMPTY)
#define __PDM_IS_FIFO_ALMOST_FULL(__PDMx__) (__PDMx__->INT_RAW_STA.FF_AFULL)
/* Exported functions --------------------------------------------------------*/
void pdm_IRQHandler(PDM_HandleTypeDef *hpdm);
/* pdm_init */
void pdm_init(PDM_HandleTypeDef *hpdm);
/* pdm_start/stio */
void pdm_start(PDM_HandleTypeDef *hpdm);
void pdm_stop(PDM_HandleTypeDef *hpdm);
/* pdm_start_IT */
void pdm_start_IT(PDM_HandleTypeDef *hpdm, void *fp_Data);
/* pdm_vol_set */
void pdm_vol_set(PDM_HandleTypeDef *hpdm, int8_t vol);
/* pdm_read_data */
void pdm_read_data(PDM_HandleTypeDef *hpdm, void *fp_Data);
#endif

View File

@ -0,0 +1,598 @@
#ifndef _DRIVER_PMU_H
#define _DRIVER_PMU_H
#include <stdint.h>
#include <stdbool.h>
/// PMU module clock source
#define PMU_REG_CLK 0x00
/// 1: external XTAL32768, 0: internal 62K RC
#define PMU_SYSCLK_SEL_POS 0
#define PMU_SYSCLK_SEL_BIT 0x01
/// configure PMU on-off base timing dividor
#define PMU_REG_FSM_TIMER 0x01
#define PMU_FSM_OFF_DIV_LSB 5
#define PMU_FSM_OFF_DIV_MSK 0xE0
#define PMU_FSM_ON_DIV_LSB 0
#define PMU_FSM_ON_DIV_MSK 0x1F
/// configure debounce module dividor
#define PMU_REG_DEB_CLK_DIV 0x02
/// configure PMU reset source
#define PMU_REG_RST_SRC_EN 0x03
#define PMU_LOW_BAT_RST_POS 2
#define PMU_LOW_BAT_RST_BIT (1<<2)
#define PMU_WDT_RST_POS 1
#define PMU_WDT_RST_BIT (1<<1)
#define PMU_PIN_RST_POS 0
#define PMU_PIN_RST_BIT (1<<0)
/// configure module clock enalbe
#define PMU_REG_CLK_EN 0x04
#define PMU_EFUSE_CLK_EN_POS 7
#define PMU_EFUSE_CLK_EN_BIT (1<<7)
#define PMU_FILTER_CLK_EN_POS 6
#define PMU_FILTER_CLK_EN_BIT (1<<6)
#define PMU_QDEC_CLK_EN_POS 5
#define PMU_QDEC_CLK_EN_BIT (1<<5)
#define PMU_KEYSCAN_CLK_EN_POS 4
#define PMU_KEYSCAN_CLK_EN_BIT (1<<4)
#define PMU_DEB_CLK_EN_POS 3
#define PMU_DEB_CLK_EN_BIT (1<<3)
#define PMU_RTC_CLK_EN_POS 2
#define PMU_RTC_CLK_EN_BIT (1<<2)
#define PMU_WDT_CLK_EN_POS 1
#define PMU_WDT_CLK_EN_BIT (1<<1)
#define PMU_LP_TICK_CLK_EN_POS 0
#define PMU_LP_TICK_CLK_EN_BIT (1<<0)
/// reset modules inside PMU
#define PMU_REG_RST 0x05
#define PMU_EFUSE_SFT_RST_POS 7
#define PMU_EFUSE_SFT_RST_BIT (1<<7)
#define PMU_FILTER_SFT_RST_POS 6
#define PMU_FILTER_SFT_RST_BIT (1<<6)
#define PMU_QDEC_SFT_RST_POS 5
#define PMU_QDEC_SFT_RST_BIT (1<<5)
#define PMU_KEYSCAN_SFT_RST_POS 4
#define PMU_KEYSCAN_SFT_RST_BIT (1<<4)
#define PMU_DEB_SFT_RST_POS 3
#define PMU_DEB_SFT_RST_BIT (1<<3)
#define PMU_RTC_SFT_RST_POS 2
#define PMU_RTC_SFT_RST_BIT (1<<2)
#define PMU_WDT_SFT_RST_POS 1
#define PMU_WDT_SFT_RST_BIT (1<<1)
#define PMU_LP_TICK_SFT_RST_POS 0
#define PMU_LP_TICK_SFT_RST_BIT (1<<0)
/// indicate which module could put PMU into sleep mode or wake up PMU
#define PMU_REG_SLP_WK_SRC 0x06
#define PMU_WK_IRQ_EN_POS 5
#define PMU_WK_IRQ_EN_BIT (1<<5)
#define PMU_WK_TICK_EN_POS 4
#define PMU_WK_TICK_EN_BIT (1<<4)
#define PMU_SLP_CPU_EN_POS 1
#define PMU_SLP_CPU_EN_BIT (1<<1)
#define PMU_SLP_TICK_EN_POS 0
#define PMU_SLP_TICK_EN_BIT (1<<0)
/// control PMU wakeup or enter sleep by software
#define PMU_REG_SW_OP 0x07
#define PMU_SW_WK_TICK_POS 1
#define PMU_SW_WK_TICK_BIT (1<<1)
#define PMU_SW_EN_SLP_POS 0
#define PMU_SW_EN_SLP_BIT (1<<0)
/// default value is 0xAD
#define PMU_REG_STATUS 0x08
#define PMU_STATUS_DEEP_SLEEP 0xC3
#define PMU_STATUS_NORAML 0xAD
/// indicate which module could wake up TICK
#define PMU_REG_TICK_CTRL 0x09
#define PMU_IRQ_WK_TICK_EN_POS 3
#define PMU_IRQ_WK_TICK_EN_BIT (1<<3)
/// this bit has to be set when PMU_IRQ_WK_TICK_EN_BIT is set
#define PMU_EXT_WK_TICK_EN_POS 1
#define PMU_EXT_WK_TICK_EN_BIT (1<<1)
#define PMU_TICK_SLP_PMU_EN_POS 0
#define PMU_TICK_SLP_PMU_EN_BIT (1<<0)
/// counter from start PMU wakeup procedure to generate BTDM sleep interrupt
#define PMU_REG_TW_WKUP_L 0x0a
#define PMU_REG_TW_WKUP_H 0x0b
/// write: expect sleep duration, read: actual sleep duration
#define PMU_REG_TICK_COUNTER_0 0x0c
#define PMU_REG_TICK_COUNTER_1 0x0d
#define PMU_REG_TICK_COUNTER_2 0x0e
#define PMU_REG_TICK_COUNTER_3 0x0f
#define PMU_REG_WDT_CTRL 0x10
#define PMU_WDT_CLR_EN_POS 6
#define PMU_WDT_CLR_EN_BIT (1<<6)
#define PMU_WDT_CLR_POS 4
#define PMU_WDT_CLR_BIT (1<<4)
#define PMU_WDT_IRQ_EN_POS 3
#define PMU_WDT_IRQ_EN_BIT (1<<3)
#define PMU_WDT_RST_CPU_POS 2
#define PMU_WDT_RST_CPU_BIT (1<<2)
#define PMU_WDT_RST_CHIP_POS 1
#define PMU_WDT_RST_CHIP_BIT (1<<1)
#define PMU_WDT_EN_POS 0
#define PMU_WDT_EN_BIT (1<<0)
/// timeout counter between wdt interrupt is triggered to reset operation is executed
#define PMU_REG_WDT_TOUT_COUNTER_0 0x11
#define PMU_REG_WDT_TOUT_COUNTER_1 0x12
/// watchdog length
#define PMU_REG_WDT_LEN_0 0x13
#define PMU_REG_WDT_LEN_1 0x14
#define PMU_REG_WDT_LEN_2 0x15
#define PMU_REG_WDT_LEN_3 0x16
#define PMU_REG_RTC_CTRL 0x17
#define PMU_RTC_ALARM_B_EN_POS 5
#define PMU_RTC_ALARM_B_EN_BIT (1<<5)
#define PMU_RTC_ALARM_A_EN_POS 4
#define PMU_RTC_ALARM_A_EN_BIT (1<<4)
#define PMU_RTC_ALARM_B_CLR_POS 3
#define PMU_RTC_ALARM_B_CLR_BIT (1<<3)
#define PMU_RTC_ALARM_A_CLR_POS 2
#define PMU_RTC_ALARM_A_CLR_BIT (1<<2)
#define PMU_RTC_SAMPLE_POS 1
#define PMU_RTC_SAMPLE_BIT (1<<1)
/// reload RTC counter with value set in PMU_REG_RTC_COUNTER_x
#define PMU_RTC_UPD_EN_POS 0
#define PMU_RTC_UPD_EN_BIT (1<<0)
/// write: set RTC counter, read: current RTC counter
#define PMU_REG_RTC_COUNTER_0 0x18
#define PMU_REG_RTC_COUNTER_1 0x19
#define PMU_REG_RTC_COUNTER_2 0x1a
#define PMU_REG_RTC_COUNTER_3 0x1b
/// RTC alarm A target value
#define PMU_REG_ALARM_A_COUNTER_0 0x1c
#define PMU_REG_ALARM_A_COUNTER_1 0x1d
#define PMU_REG_ALARM_A_COUNTER_2 0x1e
#define PMU_REG_ALARM_A_COUNTER_3 0x1f
/// RTC alarm B target value
#define PMU_REG_ALARM_B_COUNTER_0 0x20
#define PMU_REG_ALARM_B_COUNTER_1 0x21
#define PMU_REG_ALARM_B_COUNTER_2 0x22
#define PMU_REG_ALARM_B_COUNTER_3 0x23
#define PMU_REG_QDEC_CTRL 0x24
#define PMU_QDEC_SMP_EN_POS 6
#define PMU_QDEC_SMP_EN_BIT (1<<6)
#define PMU_QDEC_DEB_EN_POS 4
#define PMU_QDEC_DEB_EN_MSK (0x3<<4)
#define PMU_QDEC_RST_PROC_POS 3
#define PMU_QDEC_RST_PROC_MSK (0x1<<3)
#define PMU_QDEC_3x_EN_POS 2
#define PMU_QDEC_3x_EN_BIT (0x1<<2)
#define PMU_QDEC_CNT_MODE_POS 0
#define PMU_QDEC_CNT_MODE_MSK (0x3<<0)
#define PMU_REG_QDEC_CLR 0x25
#define PMU_QDEC_INT_CLR_POS 4
#define PMU_QDEC_INT_CLR_BIT (1<<4)
#define PMU_QDEC_INT_EN_POS 0
#define PMU_QDEC_INT_EN_MSK (0x3<<0)
#define PMU_REG_QDEC_CNT_LEN 0x26
#define PMU_REG_QDEC_DEB_LEN 0x27
#define PMU_REG_QDEC_DINAB_MUX 0x28
#define PMU_REG_QDEC_CNTA_VAL 0x29
#define PMU_REG_QDEC_CNTB_VAL 0x2a
#define PMU_REG_INT_MASK 0x32
#define PMU_OTD_INT_MASK_POS 15
#define PMU_OTD_INT_MASK_BIT (1<<15)
#define PMU_BATFULL_INT_MASK_POS 12
#define PMU_BATFULL_INT_MASK_BIT (1<<12)
#define PMU_CHG_ACOK_INT_MASK_POS 11
#define PMU_CHG_ACOK_INT_MASK_BIT (1<<11)
#define PMU_LVD_INT_MASK_POS 10
#define PMU_LVD_INT_MASK_BIT (1<<10)
#define PMU_ADKEY1_INT_MASK_POS 9
#define PMU_ADKEY1_INT_MASK_BIT (1<<9)
#define PMU_ADKEY0_INT_MASK_POS 8
#define PMU_ADKEY0_INT_MASK_BIT (1<<8)
#define PMU_GPIO_PMU_INT_MSK_POS 7
#define PMU_GPIO_PMU_INT_MSK_BIT (1<<7)
#define PMU_GPIO_GROUPL_INT_MSK_POS 6
#define PMU_GPIO_GROUPL_INT_MSK_BIT (1<<6)
#define PMU_GPIO_GROUPH_INT_MSK_POS 5
#define PMU_GPIO_GROUPH_INT_MSK_BIT (1<<5)
#define PMU_KEYSCAN_INT_MSK_POS 3
#define PMU_KEYSCAN_INT_MSK_BIT (1<<3)
#define PMU_RTC_B_INT_MSK_POS 2
#define PMU_RTC_B_INT_MSK_BIT (1<<2)
#define PMU_RTC_A_INT_MSK_POS 1
#define PMU_RTC_A_INT_MSK_BIT (1<<1)
#define PMU_WDT_INT_MSK_POS 0
#define PMU_WDT_INT_MSK_BIT (1<<0)
#define PMU_REG_INT_RAW 0x34
#define PMU_OTD_INT_RAW_POS 15
#define PMU_OTD_INT_RAW_BIT (1<<15)
#define PMU_BATFULL_INT_RAW_POS 12
#define PMU_BATFULL_INT_RAW_BIT (1<<12)
#define PMU_CHG_ACOK_INT_RAW_POS 11
#define PMU_CHG_ACOK_INT_RAW_BIT (1<<11)
#define PMU_LVD_INT_RAW_POS 10
#define PMU_LVD_INT_RAW_BIT (1<<10)
#define PMU_ADKEY1_INT_RAW_POS 9
#define PMU_ADKEY1_INT_RAW_BIT (1<<9)
#define PMU_ADKEY0_INT_RAW_POS 8
#define PMU_ADKEY0_INT_RAW_BIT (1<<8)
#define PMU_GPIO_PMU_INT_RAW_POS 7
#define PMU_GPIO_PMU_INT_RAW_BIT (1<<7)
#define PMU_GPIO_GROUPB_INT_RAW_POS 6
#define PMU_GPIO_GROUPB_INT_RAW_BIT (1<<6)
#define PMU_GPIO_GROUPA_INT_RAW_POS 5
#define PMU_GPIO_GROUPA_INT_RAW_BIT (1<<5)
#define PMU_KEYSCAN_INT_RAW_POS 3
#define PMU_KEYSCAN_INT_RAW_BIT (1<<3)
#define PMU_RTC_B_INT_RAW_POS 2
#define PMU_RTC_B_INT_RAW_BIT (1<<2)
#define PMU_RTC_A_INT_RAW_POS 1
#define PMU_RTC_A_INT_RAW_BIT (1<<1)
#define PMU_WDT_INT_RAW_POS 0
#define PMU_WDT_INT_RAW_BIT (1<<0)
#define PMU_REG_INT_STATUS 0x36
#define PMU_OTD_INT_STATUS_POS 15
#define PMU_OTD_INT_STATUS_BIT (1<<15)
#define PMU_BATFULL_INT_STATUS_POS 12
#define PMU_BATFULL_INT_STATUS_BIT (1<<12)
#define PMU_CHG_ACOK_INT_STATUS_POS 11
#define PMU_CHG_ACOK_INT_STATUS_BIT (1<<11)
#define PMU_LVD_INT_STATUS_POS 10
#define PMU_LVD_INT_STATUS_BIT (1<<10)
#define PMU_ADKEY1_INT_STATUS_POS 9
#define PMU_ADKEY1_INT_STATUS_BIT (1<<9)
#define PMU_ADKEY0_INT_STATUS_POS 8
#define PMU_ADKEY0_INT_STATUS_BIT (1<<8)
#define PMU_GPIO_PMU_INT_STATUS_POS 7
#define PMU_GPIO_PMU_INT_STATUS_BIT (1<<7)
#define PMU_GPIO_GROUPL_INT_STATUS_POS 6
#define PMU_GPIO_GROUPL_INT_STATUS_BIT (1<<6)
#define PMU_GPIO_GROUPH_INT_STATUS_POS 5
#define PMU_GPIO_GROUPH_INT_STATUS_BIT (1<<5)
#define PMU_KEYSCAN_INT_STATUS_POS 3
#define PMU_KEYSCAN_INT_STATUS_BIT (1<<3)
#define PMU_RTC_B_INT_STATUS_POS 2
#define PMU_RTC_B_INT_STATUS_BIT (1<<2)
#define PMU_RTC_A_INT_STATUS_POS 1
#define PMU_RTC_A_INT_STATUS_BIT (1<<1)
#define PMU_WDT_INT_STATUS_POS 0
#define PMU_WDT_INT_STATUS_BIT (1<<0)
#define PMU_REG_ANA_STATUS 0x38
#define PMU_OTD_STATUS_POS 7
#define PMU_OTD_STATUS_BIT (1<<7)
#define PMU_BATFULL_STATUS_POS 4
#define PMU_BATFULL_STATUS_BIT (1<<4)
#define PMU_CHG_ACOK_STATUS_POS 3
#define PMU_CHG_ACOK_STATUS_BIT (1<<3)
#define PMU_LVD_STATUS_POS 2
#define PMU_LVD_STATUS_BIT (1<<2)
#define PMU_ADKEY1_STATUS_POS 1
#define PMU_ADKEY1_STATUS_BIT (1<<1)
#define PMU_ADKEY0_STATUS_POS 0
#define PMU_ADKEY0_STATUS_BIT (1<<0)
#define PMU_REG_ANA_LEVEL 0x39
#define PMU_OTD_LEVEL_POS 7
#define PMU_OTD_LEVEL_BIT (1<<7)
#define PMU_BATFULL_LEVEL_POS 4
#define PMU_BATFULL_LEVEL_BIT (1<<4)
#define PMU_CHG_ACOK_LEVEL_POS 3
#define PMU_CHG_ACOK_LEVEL_BIT (1<<3)
#define PMU_LVD_LEVEL_POS 2
#define PMU_LVD_LEVEL_BIT (1<<2)
#define PMU_ADKEY1_LEVEL_POS 1
#define PMU_ADKEY1_LEVEL_BIT (1<<1)
#define PMU_ADKEY0_LEVEL_POS 0
#define PMU_ADKEY0_LEVEL_BIT (1<<0)
#define PMU_REG_CHG_ACOK_FILTER 0x3C
#define PMU_REG_BAT_FULL_FILTER 0x3D
#define PMU_REG_OTD_FILTER 0x3F
#define PMU_REG_ANA_INT_EN 0x40
#define PMU_OTD_INT_EN_POS 7
#define PMU_OTD_INT_EN_BIT (1<<7)
#define PMU_BATFULL_INT_EN_POS 4
#define PMU_BATFULL_INT_EN_BIT (1<<4)
#define PMU_CHG_ACOK_INT_EN_POS 3
#define PMU_CHG_ACOK_INT_EN_BIT (1<<3)
#define PMU_LVD_INT_EN_POS 2
#define PMU_LVD_INT_EN_BIT (1<<2)
#define PMU_ADKEY1_INT_EN_POS 1
#define PMU_ADKEY1_INT_EN_BIT (1<<1)
#define PMU_ADKEY0_INT_EN_POS 0
#define PMU_ADKEY0_INT_EN_BIT (1<<0)
#define PMU_REG_ANA_INT_CLR 0x41
#define PMU_OTD_INT_CLR_POS 7
#define PMU_OTD_INT_CLR_BIT (1<<7)
#define PMU_BATFULL_INT_CLR_POS 4
#define PMU_BATFULL_INT_CLR_BIT (1<<4)
#define PMU_CHG_ACOK_INT_CLR_POS 3
#define PMU_CHG_ACOK_INT_CLR_BIT (1<<3)
#define PMU_LVD_INT_CLR_POS 2
#define PMU_LVD_INT_CLR_BIT (1<<2)
#define PMU_ADKEY1_INT_CLR_POS 1
#define PMU_ADKEY1_INT_CLR_BIT (1<<1)
#define PMU_ADKEY0_INT_CLR_POS 0
#define PMU_ADKEY0_INT_CLR_BIT (1<<0)
#define PMU_REG_PIN_INPUT_EN 0x42
#define PMU_REG_PIN_PULL_EN 0x44
#define PMU_REG_PIN_PULL_SEL 0x46
#define PMU_REG_PIN_DATA 0x48
#define PMU_REG_PIN_OUTPUT_EN 0x4a
#define PMU_REG_PIN_XOR_EN 0x4c
#define PMU_REG_PIN_LAST_V 0x4e
#define PMU_REG_PIN_XOR_RESULT 0x50
#define PMU_REG_PIN_XOR_CLR 0x52
#define PMU_REG_PIN_INT_EN 0x54
#define PMU_REG_WKUP_INT_EN 0x57
#define PMU_REG_WKUP_INT_CLR 0x58
#define PMU_REG_PIN_IOMUX_L 0x59
#define PMU_REG_PIN_IOMUX_M 0x5a
#define PMU_REG_PIN_IOMUX_H 0x5b
// CPU reset vector = {1'b0, PMU_REG_CPU_RESET_VECTOR, 7'b0}
#define PMU_REG_CPU_RESET_VECTOR 0x5c
#define PMU_REG_PMU_GATE_L 0x60
#define PMU_REG_PMU_GATE_M 0x61
#define PMU_REG_PMU_GATE_H 0x62
#define PMU_REG_PKSRAM_MASK 0x6a
#define PMU_REG_PKSRAM_GATE 0x6e
#define PMU_REG_PMU_ONOFF_CNT 0x70
#define PMU_REG_BBG_ONOFF_CNT 0x71
#define PMU_REG_SYSBUCK_ONOFF_CNT 0x72
#define PMU_REG_IOBUCK_ONOFF_CNT 0x73
#define PMU_REG_IOLDO1_ONOFF_CNT 0x74
#define PMU_REG_IOLDO2_ONOFF_CNT 0x75
#define PMU_REG_APPDLDO_ONOFF_CNT 0x76
#define PMU_REG_DSPDLDO_ONOFF_CNT 0x77
#define PMU_REG_PKSTPD_ONOFF_CNT 0x78
#define PMU_REG_MEMPK_ONOFF_CNT 0x79
#define PMU_REG_MEMPD_ONOFF_CNT 0x7a
#define PMU_REG_OSCLDO_ONOFF_CNT 0x7b
#define PMU_REG_OSC_ONOFF_CNT 0x7c
#define PMU_REG_RC24PD_ONOFF_CNT 0x7d
#define PMU_REG_RAMPK_ONOFF_CNT 0x7e
#define PMU_REG_PMUISO_ONOFF_CNT 0x7f
#define PMU_REG_IOISO_ONOFF_CNT 0x80
#define PMU_REG_IORTON_ONOFF_CNT 0x81
#define PMU_REG_IOSNS_ONOFF_CNT 0x82
#define PMU_REG_RSTN_ONOFF_CNT 0x83
#define PMU_REG_DIAG_CTRL 0x8f
#define PMU_DIAG_EN_POS 7
#define PMU_DIAG_EN_BIT (1<<7)
#define PMU_DIAG_SEL_LSB 0
#define PMU_DIAG_SEL_MSK 0x0f
#define PMU_REG_APP_DLDO_CTRL 0xc2
#define PMU_REG_AULDO_CTL 0xc3
#define PMU_AULDO_CTL_PD_POS 7
#define PMU_AULDO_CTL_PD_BIT (1<<7)
#define PMU_REG_BBG_CTL 0xc6
#define PMU_BBG_CTL_VBE_EN_POS 3
#define PMU_BBG_CTL_VBE_EN_BIT (1<<3)
#define PMU_REG_CHG_CFG_C8 0xc8
#define PMU_CHG_CFG_CUR_POS 0
#define PMU_CHG_CFG_CUR_MASK 0x3F
#define PMU_REG_CHG_CFG_CB 0xcb
#define PMU_CHG_CFG_END_VOL_POS 4
#define PMU_CHG_CFG_END_VOL_MASK 0x7
#define PMU_REG_CHG_CFG_CD 0xcd
#define PMU_CHG_CFG_ENABLE_POS 3
#define PMU_CHG_CFG_ENABLE_BIT (1<<3)
#define PMU_CHG_CFG_REF_SEL_POS 1
#define PMU_CHG_CFG_REF_SEL_BIT (1<<1)
#define PMU_REG_DSP_DLDO_CTRL 0xd0
#define PMU_REG_IOBUCK_CTRL_0 0xd2
#define PMU_REG_IOBUCK_CTRL_1 0xd3
#define PMU_REG_IOBUCK_CTRL_2 0xd4
#define PMU_REG_IOBUCK_CTRL_3 0xd5
#define PMU_REG_IOBUCK_CTRL_4 0xd6
#define PMU_REG_IOBUCK_CTRL_5 0xd7
#define PMU_REG_IOBUCK_CTRL_6 0xd8
#define PMU_REG_IOBUCK_CTRL_7 0xd9
#define PMU_REG_IOBUCK_CTRL_8 0xda
#define PMU_REG_SYSBUCK_CTRL_0 0xdb
#define PMU_REG_SYSBUCK_CTRL_1 0xdc
#define PMU_REG_SYSBUCK_CTRL_2 0xdd
#define PMU_REG_SYSBUCK_CTRL_3 0xde
#define PMU_REG_SYSBUCK_CTRL_4 0xdf
#define PMU_REG_SYSBUCK_CTRL_5 0xe0
#define PMU_REG_SYSBUCK_CTRL_6 0xe1
#define PMU_REG_SYSBUCK_CTRL_7 0xe2
#define PMU_REG_SYSBUCK_CTRL_8 0xe3
#define PMU_REG_IOLDO1_CTRL_0 0xe4
#define PMU_REG_IOLDO1_CTRL_1 0xe5
#define PMU_REG_IOLDO2_CTRL_0 0xe6
#define PMU_REG_IOLDO2_CTRL_1 0xe7
#define PMU_REG_OSC_CTRL_0 0xe9
#define PMU_REG_OSC_CTRL_1 0xea
#define PMU_REG_OSC_CTRL_2 0xeb
#define PMU_REG_OSC_CTRL_3 0xec
#define PMU_REG_OSC_CTRL_4 0xed
#define PMU_REG_OSC_CTRL_5 0xee
#define PMU_REG_PKVDD_CTRL 0xef
#define PMU_REG_PKVDDH_CTRL_0 0xf0
#define PMU_REG_PKVDDH_CTRL_1 0xf1
#define PMU_REG_SBG_CFG 0xf3
#define PMU_REG_ADC_CTL 0xf8
#define PMU_ADC_CTL_POWER_POS 2
#define PMU_ADC_CTL_POWER_BIT (1<<2)
/** @addtogroup PMU_Initialization_Config_Section
* @{
*/
/* ################################ Initialization Config Section Start ################################ */
/* PMU PIN index */
typedef enum
{
PMU_PIN_0 = 0x0001,
PMU_PIN_1 = 0x0002,
PMU_PIN_2 = 0x0004,
PMU_PIN_3 = 0x0008,
PMU_PIN_4 = 0x0010,
PMU_PIN_5 = 0x0020,
PMU_PIN_6 = 0x0040,
PMU_PIN_7 = 0x0080,
PMU_PIN_8 = 0x0100,
PMU_PIN_9 = 0x0200,
}enum_PMU_PINx_t;
typedef enum
{
PMU_GPIO_NO_PULL,
PMU_GPIO_PULL_UP,
PMU_GPIO_PULL_DOWN,
}enum_PMU_GPIO_PULL_t;
typedef enum
{
PMU_GPIO_MODE_INPUT,
PMU_GPIO_MODE_OUTPUT,
}enum_PMU_GPIO_MODE_t;
typedef enum
{
PMU_LVD_THD_1_9,
PMU_LVD_THD_2_0,
PMU_LVD_THD_2_1,
PMU_LVD_THD_2_2,
PMU_LVD_THD_2_8,
PMU_LVD_THD_3_0,
PMU_LVD_THD_3_2,
PMU_LVD_THD_3_4,
}enum_PMU_LVD_THD_t;
typedef enum
{
PMU_WDT_IRQ,
PMU_WDT_RST_CHIP,
}enum_PMU_WDT_MODE_t;
typedef enum
{
PMU_CHG_END_VOL_4_1, /* charge end voltage select 4.1V */
PMU_CHG_END_VOL_4_1_5, /* charge end voltage select 4.15V */
PMU_CHG_END_VOL_4_2, /* charge end voltage select 4.2V */
PMU_CHG_END_VOL_4_2_5, /* charge end voltage select 4.25V */
PMU_CHG_END_VOL_4_3, /* charge end voltage select 4.3V */
PMU_CHG_END_VOL_4_3_5, /* charge end voltage select 4.35V */
PMU_CHG_END_VOL_4_4, /* charge end voltage select 4.4V */
}enum_PMU_charge_end_vol_t;
typedef enum
{
PMU_CHG_CUR_2mA = 0x00, /* charge current select 2mA */
PMU_CHG_CUR_7mA = 0x01, /* charge current select 7mA */
PMU_CHG_CUR_12mA = 0x02, /* charge current select 12mA */
PMU_CHG_CUR_17mA = 0x03, /* charge current select 17mA */
PMU_CHG_CUR_23mA = 0x04, /* charge current select 23mA */
PMU_CHG_CUR_28mA = 0x05, /* charge current select 28mA */
PMU_CHG_CUR_38mA = 0x07, /* charge current select 38mA */
PMU_CHG_CUR_48mA = 0x09, /* charge current select 48mA */
PMU_CHG_CUR_58mA = 0x0B, /* charge current select 58mA */
PMU_CHG_CUR_68mA = 0x0D, /* charge current select 68mA */
PMU_CHG_CUR_78mA = 0x0F, /* charge current select 78mA */
PMU_CHG_CUR_88mA = 0x11, /* charge current select 88mA */
PMU_CHG_CUR_103mA = 0x14, /* charge current select 103mA */
PMU_CHG_CUR_123mA = 0x18, /* charge current select 123mA */
PMU_CHG_CUR_143mA = 0x1C, /* charge current select 143mA */
PMU_CHG_CUR_160mA = 0x20, /* charge current select 160mA */
PMU_CHG_CUR_180mA = 0x24, /* charge current select 180mA */
PMU_CHG_CUR_204mA = 0x29, /* charge current select 204mA */
PMU_CHG_CUR_237mA = 0x30, /* charge current select 237mA */
PMU_CHG_CUR_255mA = 0x34, /* charge current select 255mA */
PMU_CHG_CUR_280mA = 0x39, /* charge current select 280mA */
PMU_CHG_CUR_300mA = 0x3F, /* charge current select 300mA */
}enum_PMU_charge_current_t;
typedef enum
{
PMU_CHARGING_IN,
PMU_CHARGING_OUT,
}enum_PMU_charge_type_t;
typedef enum
{
PMU_BATTERY_FULL,
PMU_BATTERY_NOT_FULL,
}enum_PMU_battery_type_t;
/* ################################ Initialization Config Section END ################################## */
/**
* @}
*/
void pmu_init(void);
void pmu_set_pin_pull(enum_PMU_PINx_t bits, enum_PMU_GPIO_PULL_t type);
void pmu_set_pin_dir(enum_PMU_PINx_t bits, enum_PMU_GPIO_MODE_t dir);
void pmu_set_pin_value(enum_PMU_PINx_t bits, uint8_t value);
uint8_t pmu_get_pin_value(enum_PMU_PINx_t bit);
void pmu_port_wakeup_func_set(enum_PMU_PINx_t bits);
void pmu_port_wakeup_func_clear(enum_PMU_PINx_t bits);
void pmu_gpio_int_init(enum_PMU_PINx_t bits, enum_PMU_GPIO_PULL_t pull, uint8_t init_value);
void pmu_enable_isr(uint16_t isr_map);
void pmu_disable_isr(uint16_t isr_map);
uint16_t pmu_get_isr_state(void);
void pmu_clear_isr_state(uint16_t state_map);
void pmu_lp_rc_calib(uint32_t lp_rc_counter, uint32_t hp_osc_counter);
extern uint32_t pmu_lp_rc_get(void);
void pmu_lvd_enable(enum_PMU_LVD_THD_t thd);
void pmu_lvd_disable(void);
void pmu_adc_power_ctrl(bool enable);
void pmu_vbe_power_ctrl(bool enable);
void pmu_auldo_power_ctrl(bool enable);
void pmu_charge_enable(enum_PMU_charge_current_t cur, enum_PMU_charge_end_vol_t vol);
void pmu_charge_disable(void);
void pmu_charge_monitor_en(enum_PMU_charge_type_t charge_type);
void pmu_battery_full_monitor_en(enum_PMU_battery_type_t battery_type);
#endif // _DRIVER_PMU_H

View File

@ -0,0 +1,81 @@
/*
******************************************************************************
* @file driver_pmu_iwdt.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2023
* @brief Header file of PMU IWDT HAL module.
******************************************************************************
* @attention
*
* Copyright (c) 2023 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_PMU_IWDT_H__
#define __DRIVER_PMU_IWDT_H__
#include "fr30xx.h"
/** @addtogroup IWDT_Initialization_Config_Section
* @{
*/
/* ################################ Initialization/config Section Start ################################ */
enum IWDT_INT_t
{
WDT_INT_ENABLE = 0x08,
WDT_INT_DISABLE = 0x00,
};
/**
* @brief iwdt Initialization Structure definition
*/
typedef struct
{
uint32_t iwdt_Count; /* The watchdog initializes the count value.
An interrupt can be generated when the count value is reached.
This parameter can be a 32-bit Size. */
uint16_t iwdt_Timeout; /* The watchdog Timeout reset count value.
When the count value is reached, the timeout counter is starting.
Timeout triggers the system reset.
Attention: Timeout Set to 0 the system will not reset.
This parameter can be a 16-bit Size */
uint32_t iwdt_int_Enable; /* This parameter can be a value of @ref IWDT_INT_t */
}iwdt_Init_t;
/* ################################ Initialization/config Section END ################################## */
/**
* @}
*/
/* Exported functions --------------------------------------------------------*/
/* iwdt_init */
void iwdt_init(iwdt_Init_t Init);
/* iwdt_Enable */
/* iwdt_Disable */
void iwdt_Enable(void);
void iwdt_Disable(void);
/* iwdt_Refresh */
void iwdt_Refresh(void);
/* iwdt_Interrupt_Enable */
/* iwdt_Interrupt_Disable */
void iwdt_Interrupt_Enable(void);
void iwdt_Interrupt_Disable(void);
/* iwdt_Set_Count */
void iwdt_Set_Count(uint32_t iwdtCount);
/* iwdt_Set_Timeout */
void iwdt_Set_Timeout(uint16_t iwdtTimeout);
#endif

View File

@ -0,0 +1,80 @@
/*
******************************************************************************
* @file driver_pmu_rtc.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2023
* @brief Header file of pmu rtc HAL module.
******************************************************************************
* @attention
*
* Copyright (c) 2023 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_PMU_RTC_H__
#define __DRIVER_PMU_RTC_H__
#include "fr30xx.h"
/** @addtogroup RTC_Initialization_Config_Section
* @{
*/
/* ################################ Initialization<6F><6E>Config Section Start ################################ */
typedef struct
{
uint32_t UnitBackup;
}str_Time_t;
typedef enum
{
AlARM_A = 0x10,
AlARM_B = 0x20,
}enum_Alarm_t;
/* ################################ Initialization<6F><6E>Config Section END ################################## */
/**
* @}
*/
/* Exported functions --------------------------------------------------------*/
/* rtc_AlarmA_Handler */
/* rtc_AlarmB_Handler */
void rtc_AlarmA_Handler(void);
void rtc_AlarmB_Handler(void);
/* rtc_init */
void rtc_init(uint32_t InitValue);
/* rtc_CountEnable */
/* rtc_CountDisable */
void rtc_CountEnable(void);
void rtc_CountDisable(void);
/* rtc_AlarmConfig */
void rtc_AlarmConfig(enum_Alarm_t fe_Alarm, uint32_t fu32_hour, uint32_t fu32_Minute, uint32_t fu32_Second);
/* rtc_GetCount */
uint32_t rtc_GetCount(void);
/* rtc_CountUpdate */
void rtc_CountUpdate(uint32_t fu32_CountValue);
/* rtc_AlarmUpdate */
void rtc_AlarmUpdate(enum_Alarm_t fe_Alarm);
/* rtc_AlarmEnable */
/* rtc_AlarmDisable */
void rtc_AlarmEnable(enum_Alarm_t fe_Alarm);
void rtc_AlarmDisable(enum_Alarm_t fe_Alarm);
/* rtc_AlarmRead */
/* rtc_AlarmSet */
uint32_t rtc_AlarmRead(enum_Alarm_t fe_Alarm);
void rtc_AlarmSet(enum_Alarm_t fe_Alarm, uint32_t fu32_CountValue);
#endif

View File

@ -0,0 +1,248 @@
/*
******************************************************************************
* @file driver_pwm.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief Header file of PWM HAL module.
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_PWM_H__
#define __DRIVER_PWM_H__
#include "fr30xx.h"
/** @addtogroup PWM_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
/* PWM Output ctrl register */
typedef struct
{
uint32_t OutputEN : 16;
uint32_t Output_ctrl : 16;
}REG_PWMOutput_t;
/* Posedge<67><65>Negedeg register */
typedef struct
{
uint32_t Posedge;
uint32_t Negedeg;
}REG_PWMedge_t;
/* capture control register */
typedef struct
{
uint32_t Capture_Mode : 8;
uint32_t Capture_EN : 8;
uint32_t rsv_0 : 16;
}REG_CaptureCtrl_t;
/* PWM Update control register */
typedef struct
{
uint32_t PWM_Update : 16;
uint32_t PWM_Status : 16;
}REG_PWMUpdate_t;
/* Prescale<6C><65>Period register */
typedef struct
{
uint32_t Prescale;
uint32_t Period;
}REG_PWMFrequency_t;
/* -----------------------------------------------*/
/* PWM Register */
/* -----------------------------------------------*/
typedef struct
{
volatile uint32_t rsv_0;
volatile REG_PWMOutput_t OutputEN; /* Offset 0x04 */
volatile uint32_t ChannelEN; /* Offset 0x08 */
volatile uint32_t rsv_1;
volatile REG_PWMedge_t Edge[16]; /* Offset 0x10 ~ 0x8C */
volatile uint32_t OutputSelect; /* Offset 0x90 */
volatile uint32_t CapturePrescale; /* Offset 0x94 */
volatile uint32_t CaptureStatus; /* Offset 0x98 */
volatile uint32_t CaptureINTEN; /* Offset 0x9C */
volatile REG_CaptureCtrl_t CaptureCtrl; /* Offset 0xA0 */
volatile uint32_t CaptureValue[8]; /* Offset 0xA4 ~ 0xE0 */
volatile uint32_t rsv_2[8];
volatile REG_PWMUpdate_t Update; /* Offset 0xE4 */
volatile uint32_t DACMode; /* Offset 0xE8 */
volatile uint32_t rsv_3;
volatile uint32_t OutputValue; /* Offset 0xF0 */
volatile uint32_t rsv_4;
volatile uint32_t InverterEN; /* Offset 0xF8 */
volatile uint32_t CNT_EN; /* Offset 0xFC */
volatile REG_PWMFrequency_t Frequency[16]; /* Offset 0x100 ~ 0x17C */
}struct_PWM_t;
#define PWM0 ((struct_PWM_t *)PWM0_BASE)
#define PWM1 ((struct_PWM_t *)PWM1_BASE)
/* ################################ Register Section END ################################## */
/**
* @}
*/
/** @addtogroup PWM_Initialization_Config_Section
* @{
*/
/* ################################ Initialization<6F><6E>Config Section Start ################################ */
/* PWM Channel */
typedef enum
{
PWM_CHANNEL_0 = 0x0001,
PWM_CHANNEL_1 = 0x0002,
PWM_CHANNEL_2 = 0x0004,
PWM_CHANNEL_3 = 0x0008,
PWM_CHANNEL_4 = 0x0010,
PWM_CHANNEL_5 = 0x0020,
PWM_CHANNEL_6 = 0x0040,
PWM_CHANNEL_7 = 0x0080,
PWM_CHANNEL_8 = 0x0100,
PWM_CHANNEL_9 = 0x0200,
PWM_CHANNEL_10 = 0x0400,
PWM_CHANNEL_11 = 0x0800,
PWM_CHANNEL_12 = 0x1000,
PWM_CHANNEL_13 = 0x2000,
PWM_CHANNEL_14 = 0x4000,
PWM_CHANNEL_15 = 0x8000,
}enum_PWMChannel_t;
/* Inverter Enable */
typedef enum
{
Inverter_Enable, /* output Inverter enable */
Inverter_Disable, /* output Inverter disable */
}enum_InverterEN_t;
/* Capture_Prescale */
typedef enum
{
CAPTURE_DIV_1,
CAPTURE_DIV_2,
CAPTURE_DIV_4,
CAPTURE_DIV_8,
CAPTURE_DIV_16,
CAPTURE_DIV_32,
CAPTURE_DIV_64,
CAPTURE_DIV_128,
CAPTURE_DIV_256,
CAPTURE_DIV_512,
CAPTURE_DIV_1024,
CAPTURE_DIV_2048,
}enum_CapturePrescale_t;
/* Capture Mode */
typedef enum
{
MODE_LOOP, /* Loop trigger */
MODE_SINGLE, /* Single trigger */
}enum_CaptureMode_t;
/*
* @brief PWM mode config parameter
*/
typedef struct
{
uint16_t Prescale; /* Clock = APB_Clock / Prescale */
uint16_t Period; /* Period = Clock * PWM_Period */
uint16_t Posedge; /* The position of the rising edge in the period */
uint16_t Negedge; /* The position of the falling edge in the period */
}struct_PWM_Config_t;
/*
* @brief PWM complementary config parameter
*/
typedef struct
{
uint16_t Prescale; /* Clock = APB_Clock / Prescale */
uint16_t Period; /* Period = Clock * PWM_Period */
uint16_t DutyCycle; /* Low level hold time in one period */
uint16_t MianDeadTime; /* Mian Channel dead-time */
uint16_t CompDeadTime; /* complementary Channel dead-time */
}struct_PWM_Complementary_Config_t;
/*
* @brief Capture mode config parameter
*/
typedef struct
{
uint32_t CapturePrescale; /* This parameter can be a value of @ref enum_CapturePrescale_t */
uint32_t CaptureMode; /* This parameter can be a value of @ref enum_CaptureMode_t */
}struct_Capture_Config_t;
/* ################################ Initialization<6F><6E>Config Section END ################################## */
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
/* PWM mode. output inverter Enable/Disable */
#define __PWM_INVERTER_ENABLE(__PWMx__, __CHANNEL__) (__PWMx__->InverterEN |= (__CHANNEL__))
#define __PWM_INVERTER_DISABLE(__PWMx__, __CHANNEL__) (__PWMx__->InverterEN &= ~(__CHANNEL__))
/* Capture mode. Capture interrupt Enable/Disable/Clear */
#define __PWM_CAPTURE_INT_ENABLE(__PWMx__, __CHANNEL__) (__PWMx__->CaptureINTEN |= (__CHANNEL__))
#define __PWM_CAPTURE_INT_DISABLE(__PWMx__, __CHANNEL__) (__PWMx__->CaptureINTEN &= ~(__CHANNEL__))
#define __PWM_CAPTURE_INT_CLEAR(__PWMx__, __CHANNEL__) (__PWMx__->CaptureStatus |= (__CHANNEL__))
/* Exported functions --------------------------------------------------------*/
/*------------------------------------------------------------*/
/*------------------ PWM Mode functions ------------------*/
/*------------------ PWM_DAC Mode functions ------------------*/
/*------------------------------------------------------------*/
/* pwm_config */
void pwm_config(struct_PWM_t *PWMx, uint16_t fu16_channel, struct_PWM_Config_t fstr_Config);
/* pwm_complementary_config */
bool pwm_complementary_config(struct_PWM_t *PWMx, uint16_t fu16_MainChannel, uint16_t ComplementaryChannel, struct_PWM_Complementary_Config_t fstr_Config);
/* pwm_output_enable/disable */
void pwm_output_enable(struct_PWM_t *PWMx, uint16_t fu16_channel);
void pwm_output_disable(struct_PWM_t *PWMx, uint16_t fu16_channel);
/* pwm_output_status */
bool pwm_output_status(struct_PWM_t *PWMx, enum_PWMChannel_t fe_channel);
/* pwm_output_updata */
void pwm_output_updata(struct_PWM_t *PWMx, uint16_t fu16_channel);
/*------------------------------------------------------------*/
/*------------------ Capture Mode functions ------------------*/
/*------------------------------------------------------------*/
/* pwm_capture_config */
void pwm_capture_config(struct_PWM_t *PWMx, uint16_t fu16_channel, struct_Capture_Config_t fstr_Config);
/* capture_enable/disable */
void pwm_capture_enable(struct_PWM_t *PWMx, uint16_t fu16_channel);
void pwm_capture_disable(struct_PWM_t *PWMx, uint16_t fu16_channel);
/* pwm_capture_status */
bool pwm_capture_status(struct_PWM_t *PWMx, enum_PWMChannel_t fe_channel);
/* pwm_capture_status_clear */
void pwm_capture_status_clear(struct_PWM_t *PWMx, enum_PWMChannel_t fe_channel);
/* pwm_capture_value */
uint32_t pwm_capture_value(struct_PWM_t *PWMx, enum_PWMChannel_t fe_channel);
#endif

View File

@ -0,0 +1,458 @@
/*
******************************************************************************
* @file driver_qspi.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief Header file of QSPI HAL module.
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_QSPI_H__
#define __DRIVER_QSPI_H__
#include "fr30xx.h"
/** @addtogroup QSPI_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
struct qspi_config_reg_t { //@0x00
uint32_t enable:1;
uint32_t cpol:1;
uint32_t cpha:1;
uint32_t reserved0:1;
uint32_t octal_xccela:1;
uint32_t octal_opi:1;
uint32_t octal_div2:1;
uint32_t enable_DAC:1; //direct access controller
uint32_t enable_legacy:1;
uint32_t peri_sel:1;
uint32_t peri_sel_line:4; //<2F><>peri_sel<65><6C><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>
uint32_t write_en_pin:1;
uint32_t enable_DMA:1;
uint32_t enable_AHB_remap:1;
uint32_t enable_XIP_next_R:1; //enter XIP Mode on next READ
uint32_t enalbe_XIP:1; //enter XIP Mode immediately
uint32_t baud_rate:4;
uint32_t enable_AHB_decoder:1;
uint32_t enable_DTR_prot:1;
uint32_t reserved1:6;
uint32_t status:1;
};
struct qspi_read_ins_reg_t { //@0x04
uint32_t opcode:8;
uint32_t instruction_type:2;
uint32_t enable_DDR:1;
uint32_t reserved0:1;
uint32_t addr_type:2;
uint32_t reserved1:2;
uint32_t data_type:2;
uint32_t reserved2:2;
uint32_t enable_mode:1;
uint32_t reserved3:3;
uint32_t dummy_cycles:5;
uint32_t reserved4:3;
};
struct qspi_write_ins_reg_t { //@0x08
uint32_t opcode:8;
uint32_t disable_WEL:1;
uint32_t reserved0:3;
uint32_t addr_type:2;
uint32_t reserved1:2;
uint32_t data_type:2;
uint32_t reserved2:6;
uint32_t dummy_cycles:5;
uint32_t reserved3:3;
};
struct qspi_device_delay_reg_t { //@0x0c
uint32_t sel_start_offset:8;
uint32_t sel_end_offset:8;
uint32_t sel_dessert_diff:8;
uint32_t sel_dessert:8;
};
struct qspi_read_cap_reg_t { //@0x10
uint32_t enable_loopback_clk:1;
uint32_t delay_capture:4;
uint32_t sample_edge:1;
uint32_t reserved0:10;
uint32_t delay_trans:4;
uint32_t reserved1:12;
};
struct qspi_device_size_cfg_t { //@0x14
uint32_t addr_bytes:4; //number of address bytes. 0=1byte
uint32_t page_bytes:12; //number of bytes per device page
uint32_t block_bytes:5; //number of bytes per block. bytes = 2^block_bytes
uint32_t CS0_size:2;
uint32_t CS1_size:2;
uint32_t CS2_size:2;
uint32_t CS3_size:2;
uint32_t reserved0:3;
};
struct qspi_dma_peri_cfg_t { //@0x20
uint32_t bytes_per_req:4; //2^bytes_per_req
uint32_t reserved0:4;
uint32_t bytes_per_burst:4; //2^bytes_per_burst
uint32_t reserved1:20;
};
struct qspi_sram_level_reg_t { //@0x2c
uint32_t read_part:16;
uint32_t write_part:16;
};
struct qspi_write_comp_ctrl_reg_t { //@0x38
uint32_t opcode_poll:8;
uint32_t poll_bit_index:3; //the bit index that should be polled
uint32_t reserved0:2;
uint32_t poll_polarity:1;
uint32_t disable_poll:1;
uint32_t enable_expiration:1;
uint32_t poll_count:8;
uint32_t poll_repetition_delay:8;
};
struct qspi_write_protect_reg_t {
uint32_t inversion:1;
uint32_t enable:1;
uint32_t reserved0:30;
};
struct qspi_ind_read_crtl_reg_t { //@0x60
uint32_t start:1;
uint32_t cancel:1;
uint32_t progress_status:1;
uint32_t sram_status:1;
uint32_t queue_status:1;
uint32_t comp_status:1;
uint32_t num_operation_comp:2;
uint32_t reserved0:24;
};
struct qspi_ind_write_crtl_reg_t { //@0x70
uint32_t start:1;
uint32_t cancel:1;
uint32_t progress_status:1;
uint32_t reserved0:1;
uint32_t queue_status:1;
uint32_t comp_status:1;
uint32_t num_operation_comp:2;
uint32_t reserved1:24;
};
struct qspi_stig_mem_reg_t {
uint32_t mem_bank_req:1;
uint32_t mem_bank_status:1;
uint32_t reserved0:6;
uint32_t mem_bank_data:8;
uint32_t mem_bank_req_bytes:3;
uint32_t reserved1:1;
uint32_t mem_bank_addr:9;
uint32_t reserved2:3;
};
struct qspi_stig_reg_t {
uint32_t execute:1;
uint32_t progress_status:1;
uint32_t enable_bank:1;
uint32_t reserved0:4;
uint32_t dummy_cycles:5;
uint32_t write_bytes:3; //0~1bytes
uint32_t enable_write:1;
uint32_t addr_bytes:2; //0~1bytes
uint32_t enable_mode:1;
uint32_t enable_cmd_addr:1;
uint32_t read_bytes:3;
uint32_t enable_read:1;
uint32_t opcode:8;
};
struct qspi_poll_flash_status_t {
uint32_t status:8;
uint32_t valid:1;
uint32_t reserved0:7;
uint32_t dummy_cycles:4;
uint32_t reserved1:12;
};
struct qspi_cs_ctrl_t{
uint32_t rd_brk_en:1;
uint32_t page_boundary_protect_en:1;
uint32_t disable_cs_after_first_byte:1;
uint32_t resv0:13;
uint32_t page_boundary:12;
uint32_t resv1:4;
};
struct qspi_regs_t {
volatile struct qspi_config_reg_t config; //@0x00
volatile struct qspi_read_ins_reg_t read_conf;
volatile struct qspi_write_ins_reg_t write_conf;
volatile struct qspi_device_delay_reg_t delay;
volatile struct qspi_read_cap_reg_t read_cap; //@0x10
volatile struct qspi_device_size_cfg_t size_cfg;
volatile uint32_t sram_part_cfg;
volatile uint32_t AHB_trigger_address;
volatile struct qspi_dma_peri_cfg_t dma_cfg; //@0x20
volatile uint32_t remap_address;
volatile uint32_t mode_bits;
volatile struct qspi_sram_level_reg_t sram_level;
volatile uint32_t tx_threshold; //@0x30
volatile uint32_t rx_threshold;
volatile struct qspi_write_comp_ctrl_reg_t poll_cfg;
volatile uint32_t poll_expiration;
volatile uint32_t int_status; //@0x40
volatile uint32_t int_mask;
uint32_t reserved0[2];
volatile uint32_t lower_write_protect; //@0x50
volatile uint32_t upper_write_protect;
volatile struct qspi_write_protect_reg_t write_protect;
uint32_t reserved1;
volatile struct qspi_ind_read_crtl_reg_t ind_read_ctrl; //@0x60
volatile uint32_t ind_read_watermark;
volatile uint32_t ind_read_start_addr;
volatile uint32_t ind_read_bytes;
volatile struct qspi_ind_write_crtl_reg_t ind_write_ctrl; //@0x70
volatile uint32_t ind_write_watermark;
volatile uint32_t ind_write_start_addr;
volatile uint32_t ind_write_bytes;
volatile uint32_t ind_range_width; //@0x80
uint32_t reserved2[2];
volatile struct qspi_stig_mem_reg_t cmd_ctrl_mem;
volatile struct qspi_stig_reg_t cmd_ctrl; //@0x90
volatile uint32_t cmd_address;
uint32_t reserved3[2];
volatile uint32_t read_data_L; //@0xa0
volatile uint32_t read_data_H;
volatile uint32_t write_data_L;
volatile uint32_t write_data_H;
volatile struct qspi_poll_flash_status_t poll_status; //@0xb0
volatile struct qspi_cs_ctrl_t cs_ctrl;
uint32_t reserved4[17];
volatile uint32_t module_id; //@0xfc
};
#define QSPI0 ((struct qspi_regs_t *)FLASH_QSPI_BASE)
#define QSPI1 ((struct qspi_regs_t *)DSP_QSPI_BASE)
#define OSPI ((struct qspi_regs_t *)PSRAM_OSPI_BASE)
/* ################################ Register Section END ################################## */
/**
* @}
*/
/** @addtogroup QSPI_Initialization_Config_Section
* @{
*/
/* ################################ Initialization<6F><6E>Config Section Start ################################ */
#define QSPI_INT_MODE_FAIL 0x00000001
#define QSPI_INT_UNDERFLOW 0x00000002
#define QSPI_INT_COMP_INDIRECT 0x00000004
#define QSPI_INT_FAIL_INDIRECT 0x00000008
#define QSPI_INT_FAIL_WR_PROTECT 0x00000010
#define QSPI_INT_ILLEGAL_AHB 0x00000020
#define QSPI_INT_INDIRECT_WATER 0x00000040
#define QSPI_INT_OVERFLOW 0x00000080
#define QSPI_INT_TXFF_NOFULL 0x00000100
#define QSPI_INT_TXFF_FULL 0x00000200
#define QSPI_INT_RXFF_NOEMPTY 0x00000400
#define QSPI_INT_RXFF_FULL 0x00000800
#define QSPI_INT_RD_PART_FULL 0x00001000
#define QSPI_INT_POLL_EXPIRED 0x00002000
#define QSPI_INT_COMP_STIG 0x00004000
enum qspi_flash_size_t {
QSPI_FLASH_SIZE_512Mb,
QSPI_FLASH_SIZE_1Gb,
QSPI_FLASH_SIZE_2Gb,
QSPI_FLASH_SIZE_4Gb,
};
enum qspi_mem_bank_bytes_t {
QSPI_MEM_BANK_BYTES_16,
QSPI_MEM_BANK_BYTES_32,
QSPI_MEM_BANK_BYTES_64,
QSPI_MEM_BANK_BYTES_128,
QSPI_MEM_BANK_BYTES_256,
QSPI_MEM_BANK_BYTES_512,
};
enum qspi_wire_type_t {
QSPI_WIRE_TYPE_STAND,
QSPI_WIRE_TYPE_DIO,
QSPI_WIRE_TYPE_QIO,
QSPI_WIRE_TYPE_OIO,
};
enum qspi_baud_rate_t {
QSPI_BAUDRATE_DIV_2,
QSPI_BAUDRATE_DIV_4,
QSPI_BAUDRATE_DIV_6,
QSPI_BAUDRATE_DIV_8,
QSPI_BAUDRATE_DIV_10,
QSPI_BAUDRATE_DIV_12,
QSPI_BAUDRATE_DIV_14,
QSPI_BAUDRATE_DIV_16,
QSPI_BAUDRATE_DIV_18,
QSPI_BAUDRATE_DIV_20,
QSPI_BAUDRATE_DIV_22,
QSPI_BAUDRATE_DIV_24,
QSPI_BAUDRATE_DIV_26,
QSPI_BAUDRATE_DIV_28,
QSPI_BAUDRATE_DIV_30,
QSPI_BAUDRATE_DIV_32,
};
enum qspi_stig_cmd_type_t {
QSPI_STIG_CMD_READ,
QSPI_STIG_CMD_BANK_READ,
QSPI_STIG_CMD_WRITE,
QSPI_STIG_CMD_EXE,
};
enum qspi_stig_addr_bytes_t {
QSPI_STIG_ADDR_BYTES_1,
QSPI_STIG_ADDR_BYTES_2,
QSPI_STIG_ADDR_BYTES_3,
QSPI_STIG_ADDR_BYTES_4,
};
enum qspi_device_addr_bytes_t {
QSPI_DEVICE_ADDR_BYTES_1,
QSPI_DEVICE_ADDR_BYTES_2,
QSPI_DEVICE_ADDR_BYTES_3,
QSPI_DEVICE_ADDR_BYTES_4,
};
/* ################################ Initialization<6F><6E>Config Section END ################################## */
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
/* QSPI Enable/Disable */
#define __QSPI_ENABLE(__QSPIx__) (__QSPIx__->config.enable = 1)
#define __QSPI_DISABLE(__QSPIx__) (__QSPIx__->config.enable = 0)
#define __QSPI_CFG_CPOL_SET(__QSPIx__, __VAULE__) (__QSPIx__->config.cpol = __VAULE__)
#define __QSPI_CFG_CPHA_SET(__QSPIx__, __VAULE__) (__QSPIx__->config.cpha = __VAULE__)
#define __QSPI_CFG_OCTAL_XCCELA_ENABLE(__QSPIx__) (__QSPIx__->config.octal_xccela = 1)
#define __QSPI_CFG_OCTAL_XCCELA_DISABLE(__QSPIx__) (__QSPIx__->config.octal_xccela = 0)
#define __QSPI_CFG_OCTAL_OPI_ENABLE(__QSPIx__) (__QSPIx__->config.octal_opi = 1)
#define __QSPI_CFG_OCTAL_OPI_DISABLE(__QSPIx__) (__QSPIx__->config.octal_opi = 0)
#define __QSPI_CFG_DAC_ENABLE(__QSPIx__) (__QSPIx__->config.enable_DAC = 1)
#define __QSPI_CFG_DAC_DISABLE(__QSPIx__) (__QSPIx__->config.enable_DAC = 0)
#define __QSPI_CFG_LEGACY_ENABLE(__QSPIx__) (__QSPIx__->config.enable_legacy = 1)
#define __QSPI_CFG_LEGACY_DISABLE(__QSPIx__) (__QSPIx__->config.enable_legacy = 0)
#define __QSPI_CFG_WRITE_PROTECT_ENABLE(__QSPIx__) (__QSPIx__->config.write_en_pin = 1)
#define __QSPI_CFG_WRITE_PROTECT_DISABLE(__QSPIx__) (__QSPIx__->config.write_en_pin = 0)
#define __QSPI_CFG_REMAP_ENABLE(__QSPIx__) (__QSPIx__->config.enable_AHB_remap = 1)
#define __QSPI_CFG_REMAP_DISABLE(__QSPIx__) (__QSPIx__->config.enable_AHB_remap = 0)
#define __QSPI_CFG_AHB_DECODER_ENABLE(__QSPIx__) (__QSPIx__->config.enable_AHB_decoder = 1)
#define __QSPI_CFG_AHB_DECODER_DISABLE(__QSPIx__) (__QSPIx__->config.enable_AHB_decoder = 0)
#define __QSPI_CFG_DTR_ENABLE(__QSPIx__) (__QSPIx__->config.enable_DTR_prot = 1)
#define __QSPI_CFG_DTR_DISABLE(__QSPIx__) (__QSPIx__->config.enable_DTR_prot = 0)
#define __QSPI_CFG_BAUDRATE_SET(__QSPIx__, baudrate) (__QSPIx__->config.baud_rate = baudrate)
#define __QSPI_IS_BUSY(__QSPIx__) (__QSPIx__->config.status == 0)
#define __QSPI_READ_OPCODE_SET(__QSPIx__, _opcode) (__QSPIx__->read_conf.opcode = _opcode)
#define __QSPI_READ_INSTRUCTION_TYPE_SET(__QSPIx__, type) (__QSPIx__->read_conf.instruction_type = type)
#define __QSPI_READ_ADDRESS_TYPE_SET(__QSPIx__, type) (__QSPIx__->read_conf.addr_type = type)
#define __QSPI_READ_DATA_TYPE_SET(__QSPIx__, type) (__QSPIx__->read_conf.data_type = type)
#define __QSPI_READ_MODE_ENABLE_SET(__QSPIx__, en) (__QSPIx__->read_conf.enable_mode = en)
#define __QSPI_READ_DUMMY_CYCLES_SET(__QSPIx__, cycles) (__QSPIx__->read_conf.dummy_cycles = cycles)
#define __QSPI_READ_DDR_ENABLE(__QSPIx__) (__QSPIx__->read_conf.enable_DDR = 1)
#define __QSPI_READ_DDR_DISABLE(__QSPIx__) (__QSPIx__->read_conf.enable_DDR = 0)
#define __QSPI_READ_DDR_GET(__QSPIx__) (__QSPIx__->read_conf.enable_DDR)
#define __QSPI_WRITE_OPCODE_SET(__QSPIx__, _opcode) (__QSPIx__->write_conf.opcode = _opcode)
#define __QSPI_WRITE_WEL_ENABLE(__QSPIx__) (__QSPIx__->write_conf.disable_WEL = 0)
#define __QSPI_WRITE_WEL_DISABLE(__QSPIx__) (__QSPIx__->write_conf.disable_WEL = 1)
#define __QSPI_WRITE_ADDRESS_TYPE_SET(__QSPIx__, type) (__QSPIx__->write_conf.addr_type = type)
#define __QSPI_WRITE_DATA_TYPE_SET(__QSPIx__, type) (__QSPIx__->write_conf.data_type = type)
#define __QSPI_WRITE_DUMMY_CYCLES_SET(__QSPIx__, cycles) (__QSPIx__->write_conf.dummy_cycles = cycles)
#define __QSPI_DEVICE_PAGE_SIZE_SET(__QSPIx__, page_size) (__QSPIx__->size_cfg.page_bytes = page_size)
#define __QSPI_DEVICE_CS0_SIZE_SET(__QSPIx__, cs_size) (__QSPIx__->size_cfg.CS0_size = cs_size)
#define __QSPI_DELAY_CS_END_SET(__QSPIx__, _delay) (__QSPIx__->delay.sel_end_offset = _delay)
#define __QSPI_DELAY_CS_START_SET(__QSPIx__, _delay) (__QSPIx__->delay.sel_start_offset = _delay)
#define __QSPI_DELAY_CS_DESSERT_SET(__QSPIx__, __dessert) (__QSPIx__->delay.sel_dessert = __dessert)
#define __QSPI_READ_CAPTURE_LP_CLK_EN(__QSPIx__) (__QSPIx__->read_cap.enable_loopback_clk = 1)
#define __QSPI_READ_CAPTURE_DELAY_SET(__QSPIx__, delay) (__QSPIx__->read_cap.delay_capture = delay)
#define __QSPI_DEVICE_ADDR_BYTES_SET(__QSPIx__, bytes) (__QSPIx__->size_cfg.addr_bytes = bytes)
#define __QSPI_REMAP_ADDRESS_SET(__QSPIx__, address) (__QSPIx__->remap_address = address)
#define __QSPI_MODE_BIT_SET(__QSPIx__, mode) (__QSPIx__->mode_bits = mode)
#define __QSPI_POLL_OPCODE_SET(__QSPIx__, opcode) (__QSPIx__->poll_cfg.opcode_poll = opcode)
#define __QSPI_POLL_BIT_INDEX_SET(__QSPIx__, index) (__QSPIx__->poll_cfg.poll_bit_index = index)
#define __QSPI_POLL_POLARITY_SET(__QSPIx__, pol) (__QSPIx__->poll_cfg.poll_polarity = pol)
#define __QSPI_POLL_ENABLE(__QSPIx__) (__QSPIx__->poll_cfg.disable_poll = 0)
#define __QSPI_POLL_DISABLE(__QSPIx__) (__QSPIx__->poll_cfg.disable_poll = 1)
#define __QSPI_POLL_EXPIRE_ENABLE(__QSPIx__) (__QSPIx__->poll_cfg.enable_expiration = 1)
#define __QSPI_POLL_EXPIRE_DISABLE(__QSPIx__) (__QSPIx__->poll_cfg.enable_expiration = 0)
#define __QSPI_POLL_COUNT_SET(__QSPIx__, count) (__QSPIx__->poll_cfg.poll_count = count)
#define __QSPI_POLL_DELAY_SET(__QSPIx__, delay) (__QSPIx__->poll_cfg.poll_repetition_delay = delay)
#define __QSPI_POLL_EXPIRATION_SET(__QSPIx__, duration) (__QSPIx__->poll_expiration = duration)
#define __QSPI_CMD_ADDRESS_SET(__QSPIx__, address) (__QSPIx__->cmd_address = address)
#define __QSPI_STIG_CMD_SET(__QSPIx__, cmd) (__QSPIx__->cmd_ctrl = cmd)
#define __QSPI_STIG_OPCODE_SET(__QSPIx__, opcode) (__QSPIx__->cmd_ctrl.opcode = opcode)
#define __QSPI_STIG_READ_ENABLE(__QSPIx__) (__QSPIx__->cmd_ctrl.enable_read = 1)
#define __QSPI_STIG_READ_DISABLE(__QSPIx__) (__QSPIx__->cmd_ctrl.enable_read = 0)
#define __QSPI_STIG_READ_BYTES_SET(__QSPIx__, bytes) (__QSPIx__->cmd_ctrl.read_bytes = (bytes)-1)
#define __QSPI_STIG_CMD_ADDRESS_ENABLE(__QSPIx__) (__QSPIx__->cmd_ctrl.enable_cmd_addr = 0)
#define __QSPI_STIG_CMD_ADDRESS_DISABLE(__QSPIx__) (__QSPIx__->cmd_ctrl.enable_cmd_addr = 1)
#define __QSPI_STIG_CMD_ADDRESS_BYTES_SET(__QSPIx__, bytes) (__QSPIx__->cmd_ctrl.addr_bytes = (bytes)-1)
#define __QSPI_STIG_MODE_ENABLE(__QSPIx__) (__QSPIx__->cmd_ctrl.enable_mode = 1)
#define __QSPI_STIG_MODE_DISABLE(__QSPIx__) (__QSPIx__->cmd_ctrl.enable_mode = 0)
#define __QSPI_STIG_WRITE_ENABLE(__QSPIx__) (__QSPIx__->cmd_ctrl.enable_write = 1)
#define __QSPI_STIG_WRITE_DISABLE(__QSPIx__) (__QSPIx__->cmd_ctrl.enable_write = 0)
#define __QSPI_STIG_WRITE_BYTES_SET(__QSPIx__, bytes) (__QSPIx__->cmd_ctrl.write_bytes = (bytes)-1)
#define __QSPI_STIG_DUMMY_CYCLES_SET(__QSPIx__, cycles) (__QSPIx__->cmd_ctrl.dummy_cycles = cycles)
#define __QSPI_STIG_EXECUTE(__QSPIx__) (__QSPIx__->cmd_ctrl.execute = 1)
#define __QSPI_STIG_ON_GOING(__QSPIx__) (__QSPIx__->cmd_ctrl.progress_status == 1)
#define __QSPI_STIG_DATA_L_SET(__QSPIx__, data_l) (__QSPIx__->write_data_L = data_l)
#define __QSPI_STIG_DATA_H_SET(__QSPIx__, data_h) (__QSPIx__->write_data_H = data_h)
#define __QSPI_STIG_DATA_L_GET(__QSPIx__) (__QSPIx__->read_data_L)
#define __QSPI_STIG_DATA_H_GET(__QSPIx__) (__QSPIx__->read_data_H)
#define __QSPI_CS_CTRL_RD_BRK_ENABLE(__QSPIx__) (__QSPIx__->cs_ctrl.rd_brk_en = 1)
#define __QSPI_CS_CTRL_RD_BRK_DISABLE(__QSPIx__) (__QSPIx__->cs_ctrl.rd_brk_en = 0)
#define __QSPI_CS_CTRL_DIS_CS_AFT_FIRST_BYTE_SET(__QSPIx__) (__QSPIx__->cs_ctrl.disable_cs_after_first_byte = 1)
#define __QSPI_CS_CTRL_DIS_CS_AFT_FIRST_BYTE_CLR(__QSPIx__) (__QSPIx__->cs_ctrl.disable_cs_after_first_byte = 0)
#define __QSPI_CS_PAGE_BOUNDARY_PROTECT_ENABLE(__QSPIx__) (__QSPIx__->cs_ctrl.page_boundary_protect_en = 1)
#define __QSPI_CS_PAGE_BOUNDARY_PROTECT_DISABLE(__QSPIx__) (__QSPIx__->cs_ctrl.page_boundary_protect_en = 0)
#define __QSPI_CS_PAGE_BOUNDARY_SET(__QSPIx__, _v) (__QSPIx__->cs_ctrl.page_boundary = _v)
int qspi_stig_cmd(struct qspi_regs_t *QSPI, const struct qspi_stig_reg_t cmd, enum qspi_stig_cmd_type_t type, int len, uint8_t *buffer);
#endif /* _DRIVER_QSPI_H_ */

View File

@ -0,0 +1,31 @@
#ifndef _DRIVER_RTC_H_
#define _DRIVER_RTC_H_
#include <stdint.h>
#define CO_BIT(pos) (1UL<<(pos))
#define PMU_RTC_CRL 0x37
#define PMU_UPDATE_EN CO_BIT(0)
#define PMU_VAL_RD CO_BIT(1)
#define ALAMA_CLR CO_BIT(2)
#define ALAMB_CLR CO_BIT(3)
#define ALAMA_EN CO_BIT(4)
#define ALAMB_EN CO_BIT(5)
#define PMU_REG_RST_CTRL 0x02
#define PMU_REG_CLK_CTRL 0x01
enum rtc_idx_t
{
RTC_A,
RTC_B,
};
void rtc_test(void);
void rtc_stop(void);
void rtc_isr_ram(uint8_t rtc_idx);
#endif

View File

@ -0,0 +1,288 @@
/*
******************************************************************************
* @file driver_sbc_dec.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief Header file of SBC DEC module.
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_SBC_DEC_H__
#define __DRIVER_SBC_DEC_H__
#include "fr30xx.h"
#define SBCD_INFIFO_DEEPTH 128
#define SBCD_OUTLFIFO_DEEPTH 256
#define SBCD_OUTRFIFO_DEEPTH 256
/** @addtogroup SBC_CODEC_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
/* SBC DEC CTRL REGISTER 0x00*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t DEC_EN : 1;//sbc decoder enable
uint32_t DEC_LR_SWAP : 1;//swap decoder left and rignt channel enable
uint32_t DEC_OUTL_FLOW_CTRL : 1;//whether use the left outfifo almost full status to control whether to read the infifo
uint32_t DEC_OUTR_FLOW_CTRL : 1;//whether use the right outfifo almost full status to control whether to read the infifo
uint32_t DEC_RESET : 1;//decoder reset
uint32_t DEC_IN_FIFO_RESET : 1;//decoder infifo reset
uint32_t DEC_OUTL_FIFO_RESET : 1;//decoder left outfifo reset
uint32_t DEC_OUTR_FIFO_RESET : 1;//decoder right outfifo reset
uint32_t IN_DMA_EN : 1;//infifo dma enable
uint32_t OUT_DMA_EN : 1;//outfifo dma enable
uint32_t OUTL_FIFO_EN : 1;//outfifo status select left fifo
uint32_t OUTR_FIFO_EN : 1;//outfifo status select right fifo
uint32_t RSV : 20;
} Bits;
} REG_SBCD_CTRL_t;
/* SBC DEC IN FIFO REG REGISTER 0x04*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t SBC_IN : 8;//sbc encoded data in
uint32_t RSV : 24;
} Bits;
} REG_SBCD_INFIFO_REG_t;
/* SBC DEC OUT FIFO REG REGISTER 0x08*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t PCM_RIGHT_DATA : 16;//sbc encoded data in
uint32_t PCM_LEFT_DATA : 16;
} Bits;
} REG_SBCD_OUTFIFO_REG_t;
/* SBC DEC INT EN REGISTER 0x0C*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t INFF_FULL_INT_EN : 1;//input fifo full interrupt enbale
uint32_t INFF_EMPTY_INT_EN : 1;//input fifo empty interrupt enbale
uint32_t INFF_ALEMPTY_INT_EN : 1;//input fifo almost empty interrupt enbale
uint32_t RSV1 : 1;
uint32_t OUTLFF_FULL_INT_EN : 1;//output left fifo full interrupt enbale
uint32_t OUTLFF_EMPTY_INT_EN : 1;//output left fifo empty interrupt enbale
uint32_t OUTLFF_ALFULL_INT_EN : 1;//output left fifo almost full interrupt enbale
uint32_t RSV2 : 1;
uint32_t OUTRFF_FULL_INT_EN : 1;//output right fifo full interrupt enbale
uint32_t OUTRFF_EMPTY_INT_EN : 1;//output right fifo empty interrupt enbale
uint32_t OUTRFF_ALFULL_INT_EN : 1;//output right fifo amlost full interrupt enbale
uint32_t RSV3 : 1;
uint32_t CRC_ERR_INT_EN : 1;//crc error flag interrupt enable
uint32_t RSV4 : 19;
} Bits;
} REG_SBCD_INTEN_REG_t;
/* SBC DEC INT STATUS REGISTER 0x10*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t INFF_FULL_INT_STS : 1;//input fifo full interrupt status
uint32_t INFF_EMPTY_INT_STS : 1;//input fifo empty interrupt status
uint32_t INFF_ALEMPTY_INT_STS : 1;//input fifo almost empty interrupt status
uint32_t RSV1 : 1;
uint32_t OUTLFF_FULL_INT_STS : 1;//output left fifo full interrupt status
uint32_t OUTLFF_EMPTY_INT_STS : 1;//output left fifo empty interrupt status
uint32_t OUTLFF_ALFULL_INT_STS : 1;//output left fifo almost full interrupt status
uint32_t RSV2 : 1;
uint32_t OUTRFF_FULL_INT_STS : 1;//output right fifo full interrupt status
uint32_t OUTRFF_EMPTY_INT_STS : 1;//output right fifo empty interrupt status
uint32_t OUTRFF_ALFULL_INT_STS : 1;//output right fifo almost full interrupt status
uint32_t RSV3 : 1;
uint32_t CRC_ERR_INT_STS : 1;//crc interrupt status ,write 1 to cleat this bit
uint32_t RSV4 : 19;
} Bits;
} REG_SBCD_INTS_REG_t;
/* SBC DEC FIFO STATE REGISTER 0x14 */
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t INFIFO_FULL : 1;//infifo full flag
uint32_t INFIFO_EMPTY : 1;//infifo empty flag
uint32_t INFIFO_ALEMPTY : 1;//infifo almost empty flag
uint32_t RSV1 : 1;
uint32_t OUTLFIFO_FULL : 1;//outlfifo full flag
uint32_t OUTLFIFO_EMPTY : 1;//outlfifo empty flag
uint32_t OUTLFIFO_ALFULL : 1;//outlfifo almost full flag
uint32_t RSV2 : 1;
uint32_t OUTRFIFO_FULL : 1;//outrfifo full flag
uint32_t OUTRFIFO_EMPTY : 1;//outrfifo empty flag
uint32_t OUTRFIFO_ALFULL : 1;//outrfifo almost full flag
uint32_t RSV : 21;
} Bits;
} REG_SBCD_FIFO_STATE_t;
/* SBC DEC FIFO INWDS 0x18*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t INFIFO_WC : 8;//input fifo words count
uint32_t RSV : 24;//
} Bits;
} REG_SBCD_FIFO_INWDS_t;
/* SBC DEC FIFO OUTWDS 0x1C*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t OUTLFIFO_WC : 8;//output left fifo words pointer
uint32_t RSV1 : 8;
uint32_t OUTRFIFO_WC : 8;//output right fifo words pointer
uint32_t RSV2 : 8;
} Bits;
} REG_SBCD_FIFO_OUTWDS_t;
/*SBC FIFO LEVEL 0x20*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t INFIFO_ALEMPTY_LEVEL : 7;//output left fifo words pointer
uint32_t RSV1 : 1;
uint32_t OUTLFIFO_ALFULL_LEVEL : 8;//output right fifo words pointer
uint32_t OUTRFIFO_ALFULL_LEVEL : 8;//output right fifo words pointer
uint32_t RSV2 : 8;
} Bits;
} REG_SBCD_FIFO_LEVEL_t;
typedef struct
{
volatile REG_SBCD_CTRL_t SBCD_CTRL; /* Offset 0x00 */
volatile REG_SBCD_INFIFO_REG_t SBCD_INFIFO; /* Offset 0x04 */
volatile REG_SBCD_OUTFIFO_REG_t SBCD_OUTFIFO; /* Offset 0x08 */
volatile REG_SBCD_INTEN_REG_t SBCD_INTEN; /* Offset 0x0C */
volatile REG_SBCD_INTS_REG_t SBCD_INTS; /* Offset 0x10 */
volatile REG_SBCD_FIFO_STATE_t SBCD_FIFO_STATE; /* Offset 0x14 */
volatile REG_SBCD_FIFO_INWDS_t SBCD_FIFO_INWDS; /* Offset 0x18 */
volatile REG_SBCD_FIFO_OUTWDS_t SBCD_FIFO_OUTWDS; /* Offset 0x1C */
volatile REG_SBCD_FIFO_LEVEL_t SBCD_FIFO_LEVEL; /* Offset 0x20 */
}struct_SBCD_t;
#define SBC_DEC ((struct_SBCD_t *)SBC_DEC_BASE)
typedef enum{
SBCD_MONO = 0,
SBCD_STEREO,
}enum_Ch_Mode_t ;
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t infifo_alempty_lvl : 7;
uint32_t outlfifo_alfull_lvl : 8;
uint32_t outrlfifo_alfull_lvl : 8;
uint32_t input_dma_en : 1;
uint32_t output_dma_en : 1;
uint32_t outlfifo_en : 1;
uint32_t outrfifo_en : 1;
uint32_t ch_mode : 1;
uint32_t RSV : 4;
}Bits;
}struct_SBCDec_Init_t;
typedef struct __SBC_DEC_HandleTypeDef
{
struct_SBCDec_Init_t sbc_init;
uint8_t *EncodeData;
uint32_t DataSize;
uint16_t *OrignData;
uint32_t InputIndex;
uint32_t OutIndex;
void (*Callback)(struct __SBC_DEC_HandleTypeDef *hSbcDec); /*!< SBC decode finish Callback */
}SBC_DEC_HandleTypeDef;
typedef enum
{
INFF_FULL_INT = (1 << 0),
INFF_EMPTY_INT = (1 << 1),
INFF_ALEMPTY_INT = (1 << 2),
OUTLF_FULL_INT = (1 << 4),
OUTLF_EMPTY_INT = (1 << 5),
OUTLF_ALFULL_INT = (1 << 6),
OUTRF_FULL_INT = (1 << 8),
OUTRF_EMPTY_INT = (1 << 9),
OUTRF_ALFULL_INT = (1 << 10),
CRC_ERR_INT = (1 << 12),
}enum_isr_status_t ;
typedef struct{
uint8_t frequency;
uint8_t block_mode;
uint8_t block_len;
uint8_t channels;
uint8_t bit_pool;
enum {
MONO = 0,
DUAL_CHANNEL = 1,
STEREO = 2,
JOINT_STEREO = 3
} mode;
enum {
LOUDNESS = 0,
SNR = 1
} allocation;
uint8_t subband_mode;
uint8_t subbands;
}struct_frame_info_t;
#define __SBCD_INFIFO_IS_FULL() (SBC_DEC->SBCD_FIFO_STATE.Bits.INFIFO_FULL == 1)
#define __SBCD_INFIFO_IS_EMPTY() (SBC_DEC->SBCD_FIFO_STATE.Bits.INFIFO_EMPTY == 1)
#define __SBCD_INFIFO_IS_ALEMPTY() (SBC_DEC->SBCD_FIFO_STATE.Bits.INFIFO_ALEMPTY == 1)
#define __SBCD_OUTLFIFO_IS_FULL() (SBC_DEC->SBCD_FIFO_STATE.Bits.OUTLFIFO_FULL == 1)
#define __SBCD_OUTLFIFO_IS_EMPTY() (SBC_DEC->SBCD_FIFO_STATE.Bits.OUTLFIFO_EMPTY == 1)
#define __SBCD_OUTLFIFO_IS_ALFULL() (SBC_DEC->SBCD_FIFO_STATE.Bits.OUTLFIFO_ALFULL == 1)
#define __SBCD_OUTRFIFO_IS_FULL() (SBC_DEC->SBCD_FIFO_STATE.Bits.OUTRFIFO_FULL == 1)
#define __SBCD_OUTRFIFO_IS_EMPTY() (SBC_DEC->SBCD_FIFO_STATE.Bits.OUTRFIFO_EMPTY == 1)
#define __SBCD_OUTRFIFO_IS_ALFULL() (SBC_DEC->SBCD_FIFO_STATE.Bits.OUTRFIFO_ALFULL == 1)
#define __SBCD_GET_ISR_STS() (SBC_DEC->SBCD_INTS.Word)
#define __SBCD_INFIFO_EMPTY_DISABLE() (SBC_DEC->SBCD_INTEN.Bits.INFF_EMPTY_INT_EN = 0)
/* sbc decoder initialize */
void sbc_dec_init(SBC_DEC_HandleTypeDef *hSbcDec);
/* sbc decoder get packed frame info */
int sbc_dec_get_packed_frame_info(uint8_t *data, struct_frame_info_t frame_info);
/* sbc decoder handle function in sbc decoder isr */
void sbcdec_IRQHandler(SBC_DEC_HandleTypeDef *hSbcDec);
/* sbc decoder play data with isr */
void sbc_dec_playdata_IT(SBC_DEC_HandleTypeDef *hSbcDec, uint8_t *fp_Data, uint32_t fu32_Size, uint16_t *fp_Data_Out);
#endif

View File

@ -0,0 +1,306 @@
/*
******************************************************************************
* @file driver_sbc_enc.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief Header file of SBC ENC module.
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_SBC_ENC_H__
#define __DRIVER_SBC_ENC_H__
#include "fr30xx.h"
#define SBCE_INFIFO_DEEPTH 256
#define SBCE_OUTFIFO_DEEPTH 128
/** @addtogroup SBC_ENC_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
/* SBC ENC CTRL REGISTER 0x00*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t ENC_EN : 1;//sbc encoder enable
uint32_t ENC_LR_SWAP : 1;//swap encoder left and rignt channel enable
uint32_t ENC_INL_FLOW_CTRL : 1;//bypass in left fifo status
uint32_t ENC_INR_FLOW_CTRL : 1;//bypass in right fifo status
uint32_t ENC_RESET : 1;//encoder reset
uint32_t ENC_OUT_FIFO_RESET : 1;//encoder outfifo reset
uint32_t ENC_INL_FIFO_RESET : 1;//encoder left infifo reset
uint32_t ENC_INR_FIFO_RESET : 1;//encoder right infifo reset
uint32_t IN_DMA_EN : 1;//infifo dma enable
uint32_t OUT_DMA_EN : 1;//outfifo dma enable
uint32_t INL_FIFO_EN : 1;//infifo status select left fifo
uint32_t INR_FIFO_EN : 1;//infifo status select right fifo
uint32_t RSV : 20;
} Bits;
} REG_SBCE_CTRL_t;
/* SBC ENC CONFIG REGISTER 0x04*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t SMP_FRQ : 2;//sbc encoder sample frequncy 00->16KHz, 01->32KHz, 10->44.1KHz, 11->48KHz
uint32_t BLK_LEN : 2;//block length 00->4 01->8 10->12 11->16
uint32_t RSV1 : 1;
uint32_t CH_MODE : 1;//0->mono 1->dual
uint32_t RSV2 : 26;
} Bits;
} REG_SBCE_CFG_t;
/* SBC ENC IN FIFO REG REGISTER 0x08*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t ENC_FFL : 16;//left channel input data
uint32_t ENC_FFR : 16;//right channel input data
} Bits;
} REG_SBCE_INFIFO_REG_t;
/* SBC ENC OUT FIFO REG REGISTER 0x0C*/
/* SBC ENC INT EN REGISTER 0x10*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t OUTFF_FULL_INT_EN : 1;//output fifo full interrupt enbale
uint32_t OUTFF_EMPTY_INT_EN : 1;//output fifo empty interrupt enbale
uint32_t OUTFF_ALFULL_INT_EN : 1;//output fifo almost full interrupt enbale
uint32_t RSV1 : 1;
uint32_t INLFF_FULL_INT_EN : 1;//input left fifo full interrupt enbale
uint32_t INLFF_EMPTY_INT_EN : 1;//input left fifo empty interrupt enbale
uint32_t INLFF_ALEMPTY_INT_EN : 1;//input left fifo almost empty interrupt enbale
uint32_t RSV2 : 1;
uint32_t INRFF_FULL_INT_EN : 1;//input right fifo full interrupt enbale
uint32_t INRFF_EMPTY_INT_EN : 1;//input right fifo empty interrupt enbale
uint32_t INRFF_ALEMPTY_INT_EN : 1;//input right fifo amlost empty interrupt enbale
uint32_t RSV3 : 21;
} Bits;
} REG_SBCE_INTEN_REG_t;
/* SBC ENC INT STATUS REGISTER 0x14*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t OUTFF_FULL_INT_STS : 1;//output fifo full interrupt status
uint32_t OUTFF_EMPTY_INT_STS : 1;//output fifo empty interrupt status
uint32_t OUTFF_ALFULL_INT_STS : 1;//output fifo almost full interrupt status
uint32_t RSV1 : 1;
uint32_t INLFF_FULL_INT_STS : 1;//input left fifo full interrupt status
uint32_t INLFF_EMPTY_INT_STS : 1;//input left fifo empty interrupt status
uint32_t INLFF_ALEMPTY_INT_STS : 1;//input left fifo almost empty interrupt status
uint32_t RSV2 : 1;
uint32_t INRFF_FULL_INT_STS : 1;//input right fifo full interrupt status
uint32_t INRFF_EMPTY_INT_STS : 1;//input right fifo empty interrupt status
uint32_t INRFF_ALEMPTY_INT_STS : 1;//input right fifo almost empty interrupt status
uint32_t RSV3 : 21;
} Bits;
} REG_SBCE_INTS_REG_t;
/* SBC ENC FIFO STATE REGISTER 0x18 */
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t OUTFIFO_FULL : 1;//outfifo full flag
uint32_t OUTFIFO_EMPTY : 1;//outfifo empty flag
uint32_t OUTFIFO_ALFULL : 1;//outfifo almost empty flag
uint32_t RSV1 : 1;
uint32_t INLFIFO_FULL : 1;//inlfifo full flag
uint32_t INLFIFO_EMPTY : 1;//inlfifo empty flag
uint32_t INLFIFO_ALEMPTY : 1;//inlfifo almost full flag
uint32_t RSV2 : 1;
uint32_t INRFIFO_FULL : 1;//inrfifo full flag
uint32_t INRFIFO_EMPTY : 1;//inrfifo empty flag
uint32_t INRFIFO_ALEMPTY : 1;//inrfifo almost full flag
uint32_t RSV : 21;
} Bits;
} REG_SBCE_FIFO_STATE_t;
/* SBC ENC FIFO INWDS 0x1C*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t ENC_INLFFWDS_CNT : 9;//input left fifo words count
uint32_t RSV1 : 7;
uint32_t ENC_INRFFWDS_CNT : 9;//input right fifo words count
uint32_t RSV2 : 7;
} Bits;
} REG_SBCE_FIFO_INWDS_t;
/* SBC ENC FIFO OUTWDS 0x20*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t ENC_OUTFFWDS_CNT : 8;//output fifo words pointer
uint32_t RSV1 : 24;
} Bits;
} REG_SBCE_FIFO_OUTWDS_t;
/*SBC ENC INPUT FIFO LEVEL 0x24*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t INLFIFO_ALEMPTY_LEVEL : 8;//output left fifo words pointer
uint32_t RSV1 : 8;
uint32_t INRFIFO_ALEMPTY_LEVEL : 8;//output left fifo words pointer
uint32_t RSV2 : 8;
} Bits;
} REG_SBCE_INFIFO_LEVEL_t;
/*SBC ENC OUTPUT FIFO LEVEL 0x28*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t OUTFIFO_ALFULL_LEVEL : 8;//output fifo almost full level
uint32_t RSV : 24;
} Bits;
} REG_SBCE_OUTFIFO_LEVEL_t;
typedef struct
{
volatile REG_SBCE_CTRL_t SBCE_CTRL; /* Offset 0x00 */
volatile REG_SBCE_CFG_t SBCE_CFG; /* Offset 0x04 */
volatile REG_SBCE_INFIFO_REG_t SBCE_INFIFO; /* Offset 0x08 */
volatile uint32_t SBCE_OUTFIFO; /* Offset 0x0C */
volatile REG_SBCE_INTEN_REG_t SBCE_INTEN; /* Offset 0x10 */
volatile REG_SBCE_INTS_REG_t SBCE_INTS; /* Offset 0x14 */
volatile REG_SBCE_FIFO_STATE_t SBCE_FIFO_STATE; /* Offset 0x18 */
volatile REG_SBCE_FIFO_INWDS_t SBCE_FIFO_INWDS; /* Offset 0x1C */
volatile REG_SBCE_FIFO_OUTWDS_t SBCE_FIFO_OUTWDS; /* Offset 0x20 */
volatile REG_SBCE_INFIFO_LEVEL_t SBCE_INFIFO_LVL; /* Offset 0x24 */
volatile REG_SBCE_OUTFIFO_LEVEL_t SBCE_OUTFF_LVL; /* Offset 0x28 */
}struct_SBCE_t;
#define SBC_ENC ((struct_SBCE_t *)SBC_ENC_BASE)
typedef enum{
SBCE_MONO = 0,
SBCE_STEREO = 1,
}enum_pcm_channel_mode_t ;
typedef enum{
BLOCK_4 = 0,
BLOCK_8 = 1,
BLOCK_12 = 2,
BLOCK_16 = 3,
}enum_pcm_block_length_t ;
typedef enum{
SP_16KHz = 0,
SP_32KHz = 1,
SP_44_1KHz = 2,
SP_48KHz = 3,
}enum_pcm_sample_freq_t ;
typedef struct{
uint32_t input_dma_en;
uint32_t output_dma_en;
uint32_t inlfifo_dma_en;
uint32_t inrfifo_dma_en;
}struct_SBCE_DMA_cfg_t;
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t inlfifo_alempty_lvl : 8;
uint32_t inrfifo_alempty_lvl : 8;
uint32_t outlfifo_alfull_lvl : 8;
uint32_t output_dma_en : 1;
uint32_t input_dma_en : 1;
uint32_t sample_freq : 2;
uint32_t ch_mode : 1;
uint32_t blk_len : 2;
uint32_t RSV : 1;
}Bits;
}struct_SBCENC_Init_t;
typedef struct{
uint32_t outfifo_full_int_en;
uint32_t outfifo_empty_int_en;
uint32_t outfifo_alfull_int_en;
uint32_t inlff_full_int_en;
uint32_t inlff_empty_int_en;
uint32_t inlff_alempty_int_en;
uint32_t inrff_full_int_en;
uint32_t inrff_empty_int_en;
uint32_t inrff_alempty_int_en;
}struct_SBCE_ISR_cfg_t;
typedef struct __SBC_ENC_HandleTypeDef
{
struct_SBCENC_Init_t SbcEncInit;
uint16_t *OrignlData;
uint32_t gDataInIndex;
uint8_t *EncodedData;
uint32_t gDataOutIndex;
uint32_t OrignlDataSize;
void (*Callback)(struct __SBC_ENC_HandleTypeDef *hSbcEnc); /*!< SBC encode finish Callback */
}SBC_ENC_HandleTypeDef ;
typedef enum
{
OUTFF_FULL_INT = (1 << 0),
OUTFF_EMPTY_INT = (1 << 1),
OUTFF_ALFULL_INT = (1 << 2),
INLF_FULL_INT = (1 << 4),
INLF_EMPTY_INT = (1 << 5),
INLF_ALEMPTY_INT = (1 << 6),
INRF_FULL_INT = (1 << 8),
INRF_EMPTY_INT = (1 << 9),
INRF_ALEMPTY_INT = (1 << 10),
}enum_sbce_isr_status_t ;
#define __SBCE_OUTFIFO_IS_FULL() (SBC_ENC->SBCE_FIFO_STATE.Bits.OUTFIFO_FULL == 1)
#define __SBCE_OUTFIFO_IS_EMPTY() (SBC_ENC->SBCE_FIFO_STATE.Bits.OUTFIFO_EMPTY == 1)
#define __SBCE_OUTFIFO_IS_ALFULL() (SBC_ENC->SBCE_FIFO_STATE.Bits.OUTFIFO_ALFULL == 1)
#define __SBCE_INLFIFO_IS_FULL() (SBC_ENC->SBCE_FIFO_STATE.Bits.INLFIFO_FULL == 1)
#define __SBCE_INLFIFO_IS_EMPTY() (SBC_ENC->SBCE_FIFO_STATE.Bits.INLFIFO_EMPTY == 1)
#define __SBCE_INLFIFO_IS_ALEMPTY() (SBC_ENC->SBCE_FIFO_STATE.Bits.INLFIFO_ALEMPTY == 1)
#define __SBCE_INRFIFO_IS_FULL() (SBC_ENC->SBCE_FIFO_STATE.Bits.INRFIFO_FULL == 1)
#define __SBCE_INRFIFO_IS_EMPTY() (SBC_ENC->SBCE_FIFO_STATE.Bits.INRFIFO_EMPTY == 1)
#define __SBCE_INRFIFO_IS_ALEMPTY() (SBC_ENC->SBCE_FIFO_STATE.Bits.INRFIFO_ALEMPTY == 1)
#define __SBCE_GET_ISR_STS() (SBC_ENC->SBCE_INTS.Word)
#define __SBCE_GET_OUT_RESULT_WORD() (SBC_ENC->SBCE_OUTFIFO)
#define __SBCE_INLFF_EMPTY_INT_DISABLE() (SBC_ENC->SBCE_INTEN.Bits.INLFF_EMPTY_INT_EN = 0)
void sbc_enc_init(SBC_ENC_HandleTypeDef *hSbcEnc);
void sbc_encoder_enc_IT(SBC_ENC_HandleTypeDef *hSbcEnc, uint16_t *fp_Data_In, uint32_t fu32_size, uint8_t *fp_Data_Out);
void sbcenc_IRQHandler(SBC_ENC_HandleTypeDef *hSbcEnc);
#endif

View File

@ -0,0 +1,764 @@
/*
******************************************************************************
* @file driver_sd.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2022
* @brief Header file of SD HAL module.
******************************************************************************
* @attention
*
* Copyright (c) 2022 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_SD_H__
#define __DRIVER_SD_H__
#include "fr30xx.h"
/** @addtogroup SD_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
/* Transfer Block control Register */
typedef struct
{
uint32_t BlockSize : 12;
uint32_t HostSDMABuffer : 3;
uint32_t rsv_0 : 1;
uint32_t BlockCount : 16;
}REG_TransferBlock_t;
/* Transfer mode Register */
typedef struct
{
uint16_t DMAEnable : 1;
uint16_t BlockCountEnable : 1;
uint16_t AutoCMDEnable : 2;
uint16_t DataDirection : 1;
uint16_t MultiBlockEnable : 1;
uint16_t rsv_0 : 5;
uint16_t StreamModeEnable : 1;
uint16_t SPIModeEnable : 1;
uint16_t BootAckEnable : 1;
uint16_t AlternateBootOperation : 1;
uint16_t BootOperation : 1;
}REG_TransferConfig_t;
/* Transfer Block control Register */
typedef struct
{
uint32_t CMDInhibit : 1;
uint32_t DATInhibit : 1;
uint32_t DATLineActive : 1;
uint32_t Re_TuningRequset : 1;
uint32_t rsv_0 : 4;
uint32_t WriteTransferActive : 1;
uint32_t ReadTransferActive : 1;
uint32_t BufferWriteEnable : 1;
uint32_t BUfferReadEnable : 1;
uint32_t rsv_1 : 4;
uint32_t CradInserted : 1;
uint32_t CradStateStable : 1;
uint32_t CredDetctPin : 1;
uint32_t WriteProtectPin : 1;
uint32_t DATLineSignal : 4;
uint32_t CMDLineSignal : 1;
uint32_t rsv_2 : 7;
}REG_PresentState_t;
/* control 0 Register */
typedef struct
{
/* host control 1 */
uint32_t LEDControl : 1;
uint32_t DataTransferWidth : 1;
uint32_t HighSpeedEnable : 1;
uint32_t DMASelect : 2;
uint32_t ExtendDataTransferWidth : 1;
uint32_t CardDetectTestLevel : 1;
uint32_t CardDetectSignalSelection : 1;
/* Power control */
uint32_t SDBusPower : 1;
uint32_t SDBusVoltageSelect : 3;
uint32_t SMIH_OD_PP : 1;
uint32_t SMIH_RST_N : 1;
uint32_t rsv_0 : 2;
/* Block gap control */
uint32_t StopRequest : 1;
uint32_t ContinueRequest : 1;
uint32_t ReadWaitControl : 1;
uint32_t BlockGapInt : 1;
uint32_t rsv_1 : 4;
/* wakeup control */
uint32_t WEE_CardInterrupt : 1; /* WEE: Wakeup Event Enable */
uint32_t WEE_SDCardInsertion : 1;
uint32_t WEE_SDCardRemoval : 1;
uint32_t rsv_2 : 5;
}REG_SD_Control0_t;
/* control 1 Register */
typedef struct
{
/* clock control */
uint32_t InternalClockEnable : 1;
uint32_t InternalClockStable : 1;
uint32_t SDClockEnable : 1;
uint32_t rsv_0 : 2;
uint32_t ClockGeneratorSelect : 1;
uint32_t SDCLKFrequencySelect1 : 2;
uint32_t SDCLKFrequencySelect0 : 8;
/* timeout control */
uint32_t DATTimeoutValue : 4;
uint32_t rsv_1 : 4;
/* Software reset */
uint32_t ResetAll : 1;
uint32_t ResetCMDLine : 1;
uint32_t ResetDATLine : 1;
uint32_t rsv_2 : 5;
}REG_SD_Control1_t;
/* control 2 Register */
typedef struct
{
/* Auto CMD Error status */
uint32_t AutoCMD12NotExecuted : 1;
uint32_t AutoCMDTimeoutError : 1;
uint32_t AutoCMDCRCError : 1;
uint32_t AutoCMDEndBitError : 1;
uint32_t AUtoCMDIndexError : 1;
uint32_t rsv_0 : 2;
uint32_t CommandNotIssuedByAutoCMD12Error : 1;
uint32_t rsv_1 : 8;
/* host control 2 */
uint32_t UHSModeSelect : 3;
uint32_t Signal1_8Enable : 1;
uint32_t DriverStrengthSelect : 2;
uint32_t ExcuteTuning : 1;
uint32_t SamplingClockSelect : 1;
uint32_t ConsecutiveSampling : 6;
uint32_t AsynchronousInterruptEnable : 1;
uint32_t SDCLK_IO_Operation : 1;
}REG_SD_Control2_t;
/* Capability0 Register */
typedef struct
{
uint32_t SDR50_Support : 1;
uint32_t SDR104_Support : 1;
uint32_t DDR50_Support : 1;
uint32_t rsv_0 : 1;
uint32_t DriverTypeASupport : 1;
uint32_t DriverTypeCSupport : 1;
uint32_t DriverTypeDSupport : 1;
uint32_t rsv_1 : 1;
uint32_t ReTuningTimerCount : 4;
uint32_t rsv_2 : 1;
uint32_t SDR50_UseTuning : 1;
uint32_t ReTuningMode : 2;
uint32_t ClockMultiplier : 8;
uint32_t rsv_3 : 8;
}REG_Capability0_t;
/* ------------------------------------------------*/
/* SD Register */
/* ------------------------------------------------*/
typedef struct
{
volatile uint32_t Argument2; /* Offset 0x00 */
volatile REG_TransferBlock_t Block; /* Offset 0x04 */
volatile uint32_t Argument1; /* Offset 0x08 */
volatile REG_TransferConfig_t TransferConfig; /* Offset 0x0C */
volatile uint16_t Command; /* Offset 0x0E */
volatile uint32_t Response0; /* Offset 0x10 */
volatile uint32_t Response1; /* Offset 0x14 */
volatile uint32_t Response2; /* Offset 0x18 */
volatile uint32_t Response3; /* Offset 0x1C */
volatile uint32_t BufferData; /* Offset 0x20 */
volatile uint32_t PresentState; /* Offset 0x24 */
volatile REG_SD_Control0_t Control0; /* Offset 0x28 */
volatile REG_SD_Control1_t Control1; /* Offset 0x2C */
volatile uint32_t StatusInt; /* Offset 0x30 */
volatile uint32_t StatusIntEN; /* Offset 0x34 */
volatile uint32_t SignalIntEN; /* Offset 0x38 */
volatile REG_SD_Control2_t Control2; /* Offset 0x3C */
volatile uint32_t Capability0; /* Offset 0x40 */
volatile uint32_t Capability1; /* Offset 0x44 */
volatile uint32_t MaxCurrent0; /* Offset 0x48 */
volatile uint32_t MaxCurrent1; /* Offset 0x4C */
volatile uint32_t ForceError; /* Offset 0x50 */
volatile uint32_t AMDAError; /* Offset 0x54 */
volatile uint32_t ADMA_Address0; /* Offset 0x58 */
volatile uint32_t ADMA_Address1; /* Offset 0x5C */
volatile uint32_t PresetValue0; /* Offset 0x60 */
volatile uint32_t PresetValue1; /* Offset 0x64 */
volatile uint32_t PresetValue2; /* Offset 0x68 */
volatile uint32_t PresetValue3; /* Offset 0x6C */
volatile uint32_t rsv_0[28];
volatile uint32_t ShareBusCtl; /* Offset 0xE0 */
volatile uint32_t rsv_1[2];
volatile uint32_t BurstSize; /* Offset 0xEC */
volatile uint32_t rsv_2[3];
volatile uint32_t SoltIntStatus; /* Offset 0xFC */
}struct_SD_t;
#define SDIO0 ((struct_SD_t *)SDIOH0_BASE)
#define SDIO1 ((struct_SD_t *)SDIOH1_BASE)
/* ################################ Register Section END ################################## */
/**
* @}
*/
/** @addtogroup SD_Initialization_Config_Section
* @{
*/
/* ################################ Initialization<6F><6E>Config Section Start ################################ */
/* SD Bus Voltage Select */
typedef enum
{
VOLTAGE_3_3 = 7,
VOLTAGE_3_0 = 6,
VOLTAGE_1_8 = 5,
}enum_Voltage_Select_t;
/* command response type */
typedef enum
{
CMD_TYPE_ABORT = 0xC0,
CMD_TYPE_RESUME = 0x80,
CMD_TYPE_SUSPEND = 0x40,
CMD_TYPE_NORMAL = 0,
DATA_PRESENT = 0x20,
NO_DATA_PRESENT = 0,
RES_NO = 0,
RES_R2 = 0x09,
RES_R3_R4 = 0x02,
RES_R1_R5_R6_R7 = 0x1A,
RES_R1b_R5b = 0x1B,
}enum_CmdRes_Type_t;
/* present state mask */
typedef enum
{
PreState_CMD_LINE_MASK = 0x00000001,
PreState_DAT_LINE_MASK = 0x00000002,
PreState_DAT_LINE_ACTIVE_MASK = 0x00000004,
PreState_RE_TUNING_REQUEST_MASK = 0x00000008,
PreState_WRITE_TRANDSFER_MASK = 0x00000100,
PreState_READ_TRANDSFER_MASK = 0x00000200,
PreState_BUFFER_WRITE_EN_MASK = 0x00000400,
PreState_BUFFER_READ_EN_MASK = 0x00000800,
PreState_CARD_INSERTED_MASK = 0x00010000,
PreState_CARD_STABLE_MASK = 0x00020000,
PreState_WRITE_PROTECT_MASK = 0x00080000,
PreState_DAT0_SIGNAL_MASK = 0x00100000,
PreState_DAT1_SIGNAL_MASK = 0x00200000,
PreState_DAT2_SIGNAL_MASK = 0x00400000,
PreState_DAT3_SIGNAL_MASK = 0x00800000,
PreState_CMD_SIGNAL_MASK = 0x01000000,
}enum_PresentState_t;
/* interrupt status mask */
typedef enum
{
INT_CMD_COMPLETE = 0x00000001,
INT_TRANSFER_COMPLETE = 0x00000002,
INT_BLOCK_GAP_EVENT = 0x00000004,
INT_DMA_INT = 0x00000008,
INT_BUFFER_WRITE_READY = 0x00000010,
INT_BUFFER_READ_READY = 0x00000020,
INT_CARD_INSERTION = 0x00000040,
INT_CARD_REMOVAL = 0x00000080,
INT_CARD_INT = 0x00000100,
INT_A = 0x00000200,
INT_B = 0x00000400,
INT_C = 0x00000800,
INT_RE_RUNING_EVENT = 0x00001000,
INT_BOOT_ACK_COMPLETE = 0x00002000,
INT_BOOT_DONE = 0x00004000,
INT_ERR = 0x00008000,
INT_ERR_CMD_TO = 0x00010000,
INT_ERR_CMD_CRC = 0x00020000,
INT_ERR_CMD_END_BIT = 0x00040000,
INT_ERR_CMD_INDEX = 0x00080000,
INT_ERR_DAT_TO = 0x00100000,
INT_ERR_DAT_CRC = 0x00200000,
INT_ERR_DAT_END_BIT = 0x00400000,
INT_ERR_CURRENT_LIMIT = 0x00800000,
INT_ERR_AUTO_CMD = 0x01000000,
INT_ERR_ADMA = 0x02000000,
INT_ERR_TUNING = 0x04000000,
INT_ERR_MASK = 0x07FF0000,
INT_NO_ERR = 0,
}enum_INT_Status_t;
/* Auto CMD error status mask */
typedef enum
{
AUTO_CMD12_NOT_EXECUTED = 0x00000001,
AUTO_CMD_ERR_TO = 0x00000002,
AUTO_CMD_ERR_CRC = 0x00000004,
AUTO_CMD_ERR_END_BIT = 0x00000008,
AUTO_CMD_ERR_INDEX = 0x00000010,
AUTO_CMD23_ERR = 0x00000080,
}enum_AUTO_CMD_ERR_STATUS_t;
/**
* @brief Masks for errors Card Status Response R1
*/
#define RESP1_ERR_ADDR_OUT_OF_RANGE (0x80000000U)
#define RESP1_ERR_ADDR_MISALIGNED (0x40000000U)
#define RESP1_ERR_BLOCK_LEN_ERR (0x20000000U)
#define RESP1_ERR_ERASE_SEQ_ERR (0x10000000U)
#define RESP1_ERR_BAD_ERASE_PARAM (0x08000000U)
#define RESP1_ERR_WRITE_PROT_VIOLATION (0x04000000U)
#define RESP1_ERR_LOCK_UNLOCK_FAILED (0x01000000U)
#define RESP1_ERR_COM_CRC_FAILED (0x00800000U)
#define RESP1_ERR_ILLEGAL_CMD (0x00400000U)
#define RESP1_ERR_CARD_ECC_FAILED (0x00200000U)
#define RESP1_ERR_CC_ERROR (0x00100000U)
#define RESP1_ERR_GENERAL_UNKNOWN_ERROR (0x00080000U)
#define RESP1_ERR_STREAM_READ_UNDERRUN (0x00040000U)
#define RESP1_ERR_STREAM_WRITE_OVERRUN (0x00020000U)
#define RESP1_ERR_CID_CSD_OVERWRITE (0x00010000U)
#define RESP1_ERR_WP_ERASE_SKIP (0x00008000U)
#define RESP1_ERR_CARD_ECC_DISABLED (0x00004000U)
#define RESP1_ERR_ERASE_RESET (0x00002000U)
#define RESP1_ERR_AKE_SEQ_ERROR (0x00000008U)
#define RESP1_ERR_ERRORBITS (0xFDFFE008U)
#define RCA_ERR_AKE_SEQ_ERROR (0x00000008U)
#define RCA_ERR_GENERAL_UNKNOWN_ERROR (0x00002000U)
#define RCA_ERR_ILLEGAL_CMD (0x00004000U)
#define RCA_ERR_COM_CRC_FAILED (0x00008000U)
#define RCA_ERR_ERRORBITS (0x0000E008U)
/* SD Commands Index */
typedef enum
{
SDMMC_CMD0_GO_IDLE_STATE = 0x000, // 0
MMC_CMD1_SEND_OP_COND = 0x100, // 1
SDMMC_CMD2_ALL_SEND_CID = 0x200, // 2
SD_CMD3_SEND_RELATIVE_ADDR = 0x300, // 3
MMC_CMD3_SET_RELATIVE_ADDR = 0x300, // 3
SDMMC_CMD4_SET_DSR = 0x400, // 4
SD_CMD6_SWITCH_FUNC = 0x600, // 6
MMC_CMD6_SWITCH = 0x600, // 6
SDMMC_CMD7_SEL_DESEL_CARD = 0x700, // 7
SD_CMD8_SEND_IF_COND = 0x800, // 8
MMC_CMD8_SEND_EXT_CSD = 0x800, // 8
SDMMC_CMD9_SEND_CSD = 0x900, // 9
SDMMC_CMD10_SEND_CID = 0xA00, // 10
SD_CMD11_VOLTAGE_SWITCH = 0xB00, // 11
SDMMC_CMD12_STOP_TRANSMISSION = 0xC00, // 12
SDMMC_CMD13_SEND_STATUS = 0xD00, // 13
SDMMC_CMD15_GO_INACTIVE_STATE = 0xF00, // 15
SDMMC_CMD16_SET_BLOCKLEN = 0x1000, // 16
SDMMC_CMD17_READ_SINGLI_BLOCK = 0x1100, // 17
SDMMC_CMD18_READ_MULTIPLE_BLOCK = 0x1200, // 18
SD_CMD19_SEND_TUNING_BLOCK = 0x1300, // 19
SD_CMD20_SPEED_CLASS_CONTROL = 0x1400, // 20
MMC_CMD21_SEND_TUNING_BLOCK = 0x1500, // 21
SDMMC_CMD23_SET_BLOCK_COUNT = 0x1700, // 23
SDMMC_CMD24_WRITE_BLOCK = 0x1800, // 24
SDMMC_CMD25_WRITE_MULTIPLE_BLOCK = 0x1900, // 25
MMC_CMD226_PROGRAM_CID = 0x1A00, // 26
SDMMC_CMD27_PROGRAM_CSD = 0x1B00, // 27
SDMMC_CMD28_SET_WRITE_PROT = 0x1C00, // 28
SDMMC_CMD29_CLR_WRITE_PROT = 0x1D00, // 29
SDMMC_CMD30_SEND_WRITE_PROT = 0x1E00, // 30
MMC_CMD30_SEND_WRITE_PROT_TYPE = 0x1F00, // 31
SD_CMD32_ERASE_WR_BLK_START = 0x2000, // 32
SD_CMD33_ERASE_WR_BLK_END = 0x2100, // 33
MMC_CMD35_ERASE_GROUP_START = 0x2300, // 35
MMC_CMD36_ERASE_GROUP_END = 0x2400, // 36
SDMMC_CMD38_ERASE = 0x2600, // 38
SDMMC_CMD42_LOCK_UNLOCK = 0x2A00, // 42
SDMMC_CMD55_APP_CMD = 0x3700, // 55
SDMMC_CMD56_GEN_CMD = 0x3800, // 56
}enum_SD_MMC_CMD_t;
/* SD APP Commands Index */
typedef enum
{
SD_ACMD6_SET_BUS_WIDTH = 0x600, // 6
SD_ACMD13_SD_STATUS = 0xD00, // 13
SD_ACMD22_SEND_NUM_WR_BLOCKS = 0x1600, // 22
SD_ACMD23_SET_WR_BLK_ERASE_COUNT = 0x1700, // 23
SD_ACMD41_SD_SEND_OP_COND = 0x2900, // 41
SD_ACMD42_SET_CLR_CARD_DETECT = 0x2A00, // 42
SD_ACMD51_SEND_SCR = 0x3300, // 51
}enum_SD_ACMD_t;
/* SD BUS Speed mode */
typedef enum
{
SPEED_DS = 0x010, /* default Speed up to 25MHz 3.3V signaling */
SPEED_HS = 0x011, /* High Speed up to 50MHz 3.3V signaling */
SPEED_SDR12 = 0x100, /* SDR up to 25MHz 1.8V signaling */
SPEED_SDR25 = 0x101, /* SDR up to 50MHz 1.8V signaling */
SPEED_SDR50 = 0x102, /* SDR up to 100MHz 1.8V signaling */
SPEED_SDR104 = 0x103, /* SDR up to 208MHz 1.8V signaling */
SPEED_DDR50 = 0x104, /* DDR up to 50MHz 1.8V signaling */
SIGNALING_3_3V_MASK = 0x010,
SIGNALING_1_8V_MASK = 0x100,
}enum_SpeedMode_t;
/**
* @brief SDIO Command Control structure
*/
typedef struct
{
uint32_t Argument; /*!< Specifies the SDIO command argument which is sent to a card
as part of a command message. */
uint32_t CmdIndex; /*!< Specifies the SDIO command index.
This parameter can be a value of @ref enum_SD_CMD_t/enum_SD_ACMD_t */
uint32_t CmdType; /*!< Specifies the SDIO command type.
This parameter can be a value of @ref enum_CmdRes_Type_t */
uint32_t DataType; /*!< Specifies the SDIO command type.
This parameter can be a value of @ref enum_CmdRes_Type_t */
uint32_t ResponseType; /*!< Specifies the SDIO response type.
This parameter can be a value of @ref enum_CmdRes_Type_t */
}SDIO_CmdTypeDef;
/*
* @brief SD Init Structure definition
*/
typedef struct
{
uint32_t ClockDiv; /*!< Specifies the clock frequency of the SDIO controller.
This parameter can be a even number from 0 to 510 */
uint32_t SpeedMode; /*!< Specifies the bus speed mode of the SDIO controller.
This parameter can be a value of @ref enum_SpeedMode_t */
}struct_SDInit_t;
/*
* @brief MMC Init Structure definition
*/
typedef struct
{
uint32_t ClockDiv; /*!< Specifies the clock frequency of the SDIO controller.
This parameter can be a even number from 0 to 510 */
}struct_MMCInit_t;
/* ################################ Initialization<6F><6E>Config Section END ################################## */
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
/* set SDMA system Address */
#define __SD_SET_SDMA_SYSTEM_ADDR(__SDx__, __ADDR__) (__SDx__->Argument2 = __ADDR__)
/* set argument value */
#define __SD_SET_ARGUMENT1(__SDx__, __VALUE__) (__SDx__->Argument1 = __VALUE__)
#define __SD_SET_ARGUMENT2(__SDx__, __VALUE__) (__SDx__->Argument2 = __VALUE__)
/* __SD_SET_BLOCK_SIZE */
#define __SD_SET_BLOCK_SIZE(__SDx__, __SIZE__) (__SDx__->Block.BlockSize = __SIZE__)
/* __SD_SET_SDMA_BUFF */
#define __SD_SET_SDMA_BUFF(__SDx__, __BUFF__) (__SDx__->Block.HostSDMABuffer = __BUFF__)
/* __SD_SET_BLOCK_COUNT */
/* __SD_GET_BLOCK_COUNT */
#define __SD_SET_BLOCK_COUNT(__SDx__, __COUNT__) (__SDx__->Block.BlockCount = __COUNT__)
#define __SD_GET_BLOCK_COUNT(__SDx__) (__SDx__->Block.BlockCount)
/* ----------------------*/
/* Transfer Mode */
/* ----------------------*/
/* __SD_DMA_ENABLE */
/* __SD_DMA_DISABLE */
#define __SD_DMA_ENABLE(__SDx__) (__SDx__->TransferConfig.DMAEnable = 1)
#define __SD_DMA_DISABLE(__SDx__) (__SDx__->TransferConfig.DMAEnable = 0)
/* Block Count register Enable */
#define __SD_BLOCK_COUNT_ENABLE(__SDx__) (__SDx__->TransferConfig.BlockCountEnable = 1)
#define __SD_BLOCK_COUNT_DISABLE(__SDx__) (__SDx__->TransferConfig.BlockCountEnable = 0)
/* 0x0: Auto command disable */
/* 0x1: Auto CMD12 enable */
/* 0x2: Auto CMD23 enable */
#define __SD_AUTO_CMD_ENABLE(__SDx__, __INDEX__) (__SDx__->TransferConfig.AutoCMDEnable = __INDEX__)
/* data transfer direction */
#define __SD_DATA_DIRECTION(__SDx__, __DIR__) (__SDx__->TransferConfig.DataDirection = __DIR__)
/* Multi / Single Block Select */
#define __SD_MULTI_BLOCK_ENABLE(__SDx__) (__SDx__->TransferConfig.MultiBlockEnable = 1)
#define __SD_MULTI_BLOCK_DISABLE(__SDx__) (__SDx__->TransferConfig.MultiBlockEnable = 0)
/* MMC mode CMD11 / CMD20 Stream Read/Write Operations */
#define __SD_MMC_STREAM_MODE_ENABLE(__SDx__) (__SDx__->TransferConfig.StreamModeEnable = 1)
#define __SD_MMC_STREAM_MODE_DISABLE(__SDx__) (__SDx__->TransferConfig.StreamModeEnable = 0)
/* SPI mode enable */
#define __SD_SPI_MODE_ENABLE(__SDx__) (__SDx__->TransferConfig.SPIModeEnable = 1)
#define __SD_SPI_MODE_DISABLE(__SDx__) (__SDx__->TransferConfig.SPIModeEnable = 0)
/* Boot Ack Enable */
#define __SD_BOOT_ACK_ENABLE(__SDx__) (__SDx__->TransferConfig.BootAckEnable = 1)
#define __SD_BOOT_ACK_DISABLE(__SDx__) (__SDx__->TransferConfig.BootAckEnable = 0)
/* Alternate Boot Operation */
#define __SD_ALTERNATE_BOOT_START(__SDx__) (__SDx__->TransferConfig.AlternateBootOperation = 1)
#define __SD_ALTERNATE_BOOT_STOP(__SDx__) (__SDx__->TransferConfig.AlternateBootOperation = 0)
/* Boot Operation */
#define __SD_BOOT_START(__SDx__) (__SDx__->TransferConfig.BootOperation = 1)
#define __SD_BOOT_STOP(__SDx__) (__SDx__->TransferConfig.BootOperation = 0)
/* ----------------------*/
/* Command */
/* ----------------------*/
#define __SD_SEND_COMMAND(__SDx__, __CMD__) (__SDx__->Command = __CMD__)
/* Get response value */
#define __SD_GET_RESPONSE0(__SDx__) (__SDx__->Response0)
#define __SD_GET_RESPONSE1(__SDx__) (__SDx__->Response1)
#define __SD_GET_RESPONSE2(__SDx__) (__SDx__->Response2)
#define __SD_GET_RESPONSE3(__SDx__) (__SDx__->Response3)
/* Set BufferData address */
/* Get BufferData address */
#define __SD_SET_BUFFERDATA(__SDx__, __DATA__) (__SDx__->BufferData = __DATA__)
#define __SD_GET_BUFFERDATA(__SDx__) (__SDx__->BufferData)
/* Get present state */
#define __SD_GET_PRESENT_STATE(__SDx__) (__SDx__->PresentState)
/* ----------------------*/
/* Host control 1 */
/* ----------------------*/
/* LED Control */
#define __SD_LED_CONTROL(__SDx__, __EN__) (__SDx__->Control0.LEDControl = __EN__)
/* Data Transfer Width */
#define __SD_DATA_WIDTH_1BIT(__SDx__) (__SDx__->Control0.DataTransferWidth = 0)
#define __SD_DATA_WIDTH_4BIT(__SDx__) (__SDx__->Control0.DataTransferWidth = 1)
/* High Speed Enable */
#define __SD_SPEED_MODE(__SDx__, __SPEED__) (__SDx__->Control0.HighSpeedEnable = __SPEED__)
/* DMA Select */
#define __SD_DMA_SELECT(__SDx__, __DMA__) (__SDx__->Control0.DMASelect = __DMA__)
/* 8 bit width mode */
#define __SD_8BIT_WIDTH_ENABLE(__SDx__) (__SDx__->Control0.ExtendDataTransferWidth = 1)
#define __SD_8BIT_WIDTH_DISABLE(__SDx__) (__SDx__->Control0.ExtendDataTransferWidth = 0)
/* Card Detect Test */
#define __SD_CRAD_DETECT(__SDx__, __DETECT__) (__SDx__->Control0.CardDetectTestLevel = __DETECT__)
/* Card Detect Signal Selection */
#define __SD_CRAD_DETECT_SIGNAL(__SDx__, __SIGNAL__) (__SDx__->Control0.CardDetectSignalSelection = __SIGNAL__)
/* ----------------------*/
/* Power control 1 */
/* ----------------------*/
/* SD Bus Power */
#define __SD_BUS_POWER_ON(__SDx__) (__SDx__->Control0.SDBusPower = 1)
#define __SD_BUS_POWER_OFF(__SDx__) (__SDx__->Control0.SDBusPower = 0)
/* SD Bus Voltage Select */
#define __SD_BUS_VOLTAGE_SELECT(__SDx__, __VOLTAGE__) (__SDx__->Control0.SDBusVoltageSelect = __VOLTAGE__)
/* Open drain/push-pull in MMC mode */
#define __SD_MMC_OD_PP(__SDx__, __OD_PP__) (__SDx__->Control0.SMIH_OD_PP = __OD_PP__)
/* External Hardware reset in MMC mode */
#define __SD_MMC_EXT_RST(__SDx__, __RST__) (__SDx__->Control0.SMIH_RST_N = __RST__)
/* ----------------------*/
/* Block Gap control */
/* ----------------------*/
/* Stop At Block Gap request */
#define __SD_STOP_AT_BLOCK_GAP(__SDx__, __STOP__) (__SDx__->Control0.StopRequest = __STOP__)
/* Continue At Block Gap request */
#define __SD_CONTINUE_AT_BLOCK_GAP(__SDx__, __CONTINUE__) (__SDx__->Control0.ContinueRequest = __CONTINUE__)
/* Read Wait Control */
#define __SD_READ_WAIT(__SDx__, __WAIT__) (__SDx__->Control0.ReadWaitControl = __WAIT__)
/* Interrupt At Block Gap */
#define __SD_INT_AT_BLOCK_GAP(__SDx__, __INT__) (__SDx__->Control0.BlockGapInt = __INT__)
/* ----------------------*/
/* Wakeup control */
/* ----------------------*/
/* Wakeup Event Enable On Card Interrupt */
#define __SD_WAKEUP_ON_CARD_INT(__SDx__, __ON__) (__SDx__->Control0.WEE_CardInterrupt = __ON__)
/* Wakeup Event Enable On SD Card Insertion */
#define __SD_WAKEUP_ON_CARD_INSERTION(__SDx__, __ON__) (__SDx__->Control0.WEE_SDCardInsertion = __ON__)
/* Wakeup Event Enable On SD Card Removal */
#define __SD_WAKEUP_ON_CARD_REMOVAL(__SDx__, __ON__) (__SDx__->Control0.WEE_SDCardRemoval = __ON__)
/* ----------------------*/
/* Clock control */
/* ----------------------*/
/* Internal Clock Enable/Disable */
#define __SD_INTERNAL_CLOCK_ENABLE(__SDx__) (__SDx__->Control1.InternalClockEnable = 1)
#define __SD_INTERNAL_CLOCK_DISABLE(__SDx__) (__SDx__->Control1.InternalClockEnable = 0)
/* Is Internal Clock Stable */
#define __SD_IS_INTERNAL_CLOCK_STABLE(__SDx__) (__SDx__->Control1.InternalClockStable == 1)
/* SD Clock Enable/Disable */
#define __SD_SDCLK_ENABLE(__SDx__) (__SDx__->Control1.SDClockEnable = 1)
#define __SD_SDCLK_DISABLE(__SDx__) (__SDx__->Control1.SDClockEnable = 0)
/* Clock Generator Select */
#define __SD_CLOCK_GENERATOR_SELECT(__SDx__, __SELECT__) (__SDx__->Control1.ClockGeneratorSelect = __SELECT__)
/* SDCLK Frequency divide high 2bit */
#define __SD_CLOCK_DIV_HIGH_2BIT(__SDx__, __DIV__) (__SDx__->Control1.SDCLKFrequencySelect1 = __DIV__)
/* SDCLK Frequency divide low 8bit */
#define __SD_CLOCK_DIV_LOW_8BIT(__SDx__, __DIV__) (__SDx__->Control1.SDCLKFrequencySelect0 = __DIV__)
/* ----------------------*/
/* Timeout control */
/* ----------------------*/
/* Data Timeout Counter Value */
#define __SD_DATA_TIMEOUT_COUNT(__SDx__, __COUNT__) (__SDx__->Control1.DATTimeoutValue = __COUNT__)
/* ----------------------*/
/* Software control */
/* ----------------------*/
/* Software Reset For All */
#define __SD_RST_SDIO_CONTROLLER(__SDx__) (__SDx__->Control1.ResetAll = 1)
/* Software Reset For CMD Line */
#define __SD_RST_CMD_LINE(__SDx__) (__SDx__->Control1.ResetCMDLine = 1)
/* Software Reset For DAT Line */
#define __SD_RST_DAT_LINE(__SDx__) (__SDx__->Control1.ResetDATLine = 1)
/* get interrupt status */
#define __SD_GET_INT_STATUS(__SDx__) (__SDx__->StatusInt)
/* clear interrupt status */
#define __SD_CLR_INT_STATUS(__SDx__, __STATUS__) (__SDx__->StatusInt |= __STATUS__)
#define __SD_CLR_ALL_INT_STATUS(__SDx__) (__SDx__->StatusInt = 0xFFFFFFFF)
/* interrupt Status enable/disable */
#define __SD_INT_STATUS_ENABLE(__SDx__, __STATUS__) (__SDx__->StatusIntEN |= (__STATUS__))
#define __SD_INT_STATUS_DISABLE(__SDx__, __STATUS__) (__SDx__->StatusIntEN &= ~(__STATUS__))
#define __SD_INT_STATUS_ALL_ENABLE(__SDx__) (__SDx__->StatusIntEN = 0xFFFFFFFF)
#define __SD_INT_STATUS_ALL_DISABLE(__SDx__) (__SDx__->StatusIntEN = 0x00000000)
/* interrupt Signal enable/disable */
#define __SD_INT_ENABLE(__SDx__, __STATUS__) (__SDx__->SignalIntEN |= (__STATUS__))
#define __SD_INT_DISABLE(__SDx__, __STATUS__) (__SDx__->SignalIntEN &= ~(__STATUS__))
/* get Auto CMD Error Status */
#define __SD_GET_AUTO_CMD_ERR_STATUS(__SDx__) (__SDx__->Control2 & 0x0000FFFF)
/* ----------------------*/
/* Host control 2 */
/* ----------------------*/
/* UHS Mode Select */
#define __SD_UHS_MODE(__SDx__, __MODE__) (__SDx__->Control2.UHSModeSelect = __MODE__)
/* 1.8V Signaling */
#define __SD_1_8V_ENABLE(__SDx__, __EN__) (__SDx__->Control2.Signal1_8Enable = __EN__)
/* Driver Strength Select */
#define __SD_DRIVER_TYPE_SELECT(__SDx__, __TYPE__) (__SDx__->Control2.DriverStrengthSelect = __TYPE__)
/* Execute Tuning */
#define __SD_EXECUTE_TUNING(__SDx__) (__SDx__->Control2.ExcuteTuning = 1)
/* Sampling Clock Select */
#define __SD_SAMPLING_CLOCK_SELECT(__SDx__, _SELECT__) (__SDx__->Control2.SamplingClockSelect = _SELECT__)
/* Consecutive Sampling */
#define __SD_CONSECUTIVE_SAMPLING(__SDx__, __COUNT__) (__SDx__->Control2.ConsecutiveSampling = __COUNT__)
/* Asynchronous Interrupt Enable */
#define __SD_ASYN_INT_ENABLE(__SDx__, __EN__) (__SDx__->Control2.AsynchronousInterruptEnable = __EN__)
/* Preset config Enabled */
#define __SD_PRESET_ENABLE(__SDx__, __EN__) (__SDx__->Control2.SDCLK_IO_Operation = __EN__)
/* AHB Master Burst Size */
#define __SD_AHB_BURST_SIZE(__SDx__, __BURST__) (__SDx__->BurstSize = __BURST__)
/* Exported functions --------------------------------------------------------*/
/* SD_CMD_SetBlockCount */
uint32_t SD_CMD_SetBlockCount(struct_SD_t *SDx, uint32_t fu32_Argument);
/* Read */
uint32_t SD_CMD_ReadSingleBlock(struct_SD_t *SDx, uint32_t fu32_Argument);
uint32_t SD_CMD_ReadMultiBlock(struct_SD_t *SDx, uint32_t fu32_Argument);
uint32_t SD_CMD_ReadBlock_SDMA(struct_SD_t *SDx, uint32_t fu32_Argument);
/* Write */
uint32_t SD_CMD_WriteSingleBlock(struct_SD_t *SDx, uint32_t fu32_Argument);
uint32_t SD_CMD_WriteMultiBlock(struct_SD_t *SDx, uint32_t fu32_Argument);
uint32_t SD_CMD_WriteBlock_SDMA(struct_SD_t *SDx, uint32_t fu32_Argument);
/* Erase */
uint32_t SD_CMD_EraseStartAddr(struct_SD_t *SDx, uint32_t fu32_Argument);
uint32_t SD_CMD_EraseEndAddr(struct_SD_t *SDx, uint32_t fu32_Argument);
uint32_t SD_CMD_Erase(struct_SD_t *SDx);
/* SD_CMD_StopTransfer */
uint32_t SD_CMD_StopTransfer(struct_SD_t *SDx);
/* SD_CMD_BlockLength */
uint32_t SD_CMD_BlockLength(struct_SD_t *SDx, uint32_t fu32_Argument);
/* SD_CMD_SelectCard / SD_CMD_DeselectCard */
uint32_t SD_CMD_SelectCard(struct_SD_t *SDx, uint32_t fu32_Argument);
uint32_t SD_CMD_DeselectCard(struct_SD_t *SDx);
/* SD_CMD_GoIdleState */
uint32_t SD_CMD_GoIdleState(struct_SD_t *SDx);
/* SD_CMD_VoltageSwitch */
uint32_t SD_CMD_VoltageSwitch(struct_SD_t *SDx);
/* SD_CMD_SwitchFunc */
uint32_t SD_CMD_SwitchFunc(struct_SD_t *SDx, uint32_t fu32_Argument);
/* SD_CMD_AllSendCID */
/* SD_CMD_SendRelAddr */
/* SD_CMD_SendCSD */
/* SD_CMD_SendStatus */
/* SD_CMD_SendInterfaceCondition */
uint32_t SD_CMD_AllSendCID(struct_SD_t *SDx, uint32_t *fp32_Response);
uint32_t SD_CMD_SendRelAddr(struct_SD_t *SDx, uint32_t *fp32_RCA);
uint32_t SD_CMD_SendCSD(struct_SD_t *SDx, uint32_t fu32_Argument, uint32_t *fp32_Response);
uint32_t SD_CMD_SendStatus(struct_SD_t *SDx, uint32_t fu32_Argument, uint32_t *fp_Resp);
uint32_t SD_CMD_SendInterfaceCondition(struct_SD_t *SDx);
/* SD_CMD_AppCommand */
uint32_t SD_CMD_AppCommand(struct_SD_t *SDx, uint32_t fu32_Argument);
/* SD_ACMD_SendOperCondition */
/* SD_ACMD_SetBusWidth */
uint32_t SD_ACMD_SendOperCondition(struct_SD_t *SDx, uint32_t fu32_Argument, uint32_t *fp32_Response);
uint32_t SD_ACMD_SetBusWidth(struct_SD_t *SDx, uint32_t fu32_Argument);
/* SD_SDCardClass_Init */
/* SD_SDMMCClass_Init */
void SD_SDCardClass_Init(struct_SD_t *SDx);
void SD_SDMMCClass_Init(struct_SD_t *SDx);
/* MMC_CMD_GoIdleState */
/* MMC_CMD_AllSendCID */
/* MMC_CMD_SendCSD */
/* MMC_CMD_SelectCard */
/* MMC_CMD_DeselectCard */
#define MMC_CMD_GoIdleState SD_CMD_GoIdleState
#define MMC_CMD_AllSendCID SD_CMD_AllSendCID
#define MMC_CMD_SendCSD SD_CMD_SendCSD
#define MMC_CMD_SelectCard SD_CMD_SelectCard
#define MMC_CMD_DeselectCard SD_CMD_DeselectCard
#define MMC_CMD_SendStatus SD_CMD_SendStatus
/* SD_CMD_SetBlockCount */
#define MMC_CMD_SetBlockCount SD_CMD_SetBlockCount
/* MMC_CMD_ReadSingleBlock */
/* MMC_CMD_ReadMultiBlock */
/* MMC_CMD_ReadBlock_SDMA */
#define MMC_CMD_ReadSingleBlock SD_CMD_ReadSingleBlock
#define MMC_CMD_ReadMultiBlock SD_CMD_ReadMultiBlock
#define MMC_CMD_ReadBlock_SDMA SD_CMD_ReadBlock_SDMA
/* MMC_CMD_WriteSingleBlock */
/* MMC_CMD_WriteMultiBlock */
/* MMC_CMD_WriteBlock_SDMA */
#define MMC_CMD_WriteSingleBlock SD_CMD_WriteSingleBlock
#define MMC_CMD_WriteMultiBlock SD_CMD_WriteMultiBlock
#define MMC_CMD_WriteBlock_SDMA SD_CMD_WriteBlock_SDMA
/* MMC_CMD_SendOperCondition */
uint32_t MMC_CMD_SendOperCondition(struct_SD_t *SDx, uint32_t fu32_Argument, uint32_t *fp32_Response);
/* MMC_CMD_SendExtendedCSD */
uint32_t MMC_CMD_SendExtendedCSD(struct_SD_t *SDx);
/* MMC_CMD_SetRelAddr */
uint32_t MMC_CMD_SetRelAddr(struct_SD_t *SDx, uint32_t fu32_RCA);
/* MMC_CMD_Switch */
uint32_t MMC_CMD_Switch(struct_SD_t *SDx, uint32_t fu32_Argument);
#endif

View File

@ -0,0 +1,254 @@
/*
******************************************************************************
* @file driver_sd_card.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2022
* @brief Header file of SD card application HAL module.
******************************************************************************
* @attention
*
* Copyright (c) 2022 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_SD_CARD_H__
#define __DRIVER_SD_CARD_H__
#include "fr30xx.h"
/** @addtogroup SD_Card_Initialization_Config_Section
* @{
*/
/* ################################ Initialization<6F><6E>Config Section Start ################################ */
#define BLOCKSIZE (512U) /*!< Block size is 512 bytes */
#define SDMA_ADDR_ALIGN_MASK (0xFFF80000U) /*!< SDMA align 512K Bytes */
#define SDMA_ADDR_UNIT (0x80000U)
#define CARD_STATUS_IDLE (0x0) /*!< Card status idle */
#define CARD_STATUS_READ_BUSY (0x1) /*!< Card status read busy */
#define CARD_STATUS_WIRTE_BUSY (0x2) /*!< Card status write busy */
#define CARD_STATUS_ERASE_BUSY (0x3) /*!< Card status erase busy */
#define CARD_STATUS_ERR (0x4) /*!< Card status error */
/* card version */
#define CARD_VER_1_X (1U)
#define CARD_VER_2_X (2U)
/* card type */
#define CARD_TYPE_SDHC_SDXC (1U)
#define CARD_TYPE_SDSC (2U)
/* SDIO bus width */
#define SDIO_BUS_WIDTH_1BIT (0U)
#define SDIO_BUS_WIDTH_4BIT (2U)
/* Card current state in R1 */
#define CARD_CURRENT_STATE_IDLE (0x000)
#define CARD_CURRENT_STATE_READY (0x200)
#define CARD_CURRENT_STATE_IDENT (0x400)
#define CARD_CURRENT_STATE_STBY (0x600)
#define CARD_CURRENT_STATE_TRAN (0x800)
#define CARD_CURRENT_STATE_DATA (0xA00)
#define CARD_CURRENT_STATE_RCV (0xC00)
#define CARD_CURRENT_STATE_PRG (0xE00)
#define CARD_CURRENT_STATE_DIS (0x1000)
#define CARD_CURRENT_STATE_MASK (0x1E00)
/* ACMD41 argument */
#define ACMD41_ARG_VOLTAGE_WINDOW_27_28 (0x00008000) // VDD Voltage Window 2.7V~2.8V
#define ACMD41_ARG_VOLTAGE_WINDOW_28_29 (0x00010000) // VDD Voltage Window 2.8V~2.9V
#define ACMD41_ARG_VOLTAGE_WINDOW_29_30 (0x00020000) // VDD Voltage Window 2.9V~3.0V
#define ACMD41_ARG_VOLTAGE_WINDOW_30_31 (0x00040000) // VDD Voltage Window 3.0V~3.1V
#define ACMD41_ARG_VOLTAGE_WINDOW_31_32 (0x00080000) // VDD Voltage Window 3.1V~3.2V
#define ACMD41_ARG_VOLTAGE_WINDOW_32_33 (0x00100000) // VDD Voltage Window 3.2V~3.3V
#define ACMD41_ARG_VOLTAGE_WINDOW_33_34 (0x00200000) // VDD Voltage Window 3.3V~3.4V
#define ACMD41_ARG_VOLTAGE_WINDOW_34_35 (0x00400000) // VDD Voltage Window 3.4V~3.5V
#define ACMD41_ARG_VOLTAGE_WINDOW_35_36 (0x00800000) // VDD Voltage Window 3.5V~3.6V
#define ACMD41_ARG_S18R (0x01000000) // switch to 1.8V Accepted
#define ACMD41_ARG_XPC (0x10000000) // 150mA(max) and speed class is supported
#define ACMD41_ARG_HCS (0x40000000) // host capacity support information
/* OCR register fields definition */
#define OCR_BUSY (0x80000000) // Card power up status bit
#define OCR_CCS (0x40000000) // Card capacity status
#define OCR_S18A (0x01000000) // switch to 1.8V Accepted
/* error code */
#define E1_NUM_ERR (0x0001) // Number of SD blocks is 0.
#define E2_1_8V_ERR (0x0002) // Card not support 1.8V.
#define E3_SPEED_ERR (0x0004) // Card not support selected Speed.
#define E4_CARD_BUSY (0x0005) // Card busy.
/*
* @brief CSD register definition.
*/
typedef struct
{
uint32_t rsv_0 : 2;
uint32_t FILE_FORMAT : 2; /*!< file format */
uint32_t TMP_WRITE_PROTECT : 1; /*!< temporary write protection */
uint32_t PERM_WRITE_PROTECT : 1; /*!< permanent write protection */
uint32_t COPY : 1; /*!< copy flag */
uint32_t FILE_FORMAT_GRP : 1; /*!< file format group */
uint32_t rsv_1 : 5;
uint32_t WRITE_BL_PARTIAL : 1; /*!< partial blocks for write allowed */
uint32_t WRITE_BL_LEN : 4; /*!< max. write data block length */
uint32_t R2W_FACTOR : 3; /*!< write speed factor */
uint32_t rsv_2 : 2;
uint32_t WP_GRP_ENABLE : 1; /*!< write protect group enable */
uint32_t WP_GRP_SIZE : 7; /*!< write protect group size */
uint32_t SECTOR_SIZE_H : 1; /*!< erase sector seize */
uint32_t SECTOR_SIZE_L : 6; /*!< erase sector seize */
uint32_t REASE_BLK_EN : 1; /*!< erase single block enable */
uint32_t rsv_3 : 1;
uint32_t C_SIZE : 22; /*!< device size. 22-bit */
uint32_t rsv_4 : 2;
uint32_t rsv_5 : 4;
uint32_t DSR_IMP : 1; /*!< DSR implemented */
uint32_t READ_BLK_MISALIGN : 1; /*!< read block misalignment */
uint32_t WRITE_BLK_MISALIGN : 1; /*!< write block misalignment */
uint32_t READ_BL_PARTIAL : 1; /*!< partial blocks for read allowed */
uint32_t READ_BL_LEN : 4; /*!< max. read data block length */
uint32_t CCC : 12; /*!< crad command classes */
uint32_t TRAN_SPEED : 8; /*!< max. data transfer rate */
uint32_t NSAC : 8; /*!< data read access in CLK cycles(NSAC*100) */
uint32_t TAAC : 8; /*!< data read access time 1 */
uint32_t rsv_6 : 6;
uint32_t CSD_STRUCTURE : 2; /*!< CSD structure */
uint32_t rsv_7 : 8;
}SD_CardCSDTypeDef;
/*
* @brief CID register definition.
*/
typedef struct
{
uint16_t ManufactDate; /*!< Manufacturing Date */
uint16_t ProductSN_A; /*!< Product Serial Number */
uint16_t ProductSN_B; /*!< Product Serial Number */
uint8_t ProductRevision; /*!< Product Revision */
uint8_t ProductName[5]; /*!< Product Name */
uint16_t OEM_ApplicationID; /*!< OEM/Application ID */
uint8_t ManufacturerID; /*!< Manufacturer ID */
uint8_t rsv_0;
}SD_CardCIDTypeDef;
/*
* @brief SCR register definition.
*/
typedef struct
{
uint32_t SCR_STRUCTURE : 4; /*!< SCR structure */
uint32_t SD_SPEC : 4; /*!< SD Memory Card - spec version */
uint32_t DATA_STAT_AFTER_ERASE : 1; /*!< data status after erases */
uint32_t SD_SECURITY : 3; /*!< CPRM security support */
uint32_t SD_BUS_WIDTHS : 4; /*!< dat bus widths support */
uint32_t SD_SPEC3 : 1; /*!< spec version 3.00 or higher */
uint32_t EX_SUPPORT : 4; /*!< extended security support */
uint32_t rsv_0 : 9;
uint32_t CMD_SUPPORT : 2; /*!< command support bit */
uint32_t Manufacturer : 32; /*!< reserved for Manufacturer usage */
}SD_CardSCRTypeDef;
/*
* @brief SD Card Status definition.
*/
typedef struct
{
uint8_t DAT_BUS_WIDTH; /*!< Shows the currently defined data bus width */
uint8_t SECURED_MODE; /*!< Card is in secured mode of operation */
uint16_t SD_CARD_TYPE; /*!< Carries information about card type */
uint32_t SIZE_OF_PROTECTED_AREA; /*!< Carries information about the capacity of protected area */
uint8_t SPEED_CLASS; /*!< Carries information about the speed class of the card */
uint8_t PERFORMANCE_MOVE; /*!< Carries information about the card's performance move */
uint8_t AU_SIZE; /*!< Carries information about the card's allocation unit size */
uint16_t ERASE_SIZE; /*!< Determines the number of AUs to be erased in one operation */
uint8_t ERASE_TIMEOUT; /*!< Determines the timeout for any number of AU erase */
uint8_t ERASE_OFFSET; /*!< Carries information about the erase offset */
uint8_t UHS_SPEED_GRADE; /*!< speed grade for UHS mode */
uint8_t UHS_AU_SIZE; /*!< Size of AU for UHS mode */
}SD_CardStatusTypeDef;
/**
* @brief SD Card Information Structure definition
*/
typedef struct
{
uint32_t CardType; /*!< Specifies the card Type */
uint32_t CardVersion; /*!< Specifies the card version */
uint32_t Class; /*!< Specifies the class of the card class */
uint32_t MemoryCapacity; /*!< Specifies Memory Capacity in KBytes */
uint32_t SpeedCapacity; /*!< Specifies speed Capacity */
}SD_CardInfoTypeDef;
/*
* @brief SD handle Structure definition
*/
typedef struct
{
struct_SD_t *SDx; /*!< SD registers base address */
struct_SDInit_t Init; /*!< SD communication parameters */
SD_CardInfoTypeDef CardInfo; /*!< SD Card information */
SD_CardCIDTypeDef *CIDInfo; /*!< CID information */
SD_CardCSDTypeDef *CSDInfo; /*!< CSD information */
uint32_t CSD[4]; /*!< SD card CSD register */
uint32_t CID[4]; /*!< SD card CID register */
uint32_t SCR[2]; /*!< SD card SCR register */
uint32_t OCR; /*!< SD card OCR register */
uint32_t RCA; /*!< SD card RCA register */
volatile uint32_t CardStatus; /*!< SD card status */
volatile uint32_t AddrAlign; /*!< SDMA address align */
}SD_HandleTypeDef;
/* ################################ Initialization<6F><6E>Config Section END ################################## */
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/* SDCard_Init */
uint32_t SDCard_Init(SD_HandleTypeDef *hsd);
/* SDCard_BusWidth_Select */
uint32_t SDCard_BusWidth_Select(SD_HandleTypeDef *hsd, uint32_t fu32_BusWidth);
/* Read/Write Blocks */
uint32_t SDCard_ReadBolcks(SD_HandleTypeDef *hsd, uint32_t *fp_Data, uint32_t fu32_BlockAddr, uint16_t fu16_BlockNum);
uint32_t SDCard_WriteBolcks(SD_HandleTypeDef *hsd, uint32_t *fp_Data, uint32_t fu32_BlockAddr, uint16_t fu16_BlockNum);
/* Read/Write Blocks use SDMA */
uint32_t SDCard_ReadBolcks_SDMA(SD_HandleTypeDef *hsd, uint32_t *fp_Data, uint32_t fu32_BlockAddr, uint16_t fu16_BlockNum);
uint32_t SDCard_WriteBolcks_SDMA(SD_HandleTypeDef *hsd, uint32_t *fp_Data, uint32_t fu32_BlockAddr, uint16_t fu16_BlockNum);
/* Read/Write Blocks use SDMA with interrupt */
uint32_t SDCard_ReadBolcks_SDMA_IT(SD_HandleTypeDef *hsd, uint32_t *fp_Data, uint32_t fu32_BlockAddr, uint16_t fu16_BlockNum);
uint32_t SDCard_WriteBolcks_SDMA_IT(SD_HandleTypeDef *hsd, uint32_t *fp_Data, uint32_t fu32_BlockAddr, uint16_t fu16_BlockNum);
/* SDCard_Erase */
uint32_t SDCard_Erase(SD_HandleTypeDef *hsd, uint32_t BlockStartAddr, uint32_t BlockEndAddr);
/* SDCard_Get_Block_count */
uint32_t SDCard_Get_Block_count(SD_HandleTypeDef *hsd);
/* SDCard_IRQHandler */
void SDCard_IRQHandler(SD_HandleTypeDef *hsd);
#endif

View File

@ -0,0 +1,234 @@
/*
******************************************************************************
* @file driver_sd_device.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2022
* @brief Header file of SD device HAL module.
******************************************************************************
* @attention
*
* Copyright (c) 2022 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_SD_DEVICE_H__
#define __DRIVER_SD_DEVICE_H__
#include "fr30xx.h"
/** @addtogroup SD_device_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
/* Capability0 Register */
typedef struct
{
uint32_t ProgramDone : 1;
uint32_t rsv_0 : 1;
uint32_t CardInitDone : 1;
uint32_t AddressOutRange : 1;
uint32_t AddressMisalign : 1;
uint32_t RpmbDisable : 1;
uint32_t EraseParam : 1;
uint32_t CardECCFailed : 1;
uint32_t CCError : 1;
uint32_t Error : 1;
uint32_t MMC_IRQ_Trigger : 1;
uint32_t CMDDataOutputEdge : 1;
uint32_t CMD32_CMD33_Enable : 1;
uint32_t BootSequenceSupport : 1;
uint32_t SwitchError : 1;
uint32_t SendBootACK : 1;
uint32_t WP_Violation : 1;
uint32_t WP_Erase_Skip : 1;
uint32_t CID_CSD_Overwrite : 1;
uint32_t AKE_Seq_Error : 1;
uint32_t Card_ECC_Disabled : 1;
uint32_t StreamThresholdSize : 3;
uint32_t PermanentWriteProtect : 1;
uint32_t TemporaryWriteProtect : 1;
uint32_t WPCommandsEnabled : 1;
uint32_t ALLOW_AKE : 1;
uint32_t SECURED_MODE : 1;
uint32_t AKE_SEQ_OK : 1;
uint32_t ASSD_Disable : 1;
uint32_t BootDataReady : 1;
}REG_SDDevice_Control_t;
/* Command Register */
typedef struct
{
uint32_t Application : 1;
uint32_t BlockSize : 12;
uint32_t CommandIndex : 6;
uint32_t CurrentBusWidth : 2;
uint32_t CurrentSpeed : 3;
uint32_t CardState : 4;
uint32_t EraseSequence : 1;
uint32_t rsv_0 : 3;
}REG_SDDevice_Command_t;
/* Password Length Register */
typedef struct
{
uint32_t PWDS_LEN : 8;
uint32_t LockUnlockEnable : 1;
uint32_t rsv_0 : 23;
}REG_PasswordLength_t;
/* -------------------------------------------------*/
/* SD Device Register */
/* -------------------------------------------------*/
typedef struct
{
volatile REG_SDDevice_Control_t Control; /* Offset 0x00 */
volatile REG_SDDevice_Command_t Command; /* Offset 0x04 */
volatile uint32_t Argument; /* Offset 0x08 */
volatile uint32_t BlockCount; /* Offset 0x0C */
volatile uint32_t DMA1Address; /* Offset 0x10 */
volatile uint32_t DMA1Control; /* Offset 0x14 */
volatile uint32_t DMA2Address; /* Offset 0x18 */
volatile uint32_t DMA2Control; /* Offset 0x1C */
volatile uint32_t EraseWriteBlockStart; /* Offset 0x20 */
volatile uint32_t EraseWriteblockEnd; /* Offset 0x24 */
volatile REG_PasswordLength_t PasswordLength; /* Offset 0x28 */
volatile uint32_t SecureBlockCount; /* Offset 0x2C */
volatile uint32_t rsv_0[3];
volatile uint32_t IntStatus; /* Offset 0x3C */
volatile uint32_t IntStatusEn; /* Offset 0x40 */
volatile uint32_t IntSignalEn; /* Offset 0x44 */
volatile uint32_t CardAddress; /* Offset 0x48 */
volatile uint32_t CardData; /* Offset 0x4C */
volatile uint32_t IOREADY; /* Offset 0x50 */
volatile uint32_t Function1Control; /* Offset 0x54 */
volatile uint32_t Function2Control; /* Offset 0x58 */
volatile uint32_t SDIOCCCRControl; /* Offset 0x5C */
volatile uint32_t SDIOFBRxControl[8]; /* Offset 0x60 ~ 0x7C */
volatile uint32_t CardSize; /* Offset 0x80 */
volatile uint32_t CardOCR; /* Offset 0x84 */
volatile uint32_t Control2; /* Offset 0x88 */
volatile uint32_t rsv_1;
volatile uint32_t Function3Control; /* Offset 0x90 */
volatile uint32_t Function4Control; /* Offset 0x94 */
volatile uint32_t Function5Control; /* Offset 0x98 */
volatile uint32_t IntStatus2; /* Offset 0x9C */
volatile uint32_t IntStatusEn2; /* Offset 0xA0 */
volatile uint32_t IntSignal2; /* Offset 0xA4 */
volatile uint32_t Password_127_96; /* Offset 0xA8 */
volatile uint32_t Password_95_64; /* Offset 0xAC */
volatile uint32_t Password_63_32; /* Offset 0xB0 */
volatile uint32_t Passowrd_31_0; /* Offset 0xB4 */
volatile uint32_t ADMAErrorStatus; /* Offset 0xB8 */
volatile uint32_t RCA; /* Offset 0xBC */
volatile uint32_t Debug[7]; /* Offset 0xC0 ~ 0xD8 */
volatile uint32_t AHBMasterBurstSize; /* Offset 0xDC */
volatile uint32_t Argument2; /* Offset 0xE0 */
}struct_SD_Device_t;
#define SD_DEVICE ((struct_SD_Device_t *)SDIOD0_BASE)
/* ################################ Register Section END ################################## */
/**
* @}
*/
/** @addtogroup SD_device_Initialization_Config_Section
* @{
*/
/* ################################ Initialization<6F><6E>Config Section Start ################################ */
/* SD device interrupt status mask */
typedef enum
{
INT_TRANSFER_COMP = 0x00000001,
INT_DMA1 = 0x00000002,
INT_SLEEP_AWAKE = 0x00000004,
INT_WRITE_START = 0x00000008,
INT_READ_START = 0x00000010,
INT_PASSWORD_SET = 0x00000020,
INT_PASSWORD_RESET = 0x00000040,
INT_LOCK_CARD = 0x00000080,
INT_UNLOCK_CARD = 0x00000100,
INT_FORCE_ERASE = 0x00000200,
INT_ERASE = 0x00000400,
INT_CMD11 = 0x00000800,
INT_CMD0_CMD52 = 0x00001000,
INT_CMD6_CHECK = 0x00002000,
INT_CMD6_SWITCH = 0x00004000,
INT_PROGRAM_CSD = 0x00008000,
INT_ACMD23 = 0x00010000,
INT_CMD20 = 0x00020000,
/* 0x00040000 */
INT_CMD4 = 0x00080000,
INT_BOOT_START = 0x00100000,
INT_FUNCTION1_RESET = 0x00200000,
INT_FUNCTION2_RESET = 0x00400000,
INT_CMD11_CLK_STOP = 0x00800000,
INT_CMD11_CLK_START = 0x01000000,
INT_PROGRAM_START = 0x02000000,
INT_CMD40 = 0x04000000,
INT_CMD_R1b = 0x08000000,
INT_FUNCTIONX_ERROR = 0x10000000,
INT_FUNCTIONX_ABORT = 0x20000000,
INT_LRST = 0x40000000,
INT_BOOT_COMPLETE = 0x80000000,
}enum_SD_Device_Status_t;
/* ################################ Initialization<6F><6E>Config Section END ################################## */
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
/* ----------------------*/
/* Control control */
/* ----------------------*/
/* Program Done */
#define __SD_D_SET_PROGRAM_DONE(__SDx__) (__SDx__->Control.ProgramDone = 1)
/* Card Init Done */
#define __SD_D_CARD_INIT_DONE(__SDx__) (__SDx__->Control.CardInitDone = 1)
/* Address Out of Range */
#define __SD_D_ADDR_OUT_RANGE(__SDx__) (__SDx__->Control.AddressOutRange = 1)
/* Address Misalign */
#define __SD_D_ADDR_MISALIGN(__SDx__) (__SDx__->Control.AddressMisalign = 1)
/* Command and Data Output at the falling edge */
/* Command and Data Output at the Rising edge */
#define __SD_D_FALLING_EDGE_OUTPUT(__SDx__) (__SDx__->Control.CMDDataOutputEdge = 0)
#define __SD_D_RISING_EDGE_OUTPUT(__SDx__) (__SDx__->Control.CMDDataOutputEdge = 1)
/* support/nonsupport CMD32 CMD33 */
#define __SD_D_CMD32_CMD33_ENABLE(__SDx__) (__SDx__->Control.CMD32_CMD33_Enable = 0)
#define __SD_D_CMD32_CMD33_DISABLE(__SDx__) (__SDx__->Control.CMD32_CMD33_Enable = 1)
/* Stream Threshold Size */
#define __SD_D_SET_STREAM_THRESHOLD_SIZE(__SDx__, __SIZE__) (__SDx__->Control.StreamThresholdSize = __SIZE__)
/* Set card address */
/* Set card data */
#define __SD_D_SET_CARD_ADDR(__SDx__, __ADDR__) (__SDx__->CardAddress = __ADDR__)
#define __SD_D_SET_CARD_DATA(__SDx__, __DATA__) (__SDx__->CardData = __DATA__)
/* get interrupt status */
#define __SD_D_GET_INT_STATUS(__SDx__) (__SDx__->IntStatus)
/* clear interrupt status */
#define __SD_D_CLR_INT_STATUS(__SDx__, __STATUS__) (__SDx__->IntStatus |= __STATUS__)
/* interrupt Status enable/disable */
#define __SD_D_INT_STATUS_ENABLE(__SDx__, __STATUS__) (__SDx__->IntStatusEn |= (__STATUS__))
#define __SD_D_INT_STATUS_DISABLE(__SDx__, __STATUS__) (__SDx__->IntStatusEn &= ~(__STATUS__))
#define __SD_D_INT_STATUS_ALL_ENABLE(__SDx__) (__SDx__->IntStatusEn = 0xFFFFFFFF)
#define __SD_D_INT_STATUS_ALL_DISABLE(__SDx__) (__SDx__->IntStatusEn = 0x00000000)
/* interrupt Signal enable/disable */
#define __SD_D_INT_ENABLE(__SDx__, __STATUS__) (__SDx__->IntSignalEn |= (__STATUS__))
#define __SD_D_INT_DISABLE(__SDx__, __STATUS__) (__SDx__->IntSignalEn &= ~(__STATUS__))
/* Exported functions --------------------------------------------------------*/
#endif

View File

@ -0,0 +1,212 @@
/*
******************************************************************************
* @file driver_sd_mmc.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2022
* @brief Header file of Multi-Media card application HAL module.
******************************************************************************
* @attention
*
* Copyright (c) 2022 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_SD_MMC_H__
#define __DRIVER_SD_MMC_H__
#include "fr30xx.h"
/** @addtogroup eMMC_Card_Initialization_Config_Section
* @{
*/
/* ################################ Initialization<6F><6E>Config Section Start ################################ */
/* MMC Voltage mode */
#define eMMC_HIGH_VOLTAGE_RANGE 0xC0FF8000U /*!< for eMMC > 2Gb sector mode */
#define eMMC_DUAL_VOLTAGE_RANGE 0xC0FF8080U /*!< for eMMC > 2Gb sector mode */
/* MMC Memory Cards type */
#define eMMC_DUAL_VOLTAGE_CARD 0x00000080U
#define eMMC_CAPACITY_HIGHER_2G 0x40000000U
/*
* @brief Extended CSD revisions
*/
#define MMC_REV_V4_0 (0)
#define MMC_REV_V4_1 (1)
#define MMC_REV_V4_2 (2)
#define MMC_REV_V4_3 (3)
#define MMC_REV_V4_41 (5)
#define MMC_REV_V4_45 (6)
/*
* @brief MMC speed supports in
*/
#define MMC_DEVICE_TPYE_HS200_1_2V (0x20)
#define MMC_DEVICE_TPYE_HS200_1_8V (0x10)
#define MMC_DEVICE_TPYE_HIGH_SPEED_DUAL_1_2V (0x08)
#define MMC_DEVICE_TPYE_HIGH_SPEED_DUAL_1_8V_3V (0x04)
#define MMC_DEVICE_TPYE_HIGH_SPEED_SINGLE_52MHz (0x02)
#define MMC_DEVICE_TPYE_HIGH_SPEED_SINGLE_26MHz (0x01)
/* MMC bus width */
#define MMC_BUS_WIDTH_1BIT (0U)
#define MMC_BUS_WIDTH_4BIT (1U)
#define MMC_BUS_WIDTH_8BIT (2U)
/* MMC CMD6 access mode */
#define MMC_CMD6_ACCESS_CMD_SET (0x00000000)
#define MMC_CMD6_ACCESS_SET_BITS (0x01000000)
#define MMC_CMD6_ACCESS_CLR_BITS (0x02000000)
#define MMC_CMD6_ACCESS_WRITE_BYTE (0x03000000)
/*
* @brief The parameter index in the Extended CSD register.
*/
#define MMC_EX_CSD_INDEX_SEC_COUNT0 (212)
#define MMC_EX_CSD_INDEX_SEC_COUNT1 (213)
#define MMC_EX_CSD_INDEX_SEC_COUNT2 (214)
#define MMC_EX_CSD_INDEX_SEC_COUNT3 (215)
#define MMC_EX_CSD_INDEX_DEVICE_TYPE (196)
#define MMC_EX_CSD_INDEX_EXT_CSD_REV (192)
#define MMC_EX_CSD_INDEX_HS_TIMING (185)
#define MMC_EX_CSD_INDEX_BUS_WIDTH (183)
/*
* @brief MMC CSD register definition.
*/
typedef struct
{
uint32_t ECC : 2; /*!< ECC code */
uint32_t FILE_FORMAT : 2; /*!< file format */
uint32_t TMP_WRITE_PROTECT : 1; /*!< temporary write protection */
uint32_t PERM_WRITE_PROTECT : 1; /*!< permanent write protection */
uint32_t COPY : 1; /*!< copy flag */
uint32_t FILE_FORMAT_GRP : 1; /*!< file format group */
uint32_t CONTENT_PROT_APP : 1; /*!< content protection application */
uint32_t rsv_0 : 4;
uint32_t WRITE_BL_PARTIAL : 1; /*!< partial blocks for write allowed */
uint32_t WRITE_BL_LEN : 4; /*!< max. write data block length */
uint32_t R2W_FACTOR : 3; /*!< write speed factor */
uint32_t DEFAULT_ECC : 2;
uint32_t WP_GRP_ENABLE : 1; /*!< write protect group enable */
uint32_t WP_GRP_SIZE : 5; /*!< write protect group size */
uint32_t ERASE_GRP_MULT_L : 3;
uint32_t ERASE_GRP_MULT_H : 2; /*!< Erase group size multiplier */
uint32_t ERASE_GRP_SIZE : 5; /*!< Erase group size */
uint32_t C_SIZE_MULT : 3; /*!< Device size multiplier */
uint32_t VDD_W_CURR_MAX : 3; /*!< Max. write current @ VDD max */
uint32_t VDD_W_CURR_MIN : 3; /*!< Max. write current @ VDD min */
uint32_t VDD_R_CURR_MAX : 3; /*!< Max. read current @ VDD max */
uint32_t VDD_R_CURR_MIN : 3; /*!< Max. read current @ VDD min */
uint32_t C_SIZE_L : 10;
uint32_t C_SIZE_H : 2; /*!< device size. 12-bit */
uint32_t rsv_1 : 2;
uint32_t DSR_IMP : 1; /*!< DSR implemented */
uint32_t READ_BLK_MISALIGN : 1; /*!< read block misalignment */
uint32_t WRITE_BLK_MISALIGN : 1; /*!< write block misalignment */
uint32_t READ_BL_PARTIAL : 1; /*!< partial blocks for read allowed */
uint32_t READ_BL_LEN : 4; /*!< max. read data block length */
uint32_t CCC : 12; /*!< crad command classes */
uint32_t TRAN_SPEED : 8; /*!< max. data transfer rate */
uint32_t NSAC : 8; /*!< data read access in CLK cycles(NSAC*100) */
uint32_t TAAC : 8; /*!< data read access time 1 */
uint32_t rsv_2 : 2;
uint32_t SPEC_VERS : 4; /*!< System specification version */
uint32_t CSD_STRUCTURE : 2; /*!< CSD structure */
uint32_t rsv_3 : 8;
}MMC_CardCSDTypeDef;
/*
* @brief MMC CID register definition.
*/
typedef struct
{
uint8_t ManufactDate; /*!< Manufacturing Date */
uint8_t ProductSN_A; /*!< Product Serial Number */
uint16_t ProductSN_B; /*!< Product Serial Number */
uint8_t ProductSN_C; /*!< Product Serial Number */
uint8_t ProductRevision; /*!< Product Revision */
uint8_t ProductName[6]; /*!< Product Name */
uint8_t OEM_ApplicationID; /*!< OEM/Application ID */
uint8_t BGA; /*!< Device/BGA */
uint8_t ManufacturerID; /*!< Manufacturer ID */
uint8_t rsv_0;
}MMC_CardCIDTypeDef;
/*
* @brief Extended CSD register definition.
*/
typedef struct
{
uint32_t SEC_COUNT; /*!< Sector Count */
uint8_t DEVICE_TYPE; /*!< Device type */
uint8_t EXT_CSD_REV; /*!< Extended CSD revision */
uint8_t HS_TIMING; /*!< High-speed interface timing */
uint8_t BUS_WIDTH; /*!< Bus width mode */
}MMC_CardExCSDTypeDef;
/**
* @brief MMC Card Information Structure definition
*/
typedef struct
{
uint32_t CardType; /*!< Specifies the card Type */
uint32_t Class; /*!< Specifies the class of the card class */
uint32_t MemoryCapacity; /*!< Specifies Memory Capacity in KBytes */
uint32_t Revision; /*!< Specifies the Revision */
}MMC_CardInfoTypeDef;
/*
* @brief eMMC handle Structure definition
*/
typedef struct
{
struct_SD_t *SDx; /*!< SD registers base address */
struct_MMCInit_t Init; /*!< SD communication parameters */
MMC_CardInfoTypeDef CardInfo; /*!< MMC Card information */
MMC_CardCIDTypeDef *CIDInfo; /*!< CID information */
MMC_CardCSDTypeDef *CSDInfo; /*!< CSD information */
MMC_CardExCSDTypeDef ExCSDInfo; /*!< Extended CSD information */
uint32_t CSD[4]; /*!< SD card CSD register */
uint32_t CID[4]; /*!< SD card CID register */
uint32_t OCR; /*!< SD card OCR register */
uint32_t RCA; /*!< SD card RCA register */
}MMC_HandleTypeDef;
/* ################################ Initialization<6F><6E>Config Section END ################################## */
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/* eMMC_Init */
uint32_t eMMC_Init(MMC_HandleTypeDef *hmmc);
/* eMMC_BusWidth_Select */
uint32_t eMMC_BusWidth_Select(MMC_HandleTypeDef *hmmc, uint32_t fu32_BusWidth);
/* Read/Write Blocks */
uint32_t eMMC_ReadBolcks(MMC_HandleTypeDef *hmmc, uint32_t *fp_Data, uint32_t fu32_BlockAddr, uint16_t fu16_BlockNum);
uint32_t eMMC_WriteBolcks(MMC_HandleTypeDef *hmmc, uint32_t *fp_Data, uint32_t fu32_BlockAddr, uint16_t fu16_BlockNum);
/* Read/Write Blocks use SDMA */
uint32_t eMMC_ReadBolcks_SDMA(MMC_HandleTypeDef *hsd, uint32_t *fp_Data, uint32_t fu32_BlockAddr, uint16_t fu16_BlockNum);
uint32_t eMMC_WriteBolcks_SDMA(MMC_HandleTypeDef *hsd, uint32_t *fp_Data, uint32_t fu32_BlockAddr, uint16_t fu16_BlockNum);
#endif

View File

@ -0,0 +1,115 @@
/*
******************************************************************************
* @file driver_sha.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2022
* @brief Header file of sha module.
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_SHA_H__
#define __DRIVER_SHA_H__
#include "fr30xx.h"
/** @addtogroup SHA_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
/*SHA CTRL REG 0x00*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t MODE : 3;//001->SHA-1;010->SHA-256;011->SHA-224;100->SHA-512;101->SHA-384;110->SHA-512/256;111->SHA-512/224
uint32_t INIT_EN : 1;//set this bit to encode thhe messgae with the initial value of A-H(A-E when mask= 010)
uint32_t ISR_EN : 1;//interrupt enable
uint32_t ENDIAN_MODE : 1;//message endian mode 0->big endian 1->little endian
uint32_t CALCULATE : 1;//cpu write this bit to enable calculate.read this bit to verify whether the encoding is complete
uint32_t RSV : 25;
} Bits;
} REG_SHA_CTRL_t;
/*SHA INT STATE REG 0x04*/
typedef volatile union
{
volatile uint32_t Word;
struct
{
uint32_t INT_DONE : 1;//this bit is set by SHA finishing encoding the message and writing the digest to the base address
uint32_t INT_ERROR : 1;//this bit is set by SHA select error mode
uint32_t RSV : 30;
} Bits;
} REG_SHA_INT_STATE_t;
/* ----------------------------------------------*/
/* SHA Registers */
/* ----------------------------------------------*/
typedef struct
{
volatile REG_SHA_CTRL_t SHA_CTRL; /* Offset 0x00 */
volatile REG_SHA_INT_STATE_t SHA_INT_STATE; /* Offset 0x04 */
volatile uint32_t HASH_VAL_L[8]; /* Offset 0x08 - 0x24*/
volatile uint32_t HASH_VAL_H[8]; /* Offset 0x28 - 0x44*/
volatile uint32_t DATA_1[16]; /* Offset 0x48 -0x84 */
volatile uint32_t DATA_2[16]; /* Offset 0x88-0xb4*/
}struct_SEC_SHA_t;
#define SEC_SHA_OFFSET 0x1000
#define SEC_SHA ((struct_SEC_SHA_t *)(SEC_BASE + SEC_SHA_OFFSET))
/* ################################ Register Section END ################################ */
/**
* @}
*/
/** @addtogroup ADC_Initialization_Config_Section
* @{
*/
/* ################################ Initialization, Config Section Start ################################ */
typedef enum{
SHA_1 = 1,
SHA_256 = 2,
SHA_224 = 3,
SHA_512 = 4,
SHA_384 = 5,
SHA_512_OR_256 = 6,
SHA_512_OR_224 = 7
}enum_sha_mode_t;
typedef enum{
SHA_BIG_ENDIAN = 0,
SHA_LITTLE_ENDIAN = 1
}enum_sha_endian_t;
#define SHA_256_BLOCK_SIZE (64)
#define SHA_512_BLOCK_SIZE (128)
/* ################################ Initialization, Config Section END ################################ */
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
#define __SHA_GET_INT_DONE_FALG() (SEC_SHA->SHA_INT_STATE.Bits.INT_DONE)
#define __SHA_INT_ERROR() (SEC_SHA->SHA_INT_STATE.Bits.INT_ERROR == 1)
/* Exported functions --------------------------------------------------------*/
/* sha init */
void sha_init(uint8_t Mode);
/* sha updata */
void sha_update(uint8_t *fp8_Data, uint32_t fu32_Size);
/* sha_final */
void sha_final(uint8_t *DataOut);
#endif

View File

@ -0,0 +1,236 @@
/*
******************************************************************************
* @file driver_spdif.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2023
* @brief Header file of SPDIF module.
******************************************************************************
* @attention
*
* Copyright (c) 2023 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_SPDIF_H__
#define __DRIVER_SPDIF_H__
#include "fr30xx.h"
/** @addtogroup SPDIF_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
/* SPDIF CTRL REG */
typedef struct
{
uint32_t TSAMPLERATE : 8;
uint32_t SFR_ENABLE : 1;
uint32_t SPDIF_ENABLE : 1;
uint32_t FIFO_ENABLE : 1;
uint32_t CLK_ENABLE : 1;
uint32_t TR_MODE : 1;
uint32_t PARITY_CHECK : 1;
uint32_t PARITYGEN : 1;
uint32_t VALIDITY_CHECK : 1;
uint32_t CHANNEL_MODE : 1;
uint32_t DUPLICATE : 1;
uint32_t SETPREAMBB : 1;
uint32_t rsv_0 : 2;
uint32_t PARITY_MASK : 1;
uint32_t UNDERR_MASK : 1;
uint32_t OVERR_MASK : 1;
uint32_t EMPTY_MASK : 1;
uint32_t ALEMPTY_MASK : 1;
uint32_t FULL_MASK : 1;
uint32_t ALFULL_MASK : 1;
uint32_t SYNCERR_MASK : 1;
uint32_t LOCK_MASK : 1;
uint32_t BEGIN_MASK : 1;
uint32_t INTREQ_MASK : 1;
} REG_SPDIF_CTRL_t;
/* SPDIF INT REG */
typedef struct
{
uint32_t RSAMPLERATE : 8;
uint32_t PREAMBLEDEL : 4;
uint32_t rsv_0 : 9;
uint32_t PARITYO : 1;
uint32_t TDATA_UNDERR : 1;
uint32_t RDATA_OVERR : 1;
uint32_t FIFO_EMPTY : 1;
uint32_t FIFO_ALEMPTY : 1;
uint32_t FIFO_FULL : 1;
uint32_t FIFO_ALFULL : 1;
uint32_t SYNC_ERR : 1;
uint32_t LOCK : 1;
uint32_t BLOCK_BEGIN : 1;
uint32_t rsv_1 : 1;
} REG_SPDIF_INT_t;
/* SPDIF FIFO CTRL REG */
typedef struct
{
uint32_t ALEMPTY_THRESHOLD : 7;
uint32_t rsv_0 : 1;
uint32_t HALFULL_THRESHOLD : 7;
uint32_t rsv_1 : 1;
uint32_t PARITY_INT_TYPE : 1;
uint32_t UNDERR_INT_TYPE : 1;
uint32_t OVERR_INT_TYPE : 1;
uint32_t FF_EMPTY_INT_TYPE : 1;
uint32_t FF_ALEMPTY_INT_TYPE : 1;
uint32_t FF_FULL_INT_TYPE : 1;
uint32_t FF_ALFULL_INT_TYPE : 1;
uint32_t SYNCERR_INT_TYPE : 1;
uint32_t LOCK_INT_TYPE : 1;
uint32_t BLOCK_BEGIN_INT_TYPE : 1;
uint32_t rsv_2 : 6;
} REG_SPDIF_FIFO_CTRL_t;
typedef struct
{
volatile REG_SPDIF_CTRL_t SPDIF_CTRL; /* Offset 0x00 */
volatile uint32_t SPDIF_INT_CLEAR; /* Offset 0x04 */
volatile REG_SPDIF_FIFO_CTRL_t SPDIF_FIFO_CTRL; /* Offset 0x08 */
volatile uint32_t SPDIF_INT_STS; /* Offset 0x0C */
volatile uint32_t SPDIF_FIFO_DATA; /* Offset 0x10 */
}struct_SPDIF_t;
#define SPDIF ((struct_SPDIF_t *)SPDIF_BASE)
/* ################################ Register Section END ################################## */
/**
* @}
*/
/** @addtogroup SPDIF_Initialization_Config_Section
* @{
*/
/* ################################ Initialization_Config Section Start ################################ */
/* Interrupt Status */
typedef enum
{
PARITY_FLAG = 0x200000,
UNDERR_FLAG = 0x400000,
OVERR_FLAG = 0x800000,
EMPTY_FLAG = 0x1000000,
ALEMPTY_FLAG = 0x2000000,
FULL_FLAG = 0x4000000,
ALFULL_FLAG = 0x8000000,
SYNCERR_FLAG = 0x10000000,
LOCK_FLAG = 0x20000000,
BEGIN_FLAG = 0x40000000,
RIGHT_LEFT = 0x80000000,
}enum_SPDIF_INT_Index_t;
/* MonoStere Select */
typedef enum
{
SPDIF_STEREO,
SPDIF_MONO,
}enum_SPDIF_MonoStere_Sel_t;
/*
* @brief SPDIF Init Structure definition
*/
typedef struct
{
uint8_t TxSampleRate; /*!< Specifies the internal Send sample rate.
This parameter The value can be a value 0~0x7F*/
uint8_t CH_Mode; /*!< Specifies the internal Channel selection.
This parameter can be a value of @ref enum_SPDIF_MonoStere_Sel_t*/
uint8_t RSAMPLERATE; /*!< Specifies the internal Send receive rate.
This parameter The value can be a value 0~0x7F*/
uint8_t PREAMBLEDEL; /*!< Specifies the internal Leader B delay.
This parameter The value can be a value 0~0xF*/
uint8_t ALFIFOEmpty_Threshold; /*!< Specifies the internal FIFO Almost EMPTY Level.
This parameter The value can be a value 0~0x3F*/
uint8_t HALFIFOFull_Threshold; /*!< Specifies the internal FIFO Half FULL Level.
This parameter The value can be a value 0~0x3F*/
}struct_SPDIF_Init_t;
/*
* @brief SPDIF handle Structure definition
*/
typedef struct __SPDIF_HandleTypeDef
{
struct_SPDIF_Init_t Init; /*!< SPDIF communication parameters */
void (*TxCallback)(struct __SPDIF_HandleTypeDef *hspdif); /*!< Callback */
void (*RxCallback)(struct __SPDIF_HandleTypeDef *hspdif); /*!< Callback */
volatile bool b_TxBusy; /*!< SPDIF Receive and Send parameters in interrupt */
volatile bool b_RxBusy;
volatile uint32_t *p_TxData;
volatile uint32_t u32_TxCount;
volatile uint32_t u32_TxSize;
volatile uint32_t *p_RxData;
volatile uint32_t u32_RxCount;
}SPDIF_HandleTypeDef;
/* ################################ Initialization_Config Section END ################################## */
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
/* SPDIF Enable Diable */
#define __SPDIF_ENABLE() (SPDIF->SPDIF_CTRL.SPDIF_ENABLE = 1)
#define __SPDIF_DISABLE() (SPDIF->SPDIF_CTRL.SPDIF_ENABLE = 0)
/* FIFO/TxFIFO level */
#define __SPDIF_FIFO_LEVEL(__LEVEL__) (SPDIF->SPDIF_FIFO_STS = __LEVEL__)
/* FIFO HALFULL and ALEMPTY Threshold level */
#define __SPDIF_FIFO_HALF_FULL_LEVEL(__LEVEL__) (SPDIF->SPDIF_FIFO_CTRL.HALFULL_THRESHOLD = __LEVEL__)
#define __SPDIF_FIFO_ALMOST_EMPTY_LEVEL(__LEVEL__) (SPDIF->SPDIF_FIFO_CTRL.ALEMPTY_THRESHOLD = __LEVEL__)
/* Get Interrupt Status */
#define __SPDIF_GET_INT_STATUS() (SPDIF->SPDIF_INT_STS)
/* FIFO Interrupt ALEMPTY ALFULL Enable and Disable */
#define __SPDIF_ENABLE_ALEMPTY_INT() do{ SPDIF->SPDIF_CTRL.INTREQ_MASK = 1; \
SPDIF->SPDIF_CTRL.ALEMPTY_MASK = 1;}while(0)
#define __SPDIF_DISABLE_ALEMPTY_INT() do{ SPDIF->SPDIF_CTRL.INTREQ_MASK = 0; \
SPDIF->SPDIF_CTRL.ALEMPTY_MASK = 0;}while(0)
#define __SPDIF_ENABLE_ALFULL_INT() do{ SPDIF->SPDIF_CTRL.INTREQ_MASK = 1; \
SPDIF->SPDIF_CTRL.SYNCERR_MASK = 1; \
SPDIF->SPDIF_CTRL.ALFULL_MASK = 1;}while(0)
#define __SPDIF_DISABLE_ALFULL_INT() do{ SPDIF->SPDIF_CTRL.INTREQ_MASK = 0; \
SPDIF->SPDIF_CTRL.SYNCERR_MASK = 0; \
SPDIF->SPDIF_CTRL.ALFULL_MASK = 0;}while(0)
/* Get FIFO Interrupt Enable */
#define __SPDIF_IS_INT_ALEMPTY() (SPDIF->SPDIF_CTRL.ALEMPTY_MASK)
#define __SPDIF_IS_INT_ALFULL() (SPDIF->SPDIF_CTRL.ALFULL_MASK)
#define __SPDIF_IS_INT_SYNCERR() (SPDIF->SPDIF_CTRL.SYNCERR_MASK)
/* TR MODE */
#define __SPDIF_Tx_MODE() (SPDIF->SPDIF_CTRL.TR_MODE = 1)
#define __SPDIF_Rx_MODE() (SPDIF->SPDIF_CTRL.TR_MODE = 0)
/* Exported functions -------------------------------------------------------------------------*/
void spdif_init(SPDIF_HandleTypeDef *hspdif);
bool spdif_msg_send(SPDIF_HandleTypeDef *hspdif, uint32_t *fp_Data, uint32_t fu32_Size);
bool spdif_msg_send_IT(SPDIF_HandleTypeDef *hspdif, uint32_t *fp_Data, uint32_t fu32_Size);
bool spdif_msg_receive(SPDIF_HandleTypeDef *hspdif, uint32_t *fp_Data);
bool spdif_msg_receive_IT(SPDIF_HandleTypeDef *hspdif, uint32_t *fp_Data);
void SPDIF_IRQHandler(SPDIF_HandleTypeDef *hspdif);
#endif

View File

@ -0,0 +1,557 @@
/*
******************************************************************************
* @file driver_spi.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief Header file of SPI HAL module.
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_SPI_H__
#define __DRIVER_SPI_H__
#include "fr30xx.h"
/** @addtogroup SPI_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
/* Control Register 0 */
typedef struct
{
uint32_t rsv_0 : 4;
uint32_t FRF : 2;
uint32_t SCPH : 1;
uint32_t SCPOL : 1;
uint32_t TMOD : 2;
uint32_t SLV_OE : 1;
uint32_t rsv_1 : 1;
uint32_t CFS : 4;
uint32_t DFS_32 : 5;
uint32_t SPI_FRF : 2;
uint32_t rsv_2 : 1;
uint32_t SSTE : 1;
uint32_t rsv_3 : 7;
}REG_Control0_t;
/* Control Register 1 */
typedef struct
{
uint32_t NDF : 16;
uint32_t rsv_0 : 16;
}REG_Control1_t;
/* Microwire Control Register */
typedef struct
{
uint32_t MWMOD : 1;
uint32_t DMM : 1;
uint32_t MHS : 1;
uint32_t rsv_0 : 29;
}REG_MWCR_t;
/* Status Register */
typedef union
{
volatile struct
{
uint32_t BUSY : 1;
uint32_t TFNF : 1;
uint32_t TFE : 1;
uint32_t RFNE : 1;
uint32_t RFF : 1;
uint32_t TXE : 1;
uint32_t DCOL : 1;
uint32_t rsv_0 : 25;
}SR_BIT;
uint32_t SR_DWORD;
}REG_SR_t;
/* Interrupt Mask Register */
typedef struct
{
uint32_t TXEIM : 1;
uint32_t TXOIM : 1;
uint32_t RXUIM : 1;
uint32_t RXOIM : 1;
uint32_t RXFIM : 1;
uint32_t MSTIM : 1;
uint32_t rsv_0 : 26;
}REG_IMR_t;
/* Interrupt Status Register */
typedef union
{
struct
{
uint32_t TXEIS : 1;
uint32_t TXOIS : 1;
uint32_t RXUIS : 1;
uint32_t RXOIS : 1;
uint32_t RXFIS : 1;
uint32_t MSTIS : 1;
uint32_t rsv_0 : 26;
}ISR_BIT;
uint32_t ISR_DWORD;
}REG_ISR_t;
/* Raw Interrupt Status Register */
typedef union
{
struct
{
uint32_t TXEIR : 1;
uint32_t TXOIR : 1;
uint32_t RXUIR : 1;
uint32_t RXOIR : 1;
uint32_t RXFIR : 1;
uint32_t MSTIR : 1;
uint32_t rsv_0 : 26;
}RISR_BIT;
uint32_t RISR_DWORD;
}REG_RISR_t;
/* DMA Control Register */
typedef struct
{
uint32_t RDMAE : 1;
uint32_t TDMAE : 1;
uint32_t rsv_0 : 30;
}REG_DMACR_t;
/* Control Register 2 */
typedef struct
{
uint32_t TRANS_TYPE : 2;
uint32_t ADDR_L : 4;
uint32_t rsv_0 : 2;
uint32_t INST_L : 2;
uint32_t DUAL_DEVICE_ACCESS : 1;
uint32_t WAIT_CYCLES : 5;
uint32_t DDR_EN : 1;
uint32_t rsv_1 : 3;
uint32_t TX_ENDIAN : 2;
uint32_t RX_ENDIAN : 2;
uint32_t rsv_2 : 4;
uint32_t SPI_CLOCK_FIX : 1;
uint32_t SPI_RX_NO_INST_ADD : 1;
uint32_t SLV_DUAL_MODE : 1;
uint32_t SLV_QUAD_MODE : 1;
}REG_Control2_t;
/* Flow Control Register */
typedef struct
{
uint32_t RX_FLOW_LR : 7;
uint32_t rsv_0 : 1;
uint32_t RX_FLOW_EN : 1;
uint32_t rsv_1 : 7;
uint32_t TX_FLOW_LR : 7;
uint32_t rsv_2 : 1;
uint32_t TX_FLOW_EN : 1;
uint32_t rsv_3 : 7;
}
REG_Flow_Control_t;
/* -----------------------------------------------*/
/* SPI Register */
/* -----------------------------------------------*/
typedef struct
{
volatile REG_Control0_t CTRL0; /* Offset 0x00 */
volatile REG_Control1_t CTRL1; /* Offset 0x04 */
volatile uint32_t SSI_EN; /* Offset 0x08 */
volatile REG_MWCR_t MWCR; /* Offset 0x0C */
volatile uint32_t SER; /* Offset 0x10 */
volatile uint32_t BAUDR; /* Offset 0x14 */
volatile uint32_t TXFTLR; /* Offset 0x18 */
volatile uint32_t RXFTLR; /* Offset 0x1C */
volatile uint32_t TXFLR; /* Offset 0x20 */
volatile uint32_t RXFLR; /* Offset 0x24 */
volatile REG_SR_t SR; /* Offset 0x28 */
volatile REG_IMR_t IMR; /* Offset 0x2C */
volatile REG_ISR_t ISR; /* Offset 0x30 */
volatile REG_RISR_t RISR; /* Offset 0x34 */
volatile uint32_t TXOICR; /* Offset 0x38 */
volatile uint32_t RXOICR; /* Offset 0x3C */
volatile uint32_t RXUICR; /* Offset 0x40 */
volatile uint32_t MSTICR; /* Offset 0x44 */
volatile uint32_t ICR; /* Offset 0x48 */
volatile REG_DMACR_t DMACR; /* Offset 0x4C */
volatile uint32_t DMATDLR; /* Offset 0x50 */
volatile uint32_t DMARDLR; /* Offset 0x54 */
volatile uint32_t rsv_0[2];
volatile uint32_t DR; /* Offset 0x60 */
volatile uint32_t rsv_1[35];
volatile uint32_t RX_SAMPLE_DLY; /* Offset 0xF0 */
volatile REG_Control2_t CTRL2; /* Offset 0xF4 */
volatile uint32_t TED; /* Offset 0xF8 */
volatile REG_Flow_Control_t FLOW_CTRL; /* Offset 0xFC */
}struct_SPI_t;
#define SPIM0 ((struct_SPI_t *)SPIM0_BASE)
#define SPIM1 ((struct_SPI_t *)SPIM1_BASE)
#define SPIM2 ((struct_SPI_t *)SPIM2_BASE)
#define SPIS0 ((struct_SPI_t *)SPIS0_BASE)
#define SPIS1 ((struct_SPI_t *)SPIS1_BASE)
#define SPIMX8_0 ((struct_SPI_t *)SPIMX8_0_BASE)
#define SPIMX8_1 ((struct_SPI_t *)SPIMX8_1_BASE)
/* ################################ Register Section END ################################## */
/**
* @}
*/
/** @addtogroup SPI_Initialization_Config_Section
* @{
*/
/* ################################ Initialization<6F><6E>Config Section Start ################################ */
/* SPI Frame Size */
typedef enum
{
SPI_FRAME_SIZE_4BIT = 3,
SPI_FRAME_SIZE_5BIT,
SPI_FRAME_SIZE_6BIT,
SPI_FRAME_SIZE_7BIT,
SPI_FRAME_SIZE_8BIT,
SPI_FRAME_SIZE_9BIT,
SPI_FRAME_SIZE_10BIT,
SPI_FRAME_SIZE_11BIT,
SPI_FRAME_SIZE_12BIT,
SPI_FRAME_SIZE_13BIT,
SPI_FRAME_SIZE_14BIT,
SPI_FRAME_SIZE_15BIT,
SPI_FRAME_SIZE_16BIT,
SPI_FRAME_SIZE_17BIT,
SPI_FRAME_SIZE_18BIT,
SPI_FRAME_SIZE_19BIT,
SPI_FRAME_SIZE_20BIT,
SPI_FRAME_SIZE_21BIT,
SPI_FRAME_SIZE_22BIT,
SPI_FRAME_SIZE_23BIT,
SPI_FRAME_SIZE_24BIT,
SPI_FRAME_SIZE_25BIT,
SPI_FRAME_SIZE_26BIT,
SPI_FRAME_SIZE_27BIT,
SPI_FRAME_SIZE_28BIT,
SPI_FRAME_SIZE_29BIT,
SPI_FRAME_SIZE_30BIT,
SPI_FRAME_SIZE_31BIT,
SPI_FRAME_SIZE_32BIT,
}enum_FrameSize_t;
/* work mode */
typedef enum
{
SPI_WORK_MODE_0, /* Idle: Low ; sample: first edge */
SPI_WORK_MODE_1, /* Idle: Low ; sample: second edge */
SPI_WORK_MODE_2, /* Idle: High; sample: first edge */
SPI_WORK_MODE_3, /* Idle: High; sample: second edge */
}enum_Work_Mode_t;
/* Instruct Length */
typedef enum
{
INST_0BIT, /* none Instruct */
INST_4BIT, /* 4bit Instruct */
INST_8BIT, /* 8bit Instruct */
INST_16BIT, /* 16bit Instruct */
}enum_InstructLength_t;
/* Address Length */
typedef enum
{
ADDR_0BIT, /* none Address */
ADDR_4BIT, /* 4bit Address */
ADDR_8BIT, /* 8bit Address */
ADDR_12BIT, /* 12bit Address */
ADDR_16BIT, /* 16bit Address */
ADDR_20BIT, /* 20bit Address */
ADDR_24BIT, /* 24bit Address */
ADDR_28BIT, /* 28bit Address */
ADDR_32BIT, /* 32bit Address */
}enum_AddressLength_t;
/* Transfer Type */
typedef enum
{
INST_ADDR_X1, /* Instruct and Address use X1 mode */
INST_1X_ADDR_XX, /* Instruct usb 1X mode, Address use X2/X4 mode */
INST_ADDR_XX, /* Instruct and Address use X2/X4 mode */
}enum_TransferType_t;
/* 2X2/3X Select */
typedef enum
{
Wire_X2 = 1, /* X2 mode */
Wire_X4, /* X4 mode */
Wire_X8, /* X8 mode */
}enum_Wire_X2X4_t;
/* Wire type */
typedef enum
{
Wire_Read, /* Wire_Reade */
Wire_Write, /* Wire_Write */
}enum_Wire_Type_t;
/* TX-RX endian */
typedef enum{
TX_RX_Endian_4321, /* keep origin trans sequence */
TX_RX_Endian_2143, /* TX: MCU writes 0x12345678 to DR, then SPI-core shifts the data as 0x56781234 */
/* RX: input from SPI-bus is 0x12-0x34-0x56-0x78, MCU reads from DR is:
32-bits frame size: 0x56781234
16-bits frame size: 0x12340000, 0x56780000
8-bits frame size: 0x00120000, 0x00340000, 0x00560000, 0x00780000 */
TX_RX_Endian_1234, /* TX: MCU writes 0x12345678 to DR, then SPI-core shifts the data as 0x78563412 */
/* RX: input from SPI-bus is 0x12-0x34-0x56-0x78, MCU reads from DR is:
32-bits frame size: 0x78563412
16-bits frame size: 0x34120000, 0x78560000
8-bits frame size: 0x12000000, 0x34000000, 0x56000000, 0x78000000 */
} enum_TX_RX_Endian_t;
/*
* @brief SPI Init Structure definition
*/
typedef struct
{
uint32_t Work_Mode; /* This parameter can be a value of @ref SPI_WORK_MODE */
uint32_t Frame_Size; /* This parameter can be a value of @ref enum_FrameSize_t */
uint32_t BaudRate_Prescaler; /* This parameter can be a value 2 ~ 65534 */
uint32_t TxFIFOEmpty_Threshold; /* This parameter can be a value 0 ~ 64 */
uint32_t RxFIFOFull_Threshold; /* This parameter can be a value 0 ~ 64 */
}struct_SPIInit_t;
/*
* @brief SPI Multiple wire transfer parameter
*/
typedef struct
{
uint32_t Wire_X2X4X8; /* This parameter can be a value of @ref enum_Wire_X2X4_t */
uint32_t ReceiveWaitCycles; /* This parameter can be a 5bit value */
uint32_t InstructLength; /* This parameter can be a value of @ref enum_InstructLength_t */
uint16_t Instruct; /* This parameter can be a 16bit value */
uint32_t AddressLength; /* This parameter can be a value of @ref enum_AddressLength_t */
uint32_t Address; /* This parameter can be a 32bit value */
uint32_t TransferType; /* This parameter can be a value of @ref enum_TransferType_t */
}struct_MultipleWire_t;
/*
* @brief SPI handle Structure definition
*/
typedef struct __SPI_HandleTypeDef
{
struct_SPI_t *SPIx; /*!< SPI registers base address */
struct_SPIInit_t Init; /*!< SPI communication parameters */
struct_MultipleWire_t MultWireParam; /*!< SPI Multiple wire transfer parameter */
/*!< Used for multi-line transmission */
void (*TxCpltCallback)(struct __SPI_HandleTypeDef *hspi); /*!< Tx complete Callback */
void (*RxCpltCallback)(struct __SPI_HandleTypeDef *hspi); /*!< Rx complete Callback */
volatile uint32_t u32_TxSize; /*!< SPI Transmit parameters in interrupt */
volatile uint32_t u32_TxCount;
union {
volatile void *p_data;
volatile uint8_t *p_u8;
volatile uint16_t *p_u16;
volatile uint32_t *p_u32;
} u_TxData;
volatile bool b_TxBusy;
volatile uint32_t u32_RxSize; /*!< SPI Receive parameters in interrupt */
volatile uint32_t u32_RxCount;
union {
volatile void *p_data;
volatile uint8_t *p_u8;
volatile uint16_t *p_u16;
volatile uint32_t *p_u32;
} u_RxData;
volatile bool b_RxBusy;
}SPI_HandleTypeDef;
/* ################################ Initialization<6F><6E>Config Section END ################################## */
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
/* SPI DDR Enable/Disable/Div */
#define __SPI_DDR_ENABLE(__SPIx__) (__SPIx__->CTRL2.DDR_EN = 1)
#define __SPI_DDR_DISABLE(__SPIx__) (__SPIx__->CTRL2.DDR_EN = 0)
#define __SPI_DDR_DRIVE_DIV(__SPIx__, __DIV__) (__SPIx__->TED = __DIV__)
/* SPI Enable/Disable */
#define __SPI_ENABLE(__SPIx__) (__SPIx__->SSI_EN = 1)
#define __SPI_DISABLE(__SPIx__) (__SPIx__->SSI_EN = 0)
/* SPI Enable/Disable */
#define __SPI_CS_SET(__SPIx__) (__SPIx__->SER = 1)
#define __SPI_CS_RELEASE(__SPIx__) (__SPIx__->SER = 0)
/* Master Standard<72><64>Dual<61><6C>Quad<61><64>Octal mode */
#define __SPI_SET_MODE_X1(__SPIx__) (__SPIx__->CTRL0.SPI_FRF = 0)
#define __SPI_SET_MODE_X2(__SPIx__) (__SPIx__->CTRL0.SPI_FRF = 1)
#define __SPI_SET_MODE_X4(__SPIx__) (__SPIx__->CTRL0.SPI_FRF = 2)
#define __SPI_SET_MODE_X8(__SPIx__) (__SPIx__->CTRL0.SPI_FRF = 3)
#define __SPI_SET_MODE_X2X4X8(__SPIx__, __WIDTH__) (__SPIx__->CTRL0.SPI_FRF = __WIDTH__)
/* Slave Standard<72><64>Dual<61><6C>Quad<61><64>Octal mode */
#define __SPI_SLAVE_SET_MODE_X1(__SPIx__) do{ __SPIx__->CTRL2.SLV_DUAL_MODE = 0; \
__SPIx__->CTRL2.SLV_QUAD_MODE = 0;}while(0)
#define __SPI_SLAVE_SET_MODE_X2(__SPIx__) do{ __SPIx__->CTRL2.SLV_DUAL_MODE = 1; \
__SPIx__->CTRL2.SLV_QUAD_MODE = 0;}while(0)
#define __SPI_SLAVE_SET_MODE_X4(__SPIx__) do{ __SPIx__->CTRL2.SLV_DUAL_MODE = 0; \
__SPIx__->CTRL2.SLV_QUAD_MODE = 1;}while(0)
/* SPI Slave output Enable */
#define __SPI_SLAVE_OUTPUT_ENABLE(__SPIx__) (__SPIx__->CTRL0.SLV_OE = 1)
#define __SPI_SLAVE_OUTPUT_DISABLE(__SPIx__) (__SPIx__->CTRL0.SLV_OE = 0)
/* Transfer mode */
#define __SPI_TMODE_RxTx(__SPIx__) (__SPIx__->CTRL0.TMOD = 0)
#define __SPI_TMODE_Tx_ONLY(__SPIx__) (__SPIx__->CTRL0.TMOD = 1)
#define __SPI_TMODE_Rx_ONLY(__SPIx__) (__SPIx__->CTRL0.TMOD = 2)
#define __SPI_TMODE_FLASH_READ(__SPIx__) (__SPIx__->CTRL0.TMOD = 3)
/* Data Frame Size */
#define __SPI_DATA_FRAME_SIZE(__SPIx__, __SIZE__) (__SPIx__->CTRL0.DFS_32 = __SIZE__)
#define __SPI_DATA_FRAME_SIZE_GET(__SPIx__) (__SPIx__->CTRL0.DFS_32)
/* Receive data size */
#define __SPI_RECEIVE_SIZE(__SPIx__, __SIZE__) (__SPIx__->CTRL1.NDF = __SIZE__)
/* RxFIFO_FULL_THRESHOLD */
/* TxFIFO_EMPTY_THRESHOLD */
#define __SPI_RxFIFO_FULL_THRESHOLD(__SPIx__, __THRESHOLD__) (__SPIx__->RXFTLR = __THRESHOLD__)
#define __SPI_TxFIFO_EMPTY_THRESHOLD(__SPIx__, __THRESHOLD__) (__SPIx__->TXFTLR = __THRESHOLD__)
/* Get Rx/Tx FIFO current level */
#define __SPI_GET_RxFIFO_LEVEL(__SPIx__) (__SPIx__->RXFLR)
#define __SPI_GET_TxFIFO_LEVEL(__SPIx__) (__SPIx__->TXFLR)
/* DMA Enable/Disable, level */
#define __SPI_DMA_RX_ENABLE(__SPIx__) (__SPIx__->DMACR.RDMAE = 1)
#define __SPI_DMA_TX_ENABLE(__SPIx__) (__SPIx__->DMACR.TDMAE = 1)
#define __SPI_DMA_RX_DISABLE(__SPIx__) (__SPIx__->DMACR.RDMAE = 0)
#define __SPI_DMA_TX_DISABLE(__SPIx__) (__SPIx__->DMACR.TDMAE = 0)
#define __SPI_DMA_RX_LEVEL(__SPIx__, __LEVEL__) (__SPIx__->DMARDLR = __LEVEL__)
#define __SPI_DMA_TX_LEVEL(__SPIx__, __LEVEL__) (__SPIx__->DMATDLR = __LEVEL__)
/* SPI busy status */
#define __SPI_IS_BUSY(__SPIx__) (__SPIx__->SR.SR_BIT.BUSY)
/* Tx/Rx FIFO status */
#define __SPI_IS_RxFIFO_EMPTY(__SPIx__) (__SPIx__->SR.SR_BIT.RFNE == 0)
#define __SPI_IS_RxFIFO_NOT_EMPTY(__SPIx__) (__SPIx__->SR.SR_BIT.RFNE == 1)
#define __SPI_IS_RxFIFO_FULL(__SPIx__) (__SPIx__->SR.SR_BIT.RFF == 1)
#define __SPI_IS_TxFIFO_EMPTY(__SPIx__) (__SPIx__->SR.SR_BIT.TFE == 1)
#define __SPI_IS_TxFIFO_FULL(__SPIx__) (__SPIx__->SR.SR_BIT.TFNF == 0)
/* Tx/Rx FIFO interrupt */
#define __SPI_TxFIFO_EMPTY_INT_ENABLE(__SPIx__) (__SPIx__->IMR.TXEIM = 1)
#define __SPI_RxFIFO_FULL_INT_ENABLE(__SPIx__) (__SPIx__->IMR.RXFIM = 1)
#define __SPI_TxFIFO_EMPTY_INT_DISABLE(__SPIx__) (__SPIx__->IMR.TXEIM = 0)
#define __SPI_RxFIFO_FULL_INT_DISABLE(__SPIx__) (__SPIx__->IMR.RXFIM = 0)
#define __SPI_TxFIFO_EMPTY_INT_STATUS(__SPIx__) (__SPIx__->ISR.ISR_BIT.TXEIS)
#define __SPI_RxFIFO_FULL_INT_STATUS(__SPIx__) (__SPIx__->ISR.ISR_BIT.RXFIS)
/* __SPI_RX_SAMPLE_DLY */
#define __SPI_RX_SAMPLE_DLY(__SPIx__, __DELAY__) (__SPIx__->RX_SAMPLE_DLY = __DELAY__)
/* SPI Master CS Toggle Enable */
#define __SPI_CS_TOGGLE_ENABLE(__SPIx__) (__SPIx__->CTRL0.SSTE = 1)
#define __SPI_CS_TOGGLE_DISABLE(__SPIx__) (__SPIx__->CTRL0.SSTE = 0)
/* SPI TX endian setting */
#define __SPI_TX_ENDIAN_SET(__SPIx__, v) (__SPIx__->CTRL2.TX_ENDIAN = v)
/* SPI RX endian setting */
#define __SPI_RX_ENDIAN_SET(__SPIx__, v) (__SPIx__->CTRL2.RX_ENDIAN = v)
/*-----------------------------------------------------------------------------------*/
/* Master Exported functions --------------------------------------------------------*/
/*-----------------------------------------------------------------------------------*/
/* spi_IRQHandler */
void spi_master_IRQHandler(SPI_HandleTypeDef *hspi);
/* spi_master_init */
void spi_master_init(SPI_HandleTypeDef *hspi);
/* Master Standard mode Transmit/Receive */
/* blocking<6E><67>Interrupt<70><74>DMA mode */
void spi_master_transmit_X1(SPI_HandleTypeDef *hspi, void *fp_Data, uint32_t fu32_Size);
void spi_master_transmit_X1_IT(SPI_HandleTypeDef *hspi, void *fp_Data, uint32_t fu32_Size);
void spi_master_transmit_X1_DMA(SPI_HandleTypeDef *hspi);
void spi_master_receive_X1(SPI_HandleTypeDef *hspi, void *fp_Data, uint32_t fu32_Size);
void spi_master_readflash_X1(SPI_HandleTypeDef *hspi, uint16_t *fp_CMD_ADDR, uint32_t fu32_CMDLegnth, uint8_t *fp_Data, uint16_t fu16_Size);
void spi_master_readflash_X1_IT(SPI_HandleTypeDef *hspi, uint8_t *fp_CMD_ADDR, uint32_t fu32_CMDLegnth, uint8_t *fp_Data, uint16_t fu16_Size);
void spi_master_readflash_X1_DMA(SPI_HandleTypeDef *hspi, uint8_t *fp_CMD_ADDR, uint32_t fu32_CMDLegnth, uint16_t fu16_Size);
/* Master Dual<61><6C>Quad mode Transmit/Receive */
/* blocking<6E><67>Interrupt<70><74>DMA mode */
void spi_master_transmit_X2X4X8(SPI_HandleTypeDef *hspi, void *fp_Data, uint32_t fu32_Size);
void spi_master_transmit_X2X4X8_IT(SPI_HandleTypeDef *hspi, void *fp_Data, uint32_t fu32_Size);
void spi_master_transmit_X2X4X8_DMA(SPI_HandleTypeDef *hspi);
void spi_master_receive_X2X4X8(SPI_HandleTypeDef *hspi, void *fp_Data, uint16_t fu16_Size);
void spi_master_receive_X2X4X8_IT(SPI_HandleTypeDef *hspi, void *fp_Data, uint16_t fu16_Size);
void spi_master_receive_X2X4X8_DMA(SPI_HandleTypeDef *hspi, uint16_t fu16_Size);
/* spi_master_MultWireConfig */
/* spi_slave_MultWireConfig */
void spi_master_MultWireConfig(SPI_HandleTypeDef *hspi, enum_Wire_Type_t fe_type);
void spi_slave_MultWireConfig(SPI_HandleTypeDef *hspi, enum_Wire_Type_t fe_type);
/*-----------------------------------------------------------------------------------*/
/* Slave Exported functions ---------------------------------------------------------*/
/*-----------------------------------------------------------------------------------*/
/* spi_slave_IRQHandler */
void spi_slave_IRQHandler(SPI_HandleTypeDef *hspi);
/* spi_slave_init */
void spi_slave_init(SPI_HandleTypeDef *hspi);
/* Slave Standard mode Transmit/Receive */
/* blocking<6E><67>Interrupt<70><74>DMA mode */
void spi_slave_transmit(SPI_HandleTypeDef *hspi, void *fp_Data, uint32_t fu32_Size);
void spi_slave_transmit_IT(SPI_HandleTypeDef *hspi, void *fp_Data, uint32_t fu32_Size);
void spi_slave_transmit_DMA(SPI_HandleTypeDef *hspi);
void spi_slave_receive(SPI_HandleTypeDef *hspi, void *fp_Data, uint32_t fu32_Size);
void spi_slave_receive_IT(SPI_HandleTypeDef *hspi, void *fp_Data, uint32_t fu32_Size);
void spi_slave_receive_DMA(SPI_HandleTypeDef *hspi);
#endif

View File

@ -0,0 +1,118 @@
/*
******************************************************************************
* @file driver_tick.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief Header file of System Tick HAL module.
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_TICK_H__
#define __DRIVER_TICK_H__
#include "fr30xx.h"
/** @addtogroup Tick_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
/* Tick Control Register */
typedef struct
{
uint32_t SMP : 1;
uint32_t UPD : 1;
uint32_t CMP_EN : 1;
uint32_t RST : 1;
uint32_t rsv_0 : 28;
}REG_TickControl_t;
/* Tick Sleep Control Register */
typedef struct
{
uint32_t SLP_ON : 1;
uint32_t SLP_CORR_EN : 1;
uint32_t DELTA : 1;
uint32_t rsv_0 : 29;
}REG_TickSleepControl_t;
/* Tick Interrupt Register */
typedef union
{
uint32_t Word;
struct {
uint32_t SLP : 1;
uint32_t TGT : 1;
uint32_t rsv_0 : 30;
}Bits;
}REG_TickInt_t;
typedef struct
{
volatile REG_TickControl_t CTL; /* Offset 0x00 */
volatile REG_TickSleepControl_t SLP_CTL; /* Offset 0x04 */
volatile uint32_t CLK_SMP; /* Offset 0x08 */
volatile uint32_t FINE_SMP; /* Offset 0x0C */
volatile uint32_t CLK_CORR; /* Offset 0x10 */
volatile uint32_t FINE_CORR; /* Offset 0x14 */
volatile uint32_t CLK_TGT; /* Offset 0x18 */
volatile uint32_t FINE_TGT; /* Offset 0x1C */
volatile uint32_t CLK_UPD; /* Offset 0x20 */
volatile REG_TickInt_t INT_CTL; /* Offset 0x24 */
volatile REG_TickInt_t INT_STA; /* Offset 0x28 */
volatile REG_TickInt_t INT_RAW; /* Offset 0x2C */
}struct_Tick_t;
#define Tick ((struct_Tick_t *)(SYSTEM_TIMER_BASE))
/* ################################ Register Section END ################################## */
/**
* @}
*/
/** @addtogroup Tick_Initialization_Config_Section
* @{
*/
/* ################################ Initialization<6F><6E>Config Section Start ################################ */
/* Tick Interrupt Type */
typedef enum
{
TICK_INT_TYPE_SLP = (1<<0),
TICK_INT_TYPE_TGT = (1<<1),
}enum_TickIntType_t;
/*
* @brief Tick handle Structure definition
*/
typedef struct
{
void (*TickTargetCallback)(void); /*!< Tick reach target Callback */
void (*TickSleepCallback)(void); /*!< wake up frome sleep Callback */
}TICK_HandleTypeDef;
/* ################################ Initialization<6F><6E>Config Section END ################################## */
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
#define TICK_FINE_VALUE_MAX (1000)
/* Exported functions --------------------------------------------------------*/
void tick_IRQHandler(TICK_HandleTypeDef *handle);
void tick_init(TICK_HandleTypeDef *handle);
void tick_get(uint32_t *clk, uint32_t *fine);
void tick_set_target(uint32_t clk, uint32_t fine);
void tick_set_target_IT(uint32_t clk, uint32_t fine);
void tick_start_corr(uint32_t clk, uint32_t fine);
#endif

View File

@ -0,0 +1,79 @@
/*
******************************************************************************
* @file driver_timer.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief Header file of TImer HAL module.
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_TIMER_H__
#define __DRIVER_TIMER_H__
#include "fr30xx.h"
/** @addtogroup Timer_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
/* Timer Control Register */
typedef struct
{
uint32_t ENABLE : 1;
uint32_t MODE : 1;
uint32_t INT_MASK : 1;
uint32_t rsv_0 : 29;
}REG_Control_t;
/* -------------------------------------------------*/
/* Timer Register */
/* -------------------------------------------------*/
typedef struct
{
volatile uint32_t LoadCount; /* Offset 0x00 */
volatile uint32_t CurrentValue; /* Offset 0x04 */
volatile REG_Control_t Control; /* Offset 0x08 */
volatile uint32_t IntClear; /* Offset 0x0C */
volatile uint32_t IntStatus; /* Offset 0x10 */
}struct_Timer_t;
#define Timer0 ((struct_Timer_t *)(TIM0_BASE))
#define Timer1 ((struct_Timer_t *)(TIM1_BASE))
#define Timer2 ((struct_Timer_t *)(TIM2_BASE))
#define Timer3 ((struct_Timer_t *)(TIM3_BASE))
/* ################################ Register Section END ################################## */
/**
* @}
*/
/* Exported functions --------------------------------------------------------*/
/* timer_init */
void timer_init(struct_Timer_t *TIMERx, uint32_t fu32_LoadCount);
/* timer_int_enable */
/* timer_int_disable */
/* timer_int_clear */
/* timer_int_status */
void timer_int_enable(struct_Timer_t *TIMERx);
void timer_int_disable(struct_Timer_t *TIMERx);
void timer_int_clear(struct_Timer_t *TIMERx);
bool timer_int_status(struct_Timer_t *TIMERx);
/* timer_start */
/* timer_stop */
void timer_start(struct_Timer_t *TIMERx);
void timer_stop(struct_Timer_t *TIMERx);
/* timer_get_CurrentCount */
uint32_t timer_get_CurrentCount(struct_Timer_t *TIMERx);
#endif

View File

@ -0,0 +1,89 @@
/*
******************************************************************************
* @file driver_trigfunc.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2023
* @brief Header file of trigfunc module.
******************************************************************************
* @attention
*
* Copyright (c) 2023 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_TRIGFUNC_H__
#define __DRIVER_TRIGFUNC_H__
#include "fr30xx.h"
/** @addtogroup TRIGFUNC_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
#define TRIGFUNC_INTRCR (0x01)
typedef struct
{
volatile uint32_t TRIGFUNC_CTRL; /* Offset 0x00 */
volatile uint32_t TRIGFUNC_INTR; /* Offset 0x04 */
volatile uint32_t TRIGFUNC_ARG1_IN; /* Offset 0x08 */
volatile uint32_t TRIGFUNC_ARG2_IN; /* Offset 0x0c */
volatile uint32_t TRIGFUNC_RESULT1_OUT; /* Offset 0x10 */
volatile uint32_t TRIGFUNC_RESULT2_OUT; /* Offset 0x14*/
volatile uint32_t TRIGFUNC_STATUS; /* Offset 0x18 */
}struct_TRIGFUNC_t;
#define TRIGFUNC ((struct_TRIGFUNC_t *)TRI_FUNC_BASE)
/* ################################ Register Section END ################################## */
/**
* @}
*/
/** @addtogroup TRIGFUNC_Initialization_Config_Section
* @{
*/
/* ################################ Initialization_Config Section Start ################################ */
typedef enum
{
TRIG_CAL_SIN_AND_COS = 0x0u,
TRIG_CAL_TAN = 0x1u,
TRIG_CAL_ARCTAN_X_Y = 0x2u,
TRIG_CAL_ARCTAN_X = 0x3u,
}enum_TRIGFUNC_MODE_SEL_t ;
typedef enum
{
BYTE_1 = 0x000u,
BYTE_2 = 0x100u,
BYTE_3 = 0x200u,
BYTE_ALL = 0x300u,
}enum_NBYTE_SEL_t;
/* ################################ Initialization?Config Section END ################################## */
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
#define QUANTIZATION_PARAMETER (double)((0x10000) / 2)
#define __TRIGFUNC_CAL_IS_DONE_STATUS() (TRIGFUNC->TRIGFUNC_STATUS)
#define __TRIGFUNC_IS_MODE() (TRIGFUNC->TRIGFUNC_CTRL)
#define __TRIGFUNC_CAL_IS_INT_STATUS() (TRIGFUNC->TRIGFUNC_INTR & 0x100)
/* Exported functions ---------------------------------------------------------*/
/* trigfunc_sin */
/* trigfunc_cos */
/* trigfunc_tan */
/* trigfunc_atan */
double trigfunc_sin(double fe_argin);
double trigfunc_cos(double fe_argin);
double trigfunc_tan(double fe_argin);
double trigfunc_atan(double fe_argin);
#endif

View File

@ -0,0 +1,86 @@
/*
******************************************************************************
* @file driver_trng.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2023
* @brief Header file of TRNG HAL module.
******************************************************************************
* @attention
*
* Copyright (c) 2023 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_TRNG_H__
#define __DRIVER_TRNG_H__
#include "fr30xx.h"
/** @addtogroup TRNG_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
/* ------------------------------------------------*/
/* TRNG Register */
/* ------------------------------------------------*/
typedef struct
{
volatile uint32_t rsv_0[64]; /* Offset 0x000 ~ 0x0FC */
volatile uint32_t TRNG_IMR; /* Offset 0x100 */
volatile uint32_t TRNG_ISR; /* Offset 0x104 */
volatile uint32_t TRNG_ICR; /* Offset 0x108 */
volatile uint32_t TRNG_Config; /* Offset 0x10C */
volatile uint32_t TRNG_Valid; /* Offset 0x110 */
volatile uint32_t TRNG_Data[6]; /* Offset 0x114 ~ 0x128 */
volatile uint32_t TRNG_SrcEN; /* Offset 0x12C */
volatile uint32_t TRNG_SAMPLE_CNT1; /* Offset 0x130 */
volatile uint32_t TRNG_AUTOCORR; /* Offset 0x134 */
volatile uint32_t TRNG_DebugControl; /* Offset 0x138 */
volatile uint32_t rsv_1; /* Offset 0x13C */
volatile uint32_t TRNG_Reset; /* Offset 0x140 */
volatile uint32_t rsv_2[29]; /* Offset 0x144 ~ 0x1B4 */
volatile uint32_t TRNG_Busy; /* Offset 0x1B8 */
volatile uint32_t TRNG_ResetBit; /* Offset 0x1BC */
volatile uint32_t rsv_3[8]; /* Offset 0x1C0 ~ 0x1DC */
volatile uint32_t TRNG_BIST_CNTR0; /* Offset 0x1E0 */
volatile uint32_t TRNG_BIST_CNTR1; /* Offset 0x1E4 */
volatile uint32_t TRNG_BIST_CNTR2; /* Offset 0x1E8 */
}struct_TRNG_t;
#define TRNG ((struct_TRNG_t *)TRNG_BASE)
/* ################################ Register Section END ################################## */
/**
* @}
*/
/** @addtogroup TRNG_Initialization_Config_Section
* @{
*/
/* ################################ Initialization<6F><6E>Config Section Start ################################ */
#define TRNG_STATUS_EHR_VALID (0x01)
#define TRNG_STATUS_AUTOCORR_ERR (0x02)
#define TRNG_STATUS_CRNGT_ERR (0x04)
#define TRNG_STATUS_VN_ERR (0x08)
/* ################################ Initialization<6F><6E>Config Section END ################################## */
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/* trng_init */
void trng_init(void);
/* trng_read_rand_num */
void trng_read_rand_num(uint8_t *fp_buffer, uint8_t length);
#endif

View File

@ -0,0 +1,409 @@
/*
******************************************************************************
* @file driver_uart.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief Header file of UART HAL module.
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_UART_H__
#define __DRIVER_UART_H__
#include "fr30xx.h"
/** @addtogroup UART_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
/* DATA/DLL Register */
typedef union
{
uint32_t DATA;
uint32_t DLL;
}REG_DATA_DLL_t;
/* IER/DLH Register */
typedef union
{
struct
{
uint32_t ERBFI : 1;
uint32_t ETBEI : 1;
uint32_t ELSI : 1;
uint32_t EDSSI : 1;
uint32_t rsv_0 : 3;
uint32_t PTIME : 1;
uint32_t rsv_1 : 24;
}IER;
uint32_t DLH;
}REG_IER_DLH_t;
/* FCR/IID Register */
typedef union
{
uint32_t FCR;
uint32_t IID;
}REG_FCR_IID_t;
/* Line control Register */
typedef union
{
struct
{
uint32_t DLS : 2;
uint32_t STOP : 1;
uint32_t PEN : 1;
uint32_t EPS : 1;
uint32_t SP : 1;
uint32_t BC : 1;
uint32_t DLAB : 1;
uint32_t rsv_0 : 24;
}Bits;
uint32_t LCR_W;
}REG_LCR_t;
/* MODEM control Register */
typedef struct
{
uint32_t rsv_0 : 1;
uint32_t RTS : 1;
uint32_t rsv_1 : 3;
uint32_t AFCE : 1;
uint32_t SIRE : 1;
uint32_t rsv_2 : 25;
}REG_MCR_t;
/* Status Register */
typedef union
{
struct
{
uint32_t DR : 1;
uint32_t OE : 1;
uint32_t PE : 1;
uint32_t FE : 1;
uint32_t BI : 1;
uint32_t THRE : 1;
uint32_t TEMT : 1;
uint32_t RFE : 1;
uint32_t rsv_0 : 24;
}LSR_BIT;
uint32_t LSR_DWORD;
}REG_LSR_t;
/* MODEM status Register */
typedef struct
{
uint32_t rsv_0 : 4;
uint32_t CTS : 1;
uint32_t rsv_1 : 27;
}REG_MSR_t;
/* uart status Register */
typedef struct
{
uint32_t rsv_0 : 1;
uint32_t TFNF : 1;
uint32_t TFE : 1;
uint32_t RFNE : 1;
uint32_t RFF : 1;
uint32_t rsv_1 : 27;
}REG_USR_t;
/* DLF Register */
typedef struct
{
uint32_t DLF : 6;
uint32_t rsv_0 : 26;
}REG_DLF_t;
/* ------------------------------------------------*/
/* UART Register */
/* ------------------------------------------------*/
typedef struct
{
volatile REG_DATA_DLL_t DATA_DLL; /* Offset 0x00 */
volatile REG_IER_DLH_t IER_DLH; /* Offset 0x04 */
volatile REG_FCR_IID_t FCR_IID; /* Offset 0x08 */
volatile REG_LCR_t LCR; /* Offset 0x0C */
volatile REG_MCR_t MCR; /* Offset 0x10 */
volatile REG_LSR_t LSR; /* Offset 0x14 */
volatile REG_MSR_t MSR; /* Offset 0x18 */
volatile uint32_t rsv_0[24];
volatile REG_USR_t USR; /* Offset 0x7C */
volatile uint32_t rsv_1[16];
volatile REG_DLF_t DLF; /* Offset 0xC0 */
}struct_UART_t;
#define UART0 ((struct_UART_t *)UART0_BASE)
#define UART1 ((struct_UART_t *)UART1_BASE)
#define UART2 ((struct_UART_t *)UART2_BASE)
#define UART3 ((struct_UART_t *)UART3_BASE)
#define UART4 ((struct_UART_t *)UART4_BASE)
#define UART5 ((struct_UART_t *)UART5_BASE)
/* ################################ Register Section END ################################## */
/**
* @}
*/
/** @addtogroup UART_Initialization_Config_Section
* @{
*/
/* ################################ Initialization<6F><6E>Config Section Start ################################ */
/* Uart data length */
typedef enum
{
UART_DATA_LENGTH_5BIT, /*!< 5-bit Word Length */
UART_DATA_LENGTH_6BIT, /*!< 6-bit Word Length */
UART_DATA_LENGTH_7BIT, /*!< 7-bit Word Length */
UART_DATA_LENGTH_8BIT, /*!< 8-bit Word Length */
}enum_DataLength_t;
/* Stop bit */
typedef enum
{
UART_STOPBITS_1, /*!< UART frame with 1 stop bit */
UART_STOPBITS_2, /*!< UART frame with 2 stop bit */
}enum_StopBit_t;
/* Parity */
typedef enum
{
UART_PARITY_NONE, /*!< No parity */
UART_PARITY_ODD, /*!< Odd parity */
UART_PARITY_EVEN, /*!< Even parity */
UART_PARITY_0, /*!< 0 parity */
UART_PARITY_1, /*!< 1 parity */
}enum_Parity_t;
/* FIFO Enable/Disable */
typedef enum
{
UART_FIFO_DISABLE, /*!< FIFO Disable */
UART_FIFO_ENABLE, /*!< FIFO Enable */
}enum_UART_FIFO_t;
/* AUTO FLOW Enable/Disable */
typedef enum
{
UART_AUTO_FLOW_DISABLE, /*!< AUTO FLOW Disable */
UART_AUTO_FLOW_ENABLE, /*!< AUTO FLOW Enable */
}enum_UART_FLOW_t;
/* Line Status index */
typedef enum
{
STATUS_DR = 0x01, /*!< Data Ready */
STATUS_OE = 0x02, /*!< Over Err */
STATUS_PE = 0x04, /*!< Parity Err */
STATUS_FE = 0x08, /*!< Frame Err */
STATUS_BI = 0x10, /*!< Break ERR */
STATUS_THRE = 0x20, /*!< Tx empty */
STATUS_TEMT = 0x40, /*!< Tx Shift Register empty */
STATUS_RFE = 0x80, /*!< Rx FIFO ERR */
}enum_UART_LINE_STATUS_t;
/* Interrupt Status index */
typedef enum
{
INT_INDEX_MODEM = 0x0, /*!< modem status interrupt */
INT_INDEX_NONE = 0x1, /*!< NONE */
INT_INDEX_TXE = 0x2, /*!< Tx empty interrupt */
INT_INDEX_RX = 0x4, /*!< Rx Threshold interrupt */
INT_INDEX_LINE = 0x6, /*!< Line status interrupt */
INT_INDEX_RX_TOUT = 0xC, /*!< Rx timeout interrupt */
}enum_UART_INT_INDEX_t;
/* FCR BIT position */
typedef enum
{
FCR_FIFOE = 0x00,
FCR_RFIFOR = 0x01,
FCR_XFIFOR = 0x02,
FCR_DMAM = 0x03,
FCR_TET = 0x04,
FCR_RT = 0x06,
}enum_FCR_t;
/*
* @brief UART Init Structure definition
*/
typedef struct
{
uint32_t BaudRate; /*!< This parameter configures the UART communication baud rate. */
uint32_t DataLength; /*!< Specifies the number of data bits transmitted or received in a frame.
This parameter can be a value of @ref enum_DataLength_t. */
uint32_t StopBits; /*!< Specifies the number of stop bits transmitted.
This parameter can be a value of @ref enum_StopBit_t. */
uint32_t Parity; /*!< Specifies the parity mode.
This parameter can be a value of @ref enum_Parity_t. */
uint32_t FIFO_Mode; /*!< Specifies the FIFO mode.
This parameter can be a value of @ref enum_UART_FIFO_t. */
uint32_t AUTO_FLOW; /*!< Specifies the AUTO FLOW.
This parameter can be a value of @ref enum_UART_FLOW_t. */
}struct_UARTInit_t;
/*
* @brief UART handle Structure definition
*/
typedef struct __UART_HandleTypeDef
{
struct_UART_t *UARTx; /*!< UART registers base address */
struct_UARTInit_t Init; /*!< UART communication parameters */
volatile uint32_t FCR_Shadow;
void (*TxCpltCallback)(struct __UART_HandleTypeDef *huart); /* Tx complete Callback */
void (*RxCpltCallback)(struct __UART_HandleTypeDef *huart); /* Rx complete Callback */
volatile uint32_t u32_TxSize; /*!< UART Transmit parameters in interrupt */
volatile uint32_t u32_TxCount;
volatile uint8_t *p_TxData;
volatile bool b_TxBusy;
volatile uint32_t u32_RxSize; /*!< UART Receive parameters in interrupt */
volatile uint32_t u32_RxCount;
volatile uint8_t *p_RxData;
volatile bool b_RxBusy;
}UART_HandleTypeDef;
/* ################################ Initialization<6F><6E>Config Section END ################################## */
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
/* Read/Write FIFO */
#define __UART_READ_FIFO(__UART__) (__UART__->DATA_DLL.DATA)
#define __UART_WRITE_FIFO(__UART__, __DATA__) (__UART__->DATA_DLL.DATA = __DATA__)
/* Set line control */
#define __UART_SET_LINE_CTRL(__UART__, __CTRL__) (__UART__->LCR.LCR_W = __CTRL__)
/* __UART_IS_FIFO_Enable */
/* __UART_FIFO_Enable */
/* __UART_FIFO_Disable */
/* __UART_TxFIFO_Reset */
/* __UART_RxFIFO_Reset */
#define __UART_IS_FIFO_Enable(__UART__) (__UART__->FCR_Shadow & 0x01)
#define __UART_FIFO_Enable(__UART__) do{ __UART__->FCR_Shadow |= 0x01; \
__UART__->FCR_Shadow |= 0x08; \
__UART__->UARTx->FCR_IID.FCR = __UART__->FCR_Shadow; }while(0)
#define __UART_FIFO_Disable(__UART__) do{ __UART__->FCR_Shadow &= ~0x01; \
__UART__->FCR_Shadow &= ~0x08; \
__UART__->UARTx->FCR_IID.FCR = __UART__->FCR_Shadow; }while(0)
#define __UART_TxFIFO_Reset(__UART__) (__UART__->UARTx->FCR_IID.FCR = __UART__->FCR_Shadow | 0x04)
#define __UART_RxFIFO_Reset(__UART__) (__UART__->UARTx->FCR_IID.FCR = __UART__->FCR_Shadow | 0x02)
/* __LEVEL__ = 0: RxFIFO have 1 byte */
/* __LEVEL__ = 1: RxFIFO 1/4 full */
/* __LEVEL__ = 2: RxFIFO 1/2 full */
/* __LEVEL__ = 3: Need 2 byte to full */
#define __UART_RxFIFO_THRESHOLD(__UART__, __LEVEL__) do{ __UART__->FCR_Shadow &= ~0xC0; \
__UART__->FCR_Shadow |= __LEVEL__ << FCR_RT; \
__UART__->UARTx->FCR_IID.FCR = __UART__->FCR_Shadow; }while(0)
/* __LEVEL__ = 0: TxFIFO empty */
/* __LEVEL__ = 1: TxFIFO have 2 byte */
/* __LEVEL__ = 2: TxFIFO 1/4 full */
/* __LEVEL__ = 3: TxFIFO 1/2 full */
#define __UART_TxFIFO_THRESHOLD(__UART__, __LEVEL__) do{ __UART__->FCR_Shadow &= ~0x30; \
__UART__->FCR_Shadow |= __LEVEL__ << FCR_TET; \
__UART__->UARTx->FCR_IID.FCR = __UART__->FCR_Shadow; }while(0)
/* __UART_IS_RxFIFO_FULL */
/* __UART_IS_RxFIFO_EMPTY */
/* __UART_IS_TxFIFO_FULL */
/* __UART_IS_TxFIFO_EMPTY */
#define __UART_IS_RxFIFO_FULL(__UARTx__) (__UARTx__->USR.RFF == 1)
#define __UART_IS_RxFIFO_EMPTY(__UARTx__) (__UARTx__->USR.RFNE == 0)
#define __UART_IS_TxFIFO_FULL(__UARTx__) (__UARTx__->USR.TFNF == 0)
#define __UART_IS_TxFIFO_EMPTY(__UARTx__) (__UARTx__->USR.TFE == 1)
/* uart interrupt enable */
/* uart interrupt disable */
/* uart interrupt get id */
#define __UART_INT_MODEM_ENABLE(__UARTx__) (__UARTx__->IER_DLH.IER.EDSSI = 1)
#define __UART_INT_LINE_STATUS_ENABLE(__UARTx__) (__UARTx__->IER_DLH.IER.ELSI = 1)
#define __UART_INT_RX_ENABLE(__UARTx__) (__UARTx__->IER_DLH.IER.ERBFI = 1)
/* Tx empty interrupt and fifo enable */
#define __UART_INT_TXE_ENABLE_FE(__UARTx__) do{__UARTx__->IER_DLH.IER.PTIME = 1; \
__UARTx__->IER_DLH.IER.ETBEI = 1;}while(0)
/* Tx empty interrupt and fifo disable */
#define __UART_INT_TXE_ENABLE_FD(__UARTx__) do{__UARTx__->IER_DLH.IER.PTIME = 0; \
__UARTx__->IER_DLH.IER.ETBEI = 1;}while(0)
#define __UART_INT_MODEM_DISABLE(__UARTx__) (__UARTx__->IER_DLH.IER.EDSSI = 0)
#define __UART_INT_LINE_STATUS_DISABLE(__UARTx__) (__UARTx__->IER_DLH.IER.ELSI = 0)
#define __UART_INT_RX_DISABLE(__UARTx__) (__UARTx__->IER_DLH.IER.ERBFI = 0)
#define __UART_INT_TXE_DISABLE(__UARTx__) do{__UARTx__->IER_DLH.IER.PTIME = 0; \
__UARTx__->IER_DLH.IER.ETBEI = 0;}while(0)
/* Get interrupt ID */
#define __UART_INT_GET_ID(__UARTx__) (__UARTx__->FCR_IID.IID & 0xF)
/* __UART_IrDA_ENABLE */
#define __UART_IrDA_ENABLE(__UARTx__) (__UARTx__->MCR.SIRE = 1)
#define __UART_IrDA_DISABLE(__UARTx__) (__UARTx__->MCR.SIRE = 0)
/* flow control config */
#define __UART_AUTO_FLOW_CONTROL_ENABLE(__UARTx__) do{__UARTx__->MCR.AFCE = 1; __UARTx__->MCR.RTS = 1;} while(0)
#define __UART_AUTO_FLOW_CONTROL_DISABLE(__UARTx__) (__UARTx__->MCR.AFCE = 0)
#define __UART_RTS_ACTIVE(__UARTx__) (__UARTx__->MCR.RTS = 1)
#define __UART_RTS_INACTIVE(__UARTx__) (__UARTx__->MCR.RTS = 0)
#define __UART_IS_CTS_ACTIVE(__UARTx__) (__UARTx__->MSR.CTS == 1)
/* __UART_DLL_DLH_ACCESS_ENABLE */
/* __UART_DLL_DLH_ACCESS_DISABLE */
#define __UART_DLL_DLH_ACCESS_ENABLE(__UARTx__) (__UARTx__->LCR.Bits.DLAB = 1)
#define __UART_DLL_DLH_ACCESS_DISABLE(__UARTx__) (__UARTx__->LCR.Bits.DLAB = 0)
/* __UART_GET_STATUS */
#define __UART_GET_STATUS(__UARTx__) (__UARTx__->LSR.LSR_DWORD)
/* Exported functions --------------------------------------------------------*/
/* uart_IRQHandler */
void uart_IRQHandler(UART_HandleTypeDef *huart);
/* uart_init */
void uart_init(UART_HandleTypeDef *huart);
/* uart_transmit */
/* uart_receive */
void uart_transmit(UART_HandleTypeDef *huart, uint8_t *fp_Data, uint32_t fu32_Size);
void uart_receive(UART_HandleTypeDef *huart, uint8_t *fp_Data, uint32_t fu32_Size);
/* uart_transmit_IT */
/* uart_receive_IT */
void uart_transmit_IT(UART_HandleTypeDef *huart, uint8_t *fp_Data, uint32_t fu32_Size);
void uart_receive_IT(UART_HandleTypeDef *huart, uint8_t *fp_Data, uint32_t fu32_Size);
/* uart_config_baudRate */
void uart_config_baudRate(UART_HandleTypeDef *huart);
#endif

View File

@ -0,0 +1,96 @@
/*
******************************************************************************
* @file driver_wdt.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2022
* @brief Header file of WDT HAL module.
******************************************************************************
* @attention
*
* Copyright (c) 2022 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_WDT_H__
#define __DRIVER_WDT_H__
#include "fr30xx.h"
/** @addtogroup WDT_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
/* WDT Control Register */
typedef struct
{
uint32_t WDT_EN : 1;
uint32_t RMOD : 1;
uint32_t RPL : 3;
uint32_t rsv_0 : 27;
}wdt_ctrl_t;
/* Timeout Range Register */
typedef struct
{
uint32_t TOP : 4;
uint32_t TOP_INIT : 4;
uint32_t rsv_0 : 24;
}wdt_timout_range_t;
typedef struct
{
volatile wdt_ctrl_t wdt_CR; /* Offset 0x00 */
volatile wdt_timout_range_t wdt_TORR; /* Offset 0x04 */
volatile uint32_t wdt_CCVR; /* Offset 0x08 */
volatile uint32_t wdt_CRR; /* Offset 0x0C */
volatile uint32_t wdt_STAT; /* Offset 0x10 */
volatile uint32_t wdt_EOI; /* Offset 0x14 */
volatile uint32_t rsv_0; /* Offset 0x18 */
volatile uint32_t rsv_1; /* Offset 0x1C */
volatile uint32_t wdt_CNT; /* Offset 0x20 */
}struct_WDT_t;
#define WDT ((struct_WDT_t *)(WDT_BASE))
/* ################################ Register Section END ################################## */
/**
* @}
*/
/** @addtogroup WDT_Initialization_Config_Section
* @{
*/
/* ################################ Initialization<6F><6E>Config Section Start ################################ */
typedef enum
{
WDT_MODE_0, /* Timeout reset system */
WDT_MODE_1, /* Timeout generate an interrupt,
if the interrupt is not cleared by the time a second timeout occurs, then it generates a system reset */
}enum_WDTMode_t;
/* ################################ Initialization<6F><6E>Config Section END ################################## */
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/* wdt_init */
void wdt_init(enum_WDTMode_t fe_mode, uint32_t fu32_WDTCount);
/* wdt_start */
/* wdt_stop */
void wdt_start(void);
void wdt_stop(void);
/* wdt_feed */
void wdt_feed(void);
#endif

View File

@ -0,0 +1,271 @@
/*
******************************************************************************
* @file driver_yuv2rgb.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2022
* @brief Header file of YUV2RGB HAL module.
******************************************************************************
* @attention
*
* Copyright (c) 2022 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __DRIVER_YUV2RGB_H__
#define __DRIVER_YUV2RGB_H__
#include "fr30xx.h"
/** @addtogroup YUV2RGB_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
/* YUV2RGB Config Register */
typedef struct
{
uint32_t YUV_MODE : 1;
uint32_t YUV_FORMAT : 1;
uint32_t RGB_FORMAT : 2;
uint32_t rsv_0 : 28;
}REG_YUV2RGB_CFG_t;
/* YUV FIFO control */
typedef struct
{
uint32_t YUV_FIFO_ALMOST_EMPTY_LEVEL : 5;
uint32_t rsv_0 : 3;
uint32_t YUV_FIFO_ALMOST_FULL_LEVEL : 5;
uint32_t rsv_1 : 19;
}REG_YUV_FIFO_CTRL_t;
/* RGB FIFO control */
typedef struct
{
uint32_t RGB_FIFO_ALMOST_EMPTY_LEVEL : 5;
uint32_t rsv_0 : 3;
uint32_t RGB_FIFO_ALMOST_FULL_LEVEL : 5;
uint32_t rsv_1 : 19;
}REG_RGB_FIFO_CTRL_t;
/* FIFO status control */
typedef struct
{
uint32_t rsv_0 : 8;
uint32_t YUV_FIFO_COUNT : 6;
uint32_t rsv_1 : 2;
uint32_t RGB_FIFO_COUNT : 6;
uint32_t rsv_2 : 10;
}REG_FIFO_STATUS_t;
/* DMA control */
typedef struct
{
uint32_t DMA_EN : 1;
uint32_t rsv_0 : 7;
uint32_t YUV_DMA_LEVEL : 5;
uint32_t rsv_1 : 3;
uint32_t RGB_DMA_LEVEL : 5;
uint32_t rsv_2 : 11;
}REG_DMA_CTRL_t;
/* DMA control */
typedef struct
{
uint32_t YUV_FLOW_LEVEL : 6;
uint32_t rsv_0 : 2;
uint32_t RGB_FLOW_LEVEL : 6;
uint32_t rsv_1 : 18;
}REG_FLOW_CTRL_t;
/* Result auto Incremen threshold control */
typedef struct
{
uint32_t RGB565_B_THR : 3;
uint32_t RGB565_G_THR : 2;
uint32_t RGB565_R_THR : 3;
uint32_t rsv_0 : 8;
uint32_t RGB322_B_THR : 6;
uint32_t RGB322_G_THR : 5;
uint32_t RGB322_R_THR : 5;
}REG_OPTIMIZE_CTRL_t;
/* ------------------------------------------------*/
/* YUV2RGB Register */
/* ------------------------------------------------*/
typedef struct
{
volatile uint32_t YUV2RGB_CTL; /* Offset 0x00 */
volatile REG_YUV2RGB_CFG_t YUV2RGB_CFG; /* Offset 0x04 */
volatile uint32_t YUV_DATA; /* Offset 0x08 */
volatile uint32_t RGB_DATA; /* Offset 0x0C */
volatile REG_YUV_FIFO_CTRL_t YUV_FIFO_CTRL; /* Offset 0x10 */
volatile REG_RGB_FIFO_CTRL_t RGB_FIFO_CTRL; /* Offset 0x14 */
volatile REG_FIFO_STATUS_t FIFO_STATUS; /* Offset 0x18 */
volatile uint32_t INT_CTRL; /* Offset 0x1C */
volatile uint32_t INT_STATUS; /* Offset 0x20 */
volatile uint32_t INT_RAW; /* Offset 0x24 */
volatile REG_DMA_CTRL_t DMA_CTRL; /* Offset 0x28 */
volatile REG_FLOW_CTRL_t FLOW_CTRL; /* Offset 0x2C */
volatile REG_OPTIMIZE_CTRL_t OPTIMIZE_CTRL; /* Offset 0x30 */
}struct_YUV2RGB_t;
#define YUV2RGB ((struct_YUV2RGB_t *)YUV2RGB_BASE)
/* ################################ Register Section END ################################## */
/**
* @}
*/
/** @addtogroup YUV2RGB_Initialization_Config_Section
* @{
*/
/* ################################ Initialization, Config Section Start ################################ */
/* YUV2RGB status index */
typedef enum
{
YUV_FIFO_EMPTY = 0x01, /*!< YUV FIFO empty */
YUV_FIFO_ALMOST_EMPTY = 0x02, /*!< YUV FIFO almost empty */
YUV_FIFO_FULL = 0x04, /*!< YUV FIFO full */
YUV_FIFO_ALMOST_FULL = 0x08, /*!< YUV FIFO almost full */
RGB_FIFO_EMPTY = 0x10, /*!< RGB FIFO empty */
RGB_FIFO_ALMOST_EMPTY = 0x20, /*!< RGB FIFO almost empty */
RGB_FIFO_FULL = 0x40, /*!< RGB FIFO full */
RGB_FIFO_ALMOST_FULL = 0x80, /*!< RGB FIFO almost full */
}enum_YUV2RGB_STATUS_t;
/* YUV2RGB calculate mode */
typedef enum
{
YUV2RGB_CALCULATE_MODE_A,
YUV2RGB_CALCULATE_MODE_B,
}enum_YUV2RGB_CALCULATE_MODE_t;
/* RGB FORMAT */
typedef enum
{
RGB_FORMAT_888,
RGB_FORMAT_565,
RGB_FORMAT_332,
}enum_RGB_FORMAT_t;
/* YUV FORMAT */
typedef enum
{
YUV_FORMAT_444,
YUV_FORMAT_422,
}enum_YUV_FORMAT_t;
/**
* @brief YUV2RGB Init Structure definition
*/
typedef struct
{
uint32_t YUV_Format; /*!< Specifies the number of YUV format.
This parameter can be a value of @ref enum_YUV_FORMAT_t. */
uint32_t RGB_Format; /*!< Specifies the number of RGB format.
This parameter can be a value of @ref enum_RGB_FORMAT_t. */
uint32_t YUV_CalculateMode; /*!< Specifies the number of YUV2RGB calculate mode.
This parameter can be a value of @ref enum_YUV2RGB_CALCULATE_MODE_t. */
}struct_YUV2RGBInit_t;
/**
* @brief YUV2RGB handle Structure definition
*/
typedef struct
{
struct_YUV2RGB_t *YUV2RGBx; /*!< YUV2RGB registers base address */
struct_YUV2RGBInit_t Init; /*!< YUV2RGB Init parameters */
union {
volatile void *p_data;
volatile uint16_t *p_u16;
volatile uint32_t *p_u32;
}u_YUVData;
union {
volatile void *p_data;
volatile uint8_t *p_u8;
volatile uint16_t *p_u16;
volatile uint32_t *p_u32;
}u_RGBData;
volatile bool b_CovertBusy;
volatile uint32_t u32_Pixels;
volatile uint32_t u32_RGBCount;
volatile uint32_t u32_YUVCount;
}YUV2RGB_HandleTypeDef;
/* ################################ Initialization, Config Section END ################################## */
/**
* @}
*/
/* Exported macro ------------------------------------------------------------*/
/* YUV2RGB enable */
#define __YUV2RGB_ENABLE(__YUV2RGB__) (__YUV2RGB__->YUV2RGB_CTL = 1)
#define __YUV2RGB_DISABLE(__YUV2RGB__) (__YUV2RGB__->YUV2RGB_CTL = 0)
/* YUV FIFO almost full threshold */
/* YUV FIFO almost empty threshold */
#define __YUV2RGB_YUV_FIFO_ALMOST_FULL_LEVEL(__YUV2RGB__, __LEVEL__) (__YUV2RGB__->YUV_FIFO_CTRL.YUV_FIFO_ALMOST_FULL_LEVEL = __LEVEL__)
#define __YUV2RGB_YUV_FIFO_ALMOST_EMPTY_LEVEL(__YUV2RGB__, __LEVEL__) (__YUV2RGB__->YUV_FIFO_CTRL.YUV_FIFO_ALMOST_EMPTY_LEVEL = __LEVEL__)
/* RGB FIFO almost full threshold */
/* RGB FIFO almost empty threshold */
#define __YUV2RGB_RGB_FIFO_ALMOST_FULL_LEVEL(__YUV2RGB__, __LEVEL__) (__YUV2RGB__->RGB_FIFO_CTRL.RGB_FIFO_ALMOST_FULL_LEVEL = __LEVEL__)
#define __YUV2RGB_RGB_FIFO_ALMOST_EMPTY_LEVEL(__YUV2RGB__, __LEVEL__) (__YUV2RGB__->RGB_FIFO_CTRL.RGB_FIFO_ALMOST_EMPTY_LEVEL = __LEVEL__)
/* Get RGB FIFO data count */
/* Get YUV FIFO data count */
#define __YUV2RGB_GET_RGB_FIFO_COUNT(__YUV2RGB__) (__YUV2RGB__->FIFO_STATUS.RGB_FIFO_COUNT)
#define __YUV2RGB_GET_YUV_FIFO_COUNT(__YUV2RGB__) (__YUV2RGB__->FIFO_STATUS.YUV_FIFO_COUNT)
/* YUV2RGB DMA enable */
#define __YUV2RGB_DMA_ENABLE(__YUV2RGB__) (__YUV2RGB__->DMA_CTRL.DMA_EN = 1)
#define __YUV2RGB_DMA_DISABLE(__YUV2RGB__) (__YUV2RGB__->DMA_CTRL.DMA_EN = 0)
#define __YUV2RGB_DMA_YUV_LEVEL(__YUV2RGB__, __LEVEL__) (__YUV2RGB__->DMA_CTRL.YUV_DMA_LEVEL = __LEVEL__)
#define __YUC2RGB_DMA_RGB_LEVEL(__YUV2RGB__, __LEVEL__) (__YUV2RGB__->DMA_CTRL.RGB_DMA_LEVEL = __LEVEL__)
/* YUV flow threshold */
/* RGB flow threshold */
#define __YUV2RGB_YUV_FLOW_LEVEL(__YUV2RGB__, __LEVEL__) (__YUV2RGB__->FLOW_CTRL.YUV_FLOW_LEVEL = __LEVEL__)
#define __YUV2RGB_RGB_FLOW_LEVEL(__YUV2RGB__, __LEVEL__) (__YUV2RGB__->FLOW_CTRL.RGB_FLOW_LEVEL = __LEVEL__)
/* RGB565 RGB optimize threshold */
/* RGB322 RGB optimize threshold */
#define __YUV2RGB_RGB322_R_OPTIMIZE_LEVEL(__YUV2RGB__, __LEVEL__) (__YUV2RGB__->OPTIMIZE_CTRL.RGB322_R_THR = __LEVEL__)
#define __YUV2RGB_RGB322_G_OPTIMIZE_LEVEL(__YUV2RGB__, __LEVEL__) (__YUV2RGB__->OPTIMIZE_CTRL.RGB322_G_THR = __LEVEL__)
#define __YUV2RGB_RGB322_B_OPTIMIZE_LEVEL(__YUV2RGB__, __LEVEL__) (__YUV2RGB__->OPTIMIZE_CTRL.RGB322_B_THR = __LEVEL__)
#define __YUV2RGB_RGB565_R_OPTIMIZE_LEVEL(__YUV2RGB__, __LEVEL__) (__YUV2RGB__->OPTIMIZE_CTRL.RGB565_R_THR = __LEVEL__)
#define __YUV2RGB_RGB565_G_OPTIMIZE_LEVEL(__YUV2RGB__, __LEVEL__) (__YUV2RGB__->OPTIMIZE_CTRL.RGB565_G_THR = __LEVEL__)
#define __YUV2RGB_RGB565_B_OPTIMIZE_LEVEL(__YUV2RGB__, __LEVEL__) (__YUV2RGB__->OPTIMIZE_CTRL.RGB565_B_THR = __LEVEL__)
/* YUV2RGB get interrupt raw status */
#define __YUV2RGB_GET_INT_RAW_STATUS(__YUV2RGB__) (__YUV2RGB__->INT_RAW)
/* YUV2RGB get interrupt status */
#define __YUV2RGB_GET_INT_STATUS(__YUV2RGB__) (__YUV2RGB__->INT_STATUS)
/* YUV2RGB set interrupt enable */
/* YUV2RGB set interrupt disable */
#define __YUV2RGB_INT_ENABLE(__YUV2RGB__, __INDEX__) (__YUV2RGB__->INT_CTRL |= (__INDEX__))
#define __YUV2RGB_INT_DISABLE(__YUV2RGB__, __INDEX__) (__YUV2RGB__->INT_CTRL &= ~(__INDEX__))
/* Exported functions --------------------------------------------------------*/
/* yuv2rgb_IRQHandler */
void yuv2rgb_IRQHandler(YUV2RGB_HandleTypeDef *hyuv2rgb);
/* yuv2rgb_init */
void yuv2rgb_init(YUV2RGB_HandleTypeDef *hyuv2rgb);
/* yuv2rgb_convert */
/* yuv2rgb_convert_IT */
void yuv2rgb_convert(YUV2RGB_HandleTypeDef *hyuv2rgb, void *YUV_Buffer, void *RGB_Buffer, uint32_t fu32_Pixels);
void yuv2rgb_convert_IT(YUV2RGB_HandleTypeDef *hyuv2rgb, void *YUV_Buffer, void *RGB_Buffer, uint32_t fu32_Pixels);
#endif

View File

@ -0,0 +1,110 @@
/*
******************************************************************************
* @file usb_audio.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief Header file for usb_audio.c file
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __USB_AUDIO_H__
#define __USB_AUDIO_H__
#include "stdint.h"
#include "stdbool.h"
#include "string.h"
#include "usb_core.h"
#include "usb_dev.h"
#define USB_AUDIO_VOLUME_MAX (0xAF)
#define USB_AUDIO_DATA_WIDTH_16BIT (16)
#define USB_AUDIO_DATA_WIDTH_24BIT (24)
/* Audio Class Specific Request Codes */
typedef enum
{
SET_CUR = 0x01,
GET_CUR = 0x81,
SET_MIN = 0x02,
GET_MIN = 0x82,
SET_MAX = 0x03,
GET_MAX = 0x83,
SET_RES = 0x04,
GET_RES = 0x84,
SET_MEM = 0x05,
GET_MEM = 0x85,
GET_STAT = 0xFF,
}Audio_Class_Specific_Request_Codes;
/* Feature Unit Control Selectors */
typedef enum
{
FU_CONTROL_UNDEFINED = 0x00,
MUTE_CONTROL = 0x01,
VOLUME_CONTROL = 0x02,
BASS_CONTROL = 0x03,
MID_CONTROL = 0x04,
TREBLE_CONTROL = 0x05,
GRAPHIC_EQUALIZER_CONTROL = 0x06,
AUTOMATIC_GAIN_CONTROL = 0x07,
DELAY_CONTROL = 0x08,
BASS_BOOST_CONTROL = 0x09,
LOUDNESS_CONTROL = 0x0A,
}Feature_Unit_Control_Selectors;
/* Endpoint Control Selectors */
typedef enum
{
EP_CONTROL_UNDEFINED = 0x00,
SAMPLING_FREQ_CONTROL = 0x01,
PITCH_CONTROL = 0x02,
}Endpoint_Control_Selectors;
/* Audio report */
typedef enum
{
AUDIO_REPORT_MUTE = 0x01,
AUDIO_REPORT_VOL_DEC = 0x02,
AUDIO_REPORT_VOL_INC = 0x04,
AUDIO_REPORT_PREVIOUS = 0x08,
AUDIO_REPORT_PLAY_PAUSE = 0x10,
AUDIO_REPORT_NEXT = 0x20,
AUDIO_REPORT_STOP = 0x40,
AUDIO_REPORT_RSV = 0x80,
}Audio_Report;
/* Exported Variate ----------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/* usb_audio_init */
void usb_audio_init(void);
/* usb_hid_set_Audio_report */
void usb_hid_set_Audio_report(uint8_t fu8_Value);
/* usb_hid_send_Audio_report */
int usb_hid_send_Audio_report(void);
/* get Speaker Packet Length/Data Bit Width */
/* get Mic Packet Length/Data Bit Width */
uint32_t usb_Audio_get_Speaker_Packet_Length(void);
uint32_t usb_Audio_get_Speaker_Bit_Width(void);
uint32_t usb_Audio_get_Mic_Packet_Length(void);
uint32_t usb_Audio_get_Mic_Bit_Width(void);
uint32_t usb_Audio_get_Speaker_Mute_status(void);
uint32_t usb_Audio_get_Mic_Mute_status(void);
uint32_t usb_Audio_get_Speaker_Volume(void);
uint32_t usb_Audio_get_Mic_Volume(void);
uint32_t usb_Audio_get_Speaker_SamplingFreq(void);
uint32_t usb_Audio_get_Mic_SamplingFreq(void);
#endif

View File

@ -0,0 +1,60 @@
/*
******************************************************************************
* @file usb_cdc.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief Header file for usb_cdc.c file
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __USB_CDC_H__
#define __USB_CDC_H__
#include "fr30xx.h"
/*---------------------------------------------------------------------*/
/* CDC definitions */
/*---------------------------------------------------------------------*/
#define CDC_SEND_ENCAPSULATED_COMMAND 0x00
#define CDC_GET_ENCAPSULATED_RESPONSE 0x01
#define CDC_SET_COMM_FEATURE 0x02
#define CDC_GET_COMM_FEATURE 0x03
#define CDC_CLEAR_COMM_FEATURE 0x04
#define CDC_SET_LINE_CODING 0x20
#define CDC_GET_LINE_CODING 0x21
#define CDC_SET_CONTROL_LINE_STATE 0x22
#define CDC_SEND_BREAK 0x23
/* CDC line coding */
typedef struct
{
uint32_t dwDTERate; // Baud rate
uint8_t bCharFormat; // Stop bits
/*
0: 1 Stop bit
1: 1.5 Stop bit
2: 2 Stop bit
*/
uint8_t bParityType; // Parity
/*
0: None
1: Odd
2: Even
3: Mark
4: Space
*/
uint8_t bDataBits; // Data bits
}USBD_CDC_LineCodingTypeDef;
/* usb_cdc_init */
void usb_cdc_init(void);
/* usb_cdc_serialReceive */
void usb_cdc_serialReceive(void);
#endif

View File

@ -0,0 +1,668 @@
/*
******************************************************************************
* @file usb_core.h
* @author FreqChip Firmware Team
* @version V1.1.0
* @date 2021
* @brief Header file for usb_core.c file
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __USB_CORE_H__
#define __USB_CORE_H__
#include "fr30xx.h"
/* Control Register for USB */
#define USB_OTG_CTRL_CID (0x800)
#define USB_OTG_CTRL_VBUS_CFG (0x700)
#define USB_OTG_CTRL_ADP (0x009)
#define USB_OTG_CTRL_DEVICE_CFG (USB_OTG_CTRL_CID | USB_OTG_CTRL_VBUS_CFG | USB_OTG_CTRL_ADP)
#define USB_OTG_CTRL_HOST_CFG (USB_OTG_CTRL_VBUS_CFG | USB_OTG_CTRL_ADP)
#define USB_OTG_CTRL_BASE (0xE00501DC)
#define USB_OTG_CTRL *(volatile uint32_t *)USB_OTG_CTRL_BASE
/** @addtogroup USB_Registers_Section
* @{
*/
/* ################################ Register bit define Start ################################ */
/* Power in device */
#define USB_POWER_RESUME (0x04)
#define USB_POWER_EN_SUSPEND (0x01)
/* Power in host */
#define USB_HOST_POWER_RESET (0x08)
#define USB_HOST_POWER_RESUME (0x04)
#define USB_HOST_POWER_SUSPEND (0x02)
/* usb signal interrupt */
#define USB_INT_STATUS_VBUS_ERROR (0x80)
#define USB_INT_STATUS_SESSREQ (0x40)
#define USB_INT_STATUS_DISCON (0x20)
#define USB_INT_STATUS_CONN (0x10)
#define USB_INT_STATUS_SOF (0x08)
#define USB_INT_STATUS_RESET (0x04)
#define USB_INT_STATUS_RESUME (0x02)
#define USB_INT_STATUS_SUSPEND (0x01)
/* CSR01 in device */
#define USB_CSR01_SVCSETUPEND (0x80)
#define USB_CSR01_SVCRXPKTRDY (0x40)
#define USB_CSR01_SENDSTALL (0x20)
#define USB_CSR01_SETUPEND (0x10)
#define USB_CSR01_DATAEND (0x08)
#define USB_CSR01_SENTSTALL (0x04)
#define USB_CSR01_TXPKTRDY (0x02)
#define USB_CSR01_RXPKTRDY (0x01)
/* CSR01 in host */
#define USB_HOST_CSR01_NAK_TIMEOUT (0x80)
#define USB_HOST_CSR01_STATUS_PKT (0x40)
#define USB_HOST_CSR01_REQ_PKT (0x20)
#define USB_HOST_CSR01_ERROR (0x10)
#define USB_HOST_CSR01_SETUP_PKT (0x08)
#define USB_HOST_CSR01_RXSTALL (0x04)
#define USB_HOST_CSR01_TXPKTRDY (0x02)
#define USB_HOST_CSR01_RXPKTRDY (0x01)
/* TXCSR1 in device */
#define USB_TXCSR1_CLRDATATOG (0x40)
#define USB_TXCSR1_SENTSTALL (0x20)
#define USB_TXCSR1_SENDSTALL (0x10)
#define USB_TXCSR1_FLUSHFIFO (0x08)
#define USB_TXCSR1_UNDERRUN (0x04)
#define USB_TXCSR1_FIFO_NOTEMPTY (0x02)
#define USB_TXCSR1_TXPKTRDY (0x01)
/* TXCSR1 in host */
#define USB_HOST_TXCSR1_NAK_TIMEOUT (0x80)
#define USB_HOST_TXCSR1_CLRDATATOG (0x40)
#define USB_HOST_TXCSR1_RXSTALL (0x20)
#define USB_HOST_TXCSR1_FLUSHFIFO (0x08)
#define USB_HOST_TXCSR1_ERROR (0x04)
#define USB_HOST_TXCSR1_FIFO_NOTEMPTY (0x02)
#define USB_HOST_TXCSR1_TXPKTRDY (0x01)
#define USB_TXCSR2_AUTO_SET (0x80)
#define USB_TXCSR2_ISO (0x40)
#define USB_TXCSR2_MODE (0x20)
#define USB_TXCSR2_DMA_ENABLE (0x10)
#define USB_TXCSR2_FRC_DATA_TOG (0x08)
#define USB_TXCSR2_DMA_MODE (0x04)
/* RXCSR1 in device */
#define USB_RXCSR1_CLRDATATOG (0x80)
#define USB_RXCSR1_SENTSTALL (0x40)
#define USB_RXCSR1_SENDSTALL (0x20)
#define USB_RXCSR1_FLUSHFIFO (0x10)
#define USB_RXCSR1_DATAERROR (0x08)
#define USB_RXCSR1_OVERRUN (0x04)
#define USB_RXCSR1_FIFO_FULL (0x02)
#define USB_RXCSR1_RXPKTRDY (0x01)
/* RXCSR1 in host */
#define USB_HOST_RXCSR1_CLRDATATOG (0x80)
#define USB_HOST_RXCSR1_RXSTALL (0x40)
#define USB_HOST_RXCSR1_REQPKT (0x20)
#define USB_HOST_RXCSR1_FLUSHFIFO (0x10)
#define USB_HOST_RXCSR1_NAK_TIMEOUT (0x08)
#define USB_HOST_RXCSR1_ERROR (0x04)
#define USB_HOST_RXCSR1_FIFO_FULL (0x02)
#define USB_HOST_RXCSR1_RXPKTRDY (0x01)
#define USB_RXCSR2_AUTO_CLEAR (0x80)
#define USB_RXCSR2_DEVICE_ISO (0x40)
#define USB_RXCSR2_HOST_AUTO_REQ (0x40)
#define USB_RXCSR2_DMA_ENABLE (0x20)
#define USB_RXCSR2_DMA_MODE (0x10)
#define USB_HOST_TXTYPE_PROTOCOL_POS (0x04)
#define USB_HOST_TXTYPE_PROTOCOL_MSK (0x30)
#define USB_HOST_TXTYPE_TARGET_ENDP_NUM_POS (0x00)
#define USB_HOST_TXTYPE_TARGET_ENDP_NUM_MSK (0x0F)
#define USB_HOST_RXTYPE_PROTOCOL_POS (0x04)
#define USB_HOST_RXTYPE_PROTOCOL_MSK (0x30)
#define USB_HOST_RXTYPE_TARGET_ENDP_NUM_POS (0x00)
#define USB_HOST_RXTYPE_TARGET_ENDP_NUM_MSK (0x0F)
/* ################################ Register bit define END ################################ */
/**
* @}
*/
typedef enum
{
ENDPOINT_0,
ENDPOINT_1,
ENDPOINT_2,
ENDPOINT_3,
ENDPOINT_4,
ENDPOINT_5,
ENDPOINT_6,
ENDPOINT_7,
}enum_Endpoint_t;
typedef enum
{
HOST_ENDP_TYPE_NONE,
HOST_ENDP_TYPE_ISO,
HOST_ENDP_TYPE_BULK,
HOST_ENDP_TYPE_INT,
}enum_HostEndpointType_t;
/** @addtogroup USB_Registers_Section
* @{
*/
/* ################################ Register Section Start ################################ */
/* -------------------------------------------*/
/* Common USB registers */
/* -------------------------------------------*/
typedef struct
{
volatile uint8_t FAddr; // offset 0x00
volatile uint8_t Power; // offset 0x01
volatile uint8_t IntrTx1; // offset 0x02
volatile uint8_t IntrTx2; // offset 0x03
volatile uint8_t IntrRx1; // offset 0x04
volatile uint8_t IntrRx2; // offset 0x05
volatile uint8_t IntrUSB; // offset 0x06
volatile uint8_t IntrTx1E; // offset 0x07
volatile uint8_t IntrTx2E; // offset 0x08
volatile uint8_t IntrRx1E; // offset 0x09
volatile uint8_t IntrRx2E; // offset 0x0A
volatile uint8_t IntrUSBE; // offset 0x0B
volatile uint8_t Frame1; // offset 0x0C
volatile uint8_t Frame2; // offset 0x0D
volatile uint8_t Index; // offset 0x0E
volatile uint8_t DevCtl; // offset 0x0F
}usb_common_t;
/* ------------------------------------------------*/
/* Control Status registers for endpoint0 */
/* ------------------------------------------------*/
typedef struct
{
volatile uint8_t rsv_0; // offset 0x10
volatile uint8_t CSR01; // offset 0x11
volatile uint8_t CSR02; // offset 0x12
volatile uint8_t rsv_1[3]; // offset 0x13 ~ 0x15
volatile uint8_t Count0; // offset 0x16
volatile uint8_t rsv_2[2]; // offset 0x17 ~ 0x18
volatile uint8_t NAKLimit0; // offset 0x19
volatile uint8_t rsv_3[6]; // offset 0x1A ~ 0x1F
volatile uint8_t FIFO; // offset 0x20
}usb_endpoint0_t;
/* -----------------------------------------------------*/
/* Control Status registers for endpoint1 ~ 10 */
/* -----------------------------------------------------*/
typedef struct
{
volatile uint8_t TxMaxP; // offset 0x10
volatile uint8_t TxCSR1; // offset 0x11
volatile uint8_t TxCSR2; // offset 0x12
volatile uint8_t RxMaxP; // offset 0x13
volatile uint8_t RxCSR1; // offset 0x14
volatile uint8_t RxCSR2; // offset 0x15
volatile uint8_t RxCount1; // offset 0x16
volatile uint8_t RxCount2; // offset 0x17
volatile uint8_t TxType; // offset 0x18 (Used in HostMode)
volatile uint8_t TxInterval; // offset 0x19 (Used in HostMode)
volatile uint8_t RxType; // offset 0x1A (Used in HostMode)
volatile uint8_t RxInterval; // offset 0x1B (Used in HostMode)
volatile uint8_t TxFIFO1; // offset 0x1C
volatile uint8_t TxFIFO2; // offset 0x1D
volatile uint8_t RxFIFO1; // offset 0x1E
volatile uint8_t RxFIFO2; // offset 0x1F
volatile uint8_t FIFO[44]; // offset 0x20
}usb_endpoints_t;
#define USB_OTG_ENDPOINT_BASE (0x10010010) /* USB_OTG_BASE + 0x10 */
#define USB ((volatile usb_common_t *)USB_OTG_BASE)
#define USB_POINT0 ((volatile usb_endpoint0_t *)USB_OTG_ENDPOINT_BASE)
#define USB_POINTS ((volatile usb_endpoints_t *)USB_OTG_ENDPOINT_BASE)
/* ################################ Register Section END ################################ */
/**
* @}
*/
/* Exported functions --------------------------------------------------------*/
/* usb_device_init */
void usb_device_init(void);
void usb_host_init(void);
/* usb_selecet_endpoint */
void usb_selecet_endpoint(enum_Endpoint_t Endpoint);
/* usb_get_endpoint */
uint8_t usb_get_endpoint(void);
/* usb_set_address */
void usb_set_address(uint8_t address);
/* usb_get_frame */
uint32_t usb_get_frame(void);
/* usb_RxSyncEndpoint_enable */
/* usb_TxSyncEndpoint_enable */
void usb_RxSyncEndpoint_enable(void);
void usb_TxSyncEndpoint_enable(void);
/* usb_SingleInt_Enable */
/* usb_SingleInt_Disable */
void usb_SingleInt_Enable(uint8_t fu8_Signal);
void usb_SingleInt_Disable(uint8_t fu8_Signal);
/* usb_TxInt_Enable/usb_TxInt_Disable */
/* usb_RxInt_Enable/usb_RxInt_Disable */
void usb_TxInt_Enable(enum_Endpoint_t Endpoint);
void usb_TxInt_Disable(enum_Endpoint_t Endpoint);
void usb_RxInt_Enable(enum_Endpoint_t Endpoint);
void usb_RxInt_Disable(enum_Endpoint_t Endpoint);
/* usb_endpoint_Txfifo_config */
/* usb_endpoint_Rxfifo_config */
void usb_endpoint_Txfifo_config(uint32_t StartAddress, uint32_t MaxPacket);
void usb_endpoint_Rxfifo_config(uint32_t StartAddress, uint32_t MaxPacket);
/* usb_TxMaxP_set */
/* usb_RxMaxP_set */
void usb_TxMaxP_set(uint32_t MaxPacket);
void usb_RxMaxP_set(uint32_t MaxPacket);
/* usb_Host_TxEndpointType */
/* usb_Host_RxEndpointType */
void usb_Host_TxEndpointType(enum_HostEndpointType_t fe_Type);
void usb_Host_RxEndpointType(enum_HostEndpointType_t fe_Type);
/* usb_Host_TxTargetEndpoint */
/* usb_Host_RxTargetEndpoint */
void usb_Host_TxTargetEndpoint(uint8_t fu8_TargetEndpointNum);
void usb_Host_RxTargetEndpoint(uint8_t fu8_TargetEndpointNum);
/* usb_Host_TxPollingInterval */
/* usb_Host_RxPollingInterval */
/* usb_Host_TxNAKLimit */
/* usb_Host_RxNAKLimit */
void usb_Host_TxPollingInterval(uint8_t fu8_TxInterval);
void usb_Host_TxNAKLimit(uint8_t fu8_TxNAKLimit);
void usb_Host_RxPollingInterval(uint8_t fu8_RxInterval);
void usb_Host_RxNAKLimit(uint8_t fu8_RxNAKLimit);
/* usb_write_fifo */
/* usb_read_fifo */
void usb_write_fifo(enum_Endpoint_t Endpoint, uint8_t *Buffer, uint32_t Size);
void usb_read_fifo(enum_Endpoint_t Endpoint, uint8_t *Buffer, uint32_t Size);
/* Exported inline functions --------------------------------------------------------*/
/* usb_get_USBStatus */
static inline uint8_t usb_get_USBStatus(void)
{
return USB->IntrUSB;
}
/* usb_get_TxStatus */
/* usb_get_RxStatus */
static inline uint8_t usb_get_TxStatus(void)
{
return USB->IntrTx1;
}
static inline uint8_t usb_get_RxStatus(void)
{
return USB->IntrRx1;
}
/* ------------------------------------ */
/* ---------- Pwoer function ---------- */
/* ------------------------------------ */
/* ---------- Device ---------- */
static inline void usb_ResumeSignalStart(void)
{
/* Device generate Resume signaling on the bus. */
USB->Power |= USB_POWER_RESUME;
}
static inline void usb_ResumeSignalStop(void)
{
USB->Power &= ~USB_POWER_RESUME;
}
static inline void usb_SuspendDetectEn(void)
{
/* Device Detec Suspend signal on the bus. */
USB->Power |= USB_POWER_EN_SUSPEND;
}
/* ---------- Host ---------- */
/* usb_Host_ResetSignalStart */
/* usb_Host_ResetSignalStop */
/* usb_Host_ResumeSignalStart */
/* usb_Host_ResumeSignalStop */
/* usb_Host_EntrySuspendMode */
/* usb_Host_ExitSuspendMode */
static inline void usb_Host_ResetSignalStart(void)
{
/* Host generate Reset signaling on the bus. */
USB->Power |= USB_HOST_POWER_RESET;
}
static inline void usb_Host_ResetSignalStop(void)
{
USB->Power &= ~USB_HOST_POWER_RESET;
}
static inline void usb_Host_ResumeSignalStart(void)
{
/* Host generate Resume signaling on the bus. */
USB->Power |= USB_HOST_POWER_RESUME;
}
static inline void usb_Host_ResumeSignalStop(void)
{
USB->Power &= ~USB_HOST_POWER_RESUME;
}
static inline void usb_Host_EntrySuspendMode(void)
{
USB->Power |= USB_HOST_POWER_SUSPEND;
}
static inline void usb_Host_ExitSuspendMode(void)
{
USB->Power &= ~USB_HOST_POWER_SUSPEND;
}
/* ---------------------------------------- */
/* ---------- Endpoint0 function ---------- */
/* ---------------------------------------- */
/* usb_get_Endpoint0_RxCount */
/* usb_get_Endpoint0_FlushFIFO */
static inline uint8_t usb_Endpoint0_get_RxCount(void)
{
return USB_POINT0->Count0;
}
static inline void usb_Endpoint0_FlushFIFO(void)
{
USB_POINT0->CSR02 = 1;
}
/* ---------- Device ---------- */
/* usb_Endpoint0_SendStall */
/* usb_Endpoint0_DataEnd */
/* usb_Endpoint0_SET_TxPktRdy */
/* usb_Endpoint0_GET_TxPktRdy */
/* usb_Endpoint0_GET_RxPktRdy */
static inline void usb_Endpoint0_SendStall(void)
{
USB_POINT0->CSR01 |= USB_CSR01_SENDSTALL;
}
static inline void usb_Endpoint0_DataEnd(void)
{
USB_POINT0->CSR01 |= USB_CSR01_DATAEND;
}
static inline void usb_Endpoint0_SET_TxPktRdy(void)
{
USB_POINT0->CSR01 |= USB_CSR01_TXPKTRDY;
}
static inline bool usb_Endpoint0_GET_TxPktRdy(void)
{
return (USB_POINT0->CSR01 & USB_CSR01_TXPKTRDY) ? true : false;
}
static inline bool usb_Endpoint0_GET_RxPktRdy(void)
{
return (USB_POINT0->CSR01 & USB_CSR01_RXPKTRDY) ? true : false;
}
/* ---------- Host ---------- */
/* usb_Host_Endpoint0_SET_ReqPkt */
/* usb_Host_Endpoint0_SET_ReqPkt_StatusPkt */
/* usb_Host_Endpoint0_SET_TxPktRdy */
/* usb_Host_Endpoint0_SET_TxPktRdy_StatusPkt */
/* usb_Host_Endpoint0_SET_TxPktRdy_SetupPkt */
/* usb_Host_Endpoint0_Clr_SetupPkt */
/* usb_Host_Endpoint0_Clr_StatusPkt */
/* usb_Host_Endpoint0_Clr_ReqPkt */
/* usb_Host_Endpoint0_GET_TxPktRdy */
/* usb_Host_Endpoint0_GET_RxPktRdy */
/* usb_Host_Endpoint0_GET_NAKtimeout */
/* usb_Host_Endpoint0_Clr_NAKtimeout */
/* usb_Host_Endpoint0_GET_ERROR */
/* usb_Host_Endpoint0_NAKlimit */
static inline void usb_Host_Endpoint0_SET_ReqPkt(void)
{
USB_POINT0->CSR01 |= USB_HOST_CSR01_REQ_PKT;
}
static inline void usb_Host_Endpoint0_SET_ReqPkt_StatusPkt(void)
{
USB_POINT0->CSR01 |= (USB_HOST_CSR01_REQ_PKT | USB_HOST_CSR01_STATUS_PKT);
}
static inline void usb_Host_Endpoint0_SET_TxPktRdy(void)
{
USB_POINT0->CSR01 |= USB_HOST_CSR01_TXPKTRDY;
}
static inline void usb_Host_Endpoint0_SET_TxPktRdy_SetupPkt(void)
{
USB_POINT0->CSR01 |= (USB_HOST_CSR01_TXPKTRDY | USB_HOST_CSR01_SETUP_PKT);
}
static inline void usb_Host_Endpoint0_SET_TxPktRdy_StatusPkt(void)
{
USB_POINT0->CSR01 |= (USB_HOST_CSR01_TXPKTRDY | USB_HOST_CSR01_STATUS_PKT);
}
static inline void usb_Host_Endpoint0_Clr_SetupPkt(void)
{
USB_POINT0->CSR01 &= ~USB_HOST_CSR01_SETUP_PKT;
}
static inline void usb_Host_Endpoint0_Clr_StatusPkt(void)
{
USB_POINT0->CSR01 &= ~USB_HOST_CSR01_STATUS_PKT;
}
static inline void usb_Host_Endpoint0_Clr_ReqPkt(void)
{
USB_POINT0->CSR01 &= ~USB_HOST_CSR01_REQ_PKT;
}
static inline bool usb_Host_Endpoint0_GET_TxPktRdy(void)
{
return (USB_POINT0->CSR01 & USB_HOST_CSR01_TXPKTRDY) ? true : false;
}
static inline bool usb_Host_Endpoint0_GET_RxPktRdy(void)
{
return (USB_POINT0->CSR01 & USB_HOST_CSR01_RXPKTRDY) ? true : false;
}
static inline bool usb_Host_Endpoint0_GET_NAKtimeout(void)
{
return (USB_POINT0->CSR01 & USB_HOST_CSR01_NAK_TIMEOUT) ? true : false;
}
static inline void usb_Host_Endpoint0_Clr_NAKtimeout(void)
{
USB_POINT0->CSR01 &= ~USB_HOST_CSR01_NAK_TIMEOUT;
}
static inline bool usb_Host_Endpoint0_GET_ERROR(void)
{
return (USB_POINT0->CSR01 & USB_HOST_CSR01_ERROR) ? true : false;
}
static inline void usb_Host_Endpoint0_Clr_ERROR(void)
{
USB_POINT0->CSR01 &= ~USB_HOST_CSR01_ERROR;
}
static inline void usb_Host_Endpoint0_NAKlimit(uint8_t fu8_NAKlimit)
{
USB_POINT0->NAKLimit0 = fu8_NAKlimit;
}
/* ---------------------------------------- */
/* ------- other Endpoints function ------- */
/* ---------------------------------------- */
/* usb_Endpoints_get_RxCount */
static inline uint8_t usb_Endpoints_get_RxCount(void)
{
return USB_POINTS->RxCount1;
}
/* usb_Endpoints_get_RxCount_16bit */
static inline uint16_t usb_Endpoints_get_RxCount_16bit(void)
{
return (uint16_t)USB_POINTS->RxCount2 << 8 | (uint16_t)USB_POINTS->RxCount1;
}
/* ---------- Device ---------- */
/* usb_Endpoints_GET_RxPktRdy */
/* usb_Endpoints_SET_TxPktRdy */
/* usb_Endpoints_GET_TxPktRdy */
/* usb_Endpoints_FlushRxFIFO */
/* usb_Endpoints_FlushTxFIFO */
static inline bool usb_Endpoints_GET_RxPktRdy(void)
{
return (USB_POINTS->RxCSR1 & USB_RXCSR1_RXPKTRDY) ? true : false;
}
static inline void usb_Endpoints_SET_TxPktRdy(void)
{
USB_POINTS->TxCSR1 |= USB_TXCSR1_TXPKTRDY;
}
static inline bool usb_Endpoints_GET_TxPktRdy(void)
{
return (USB_POINTS->TxCSR1 & USB_TXCSR1_TXPKTRDY) ? true : false;
}
static inline void usb_Endpoints_FlushRxFIFO(void)
{
USB_POINTS->RxCSR1 |= USB_RXCSR1_FLUSHFIFO;
}
static inline void usb_Endpoints_FlushTxFIFO(void)
{
USB_POINTS->TxCSR1 |= USB_TXCSR1_FLUSHFIFO;
}
/* ---------- Host ---------- */
/* usb_Host_Endpoints_SET_RxReqPkt */
/* usb_Host_Endpoints_Clr_RxReqPkt */
/* usb_Host_Endpoints_GET_RxPktRdy */
/* usb_Host_Endpoints_SET_TxPktRdy */
/* usb_Host_Endpoints_GET_TxPktRdy */
/* usb_Host_Endpoints_FlushRxFIFO */
/* usb_Host_Endpoints_FlushTxFIFO */
/* usb_Host_Endpoints_GET_Tx_NAKtimeout */
/* usb_Host_Endpoints_Clr_Tx_NAKtimeout */
/* usb_Host_Endpoints_GET_Tx_STALL */
/* usb_Host_Endpoints_Clr_Tx_STALL */
/* usb_Host_Endpoints_GET_Tx_ERROR */
/* usb_Host_Endpoints_Clr_Tx_ERROR */
/* usb_Host_Endpoints_GET_Rx_NAKtimeout */
/* usb_Host_Endpoints_Clr_Rx_NAKtimeout */
/* usb_Host_Endpoints_GET_Rx_STALL */
/* usb_Host_Endpoints_Clr_Rx_STALL */
/* usb_Host_Endpoints_GET_Rx_ERROR */
/* usb_Host_Endpoints_Clr_Rx_ERROR */
static inline void usb_Host_Endpoints_SET_RxReqPkt(void)
{
USB_POINTS->RxCSR1 |= USB_HOST_RXCSR1_REQPKT;
}
static inline void usb_Host_Endpoints_Clr_RxReqPkt(void)
{
USB_POINTS->RxCSR1 &= ~USB_HOST_RXCSR1_REQPKT;
}
static inline bool usb_Host_Endpoints_GET_RxPktRdy(void)
{
return (USB_POINTS->RxCSR1 & USB_HOST_RXCSR1_RXPKTRDY) ? true : false;
}
static inline void usb_Host_Endpoints_SET_TxPktRdy(void)
{
USB_POINTS->TxCSR1 |= USB_HOST_TXCSR1_TXPKTRDY;
}
static inline bool usb_Host_Endpoints_GET_TxPktRdy(void)
{
return (USB_POINTS->TxCSR1 & USB_HOST_TXCSR1_TXPKTRDY) ? true : false;
}
static inline void usb_Host_Endpoints_FlushRxFIFO(void)
{
USB_POINTS->RxCSR1 |= USB_HOST_RXCSR1_FLUSHFIFO;
}
static inline void usb_Host_Endpoints_FlushTxFIFO(void)
{
USB_POINTS->TxCSR1 |= USB_HOST_TXCSR1_FLUSHFIFO;
}
static inline bool usb_Host_Endpoints_GET_Tx_NAKtimeout(void)
{
return (USB_POINTS->TxCSR1 & USB_HOST_TXCSR1_NAK_TIMEOUT) ? true : false;
}
static inline void usb_Host_Endpoints_Clr_Tx_NAKtimeout(void)
{
USB_POINTS->TxCSR1 &= ~USB_HOST_TXCSR1_NAK_TIMEOUT;
}
static inline bool usb_Host_Endpoints_GET_Tx_STALL(void)
{
return (USB_POINTS->TxCSR1 & USB_HOST_TXCSR1_RXSTALL) ? true : false;
}
static inline void usb_Host_Endpoints_Clr_Tx_STALL(void)
{
USB_POINTS->TxCSR1 &= ~USB_HOST_TXCSR1_RXSTALL;
}
static inline bool usb_Host_Endpoints_GET_Tx_ERROR(void)
{
return (USB_POINTS->TxCSR1 & USB_HOST_TXCSR1_ERROR) ? true : false;
}
static inline void usb_Host_Endpoints_Clr_Tx_ERROR(void)
{
USB_POINTS->TxCSR1 &= ~USB_HOST_TXCSR1_ERROR;
}
static inline bool usb_Host_Endpoints_GET_Rx_NAKtimeout(void)
{
return (USB_POINTS->RxCSR1 & USB_HOST_RXCSR1_NAK_TIMEOUT) ? true : false;
}
static inline void usb_Host_Endpoints_Clr_Rx_NAKtimeout(void)
{
USB_POINTS->RxCSR1 &= ~USB_HOST_RXCSR1_NAK_TIMEOUT;
}
static inline bool usb_Host_Endpoints_GET_Rx_STALL(void)
{
return (USB_POINTS->RxCSR1 & USB_HOST_RXCSR1_RXSTALL) ? true : false;
}
static inline void usb_Host_Endpoints_Clr_Rx_STALL(void)
{
USB_POINTS->RxCSR1 &= ~USB_HOST_RXCSR1_RXSTALL;
}
static inline bool usb_Host_Endpoints_GET_Rx_ERROR(void)
{
return (USB_POINTS->RxCSR1 & USB_HOST_RXCSR1_ERROR) ? true : false;
}
static inline void usb_Host_Endpoints_Clr_Rx_ERROR(void)
{
USB_POINTS->RxCSR1 &= ~USB_HOST_RXCSR1_ERROR;
}
#endif

View File

@ -0,0 +1,186 @@
/*
******************************************************************************
* @file usb_dev.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief Header file for usb_dev.c file
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __USB_DEV_H__
#define __USB_DEV_H__
#include "stdint.h"
#include "stdbool.h"
#include "string.h"
#include "usb_core.h"
#define ENDPOINT0_MAX (64)
#define ENDPOINT_0_MASK (0x01)
#define ENDPOINT_1_MASK (0x02)
#define ENDPOINT_2_MASK (0x04)
#define ENDPOINT_3_MASK (0x08)
#define ENDPOINT_4_MASK (0x10)
#define ENDPOINT_5_MASK (0x20)
#define ENDPOINT_6_MASK (0x40)
#define ENDPOINT_7_MASK (0x80)
/* Build the returned data */
typedef struct
{
uint16_t RequestLength;
uint8_t *DataBuffer;
uint32_t DataLength;
}usb_ReturnData_t;
#define HID_MAX_REPORT_NUM (10)
/* USB Device descriptors structure */
typedef struct
{
uint8_t *DeviceDescriptor;
uint8_t *ConfigurationDescriptor;
uint8_t *InterfaceStrDescriptor;
uint8_t *EndpointDescriptor;
uint8_t *stringManufacture;
uint8_t *stringProduct;
uint8_t *stringSerialNumber;
uint8_t *stringLanuageID;
uint8_t *stringOS; // Extended Compat ID OS Feature Descriptor
}usb_DescriptorsTypeDef_t;
/* USB Device standard request */
typedef struct
{
uint8_t bmRequestType; // Characteristics of request
/*
D7: Data transfer direction
0 : Host-to-device
1 : Device-to-host
D6...5: Type
0 : Standard
1 : Class
2 : Vendor
3 : Reserved
D4...0: Recipient
0 : Device
1 : Interface
2 : Endpoint
3 : Other
4 ~ 31 : Reserved
*/
uint8_t bRequest; // Specific request
uint8_t wValue[2]; // Word-sized field that varies according to request
uint8_t wIndex[2]; // Word-sized field that varies according to request
uint8_t wLength[2]; // Number of bytes to transfer if there is a Data stage
}usb_StandardRequest_t;
/* bmRequestType bit mask */
#define REQUEST_DIRECTION_MASK (0x80)
#define REQUEST_TYPE_MASK (0x60)
#define REQUEST_RECIPIENT_MASK (0x0F)
/* direction define */
#define DIRECTION_IN (0x80)
#define DIRECTION_OUT (0x00)
/* Type define */
#define TYPE_STANDARD (0x00)
#define TYPE_CLASS (0x20)
#define TYPE_VENDOR (0x40)
/* Recipient define */
#define RECIPIENT_DEVICE (0x00)
#define RECIPIENT_INTERFACE (0x01)
#define RECIPIENT_ENDPOINT (0x02)
/* standard request code */
#define REQUEST_GET_STATUS (0)
#define REQUEST_CLEAR_FEATURE (1)
#define REQUEST_SET_FEATURE (3)
#define REQUEST_SET_ADDRESS (5)
#define REQUEST_GET_DESCRIPTOR (6)
#define REQUEST_SET_DESCRIPTOR (7)
#define REQUEST_GET_CONFIGURATION (8)
#define REQUEST_SET_CONFIGURATION (9)
#define REQUEST_GET_INTERFACE (10)
#define REQUEST_SET_INTERFACE (11)
#define REQUEST_SYNCH_FRAME (12)
/* USB2.0 Descriptor type and number */
#define DESCRIPTOR_DEVICE (1)
#define DESCRIPTOR_CONFIGURATION (2)
#define DESCRIPTOR_STRING (3)
#define DESCRIPTOR_INTERFACE (4)
#define DESCRIPTOR_ENPOINT (5)
#define DESCRIPTOR_DEVICE_QUALIFIER (6)
#define DESCRIPTOR_OTHER_SPEED_CONFIGURATION (7)
#define DESCRIPTOR_INTERFACE_POWER (8)
/* HID class standard descriptor */
#define DESCRIPTOR_HID (33) /* 0x21 */
#define DESCRIPTOR_HID_REPORT (34) /* 0x22 */
#define DESCRIPTOR_HID_PHYSICAL (35) /* 0x23 */
/* USB3.2 Descriptor type and number */
#define DESCRIPTOR_OTG (9)
#define DESCRIPTOR_DEBUG (10)
#define DESCRIPTOR_INTERFACE_ASSOCIATION (11)
#define DESCRIPTOR_BOS (15)
#define DESCRIPTOR_DEVICE_CAPABILITY (16)
#define DESCRIPTOR_SUPERSPEED_USB_ENDPOINT_COMPANION (48)
#define DESCRIPTOR_SUPERSPEEDPLUS_ISOCHRONOUS_ENDPOINT_COMPANION (49)
/* string index */
#define STRING_MANUFACTURE (1)
#define STRING_PRODUCT (2)
#define STRING_SERIAL_Number (3)
#define STRING_LANUAGE_ID (0)
#define STRING_OS (0xEE)
/* Exported Variate ----------------------------------------------------------*/
extern void (*Endpoint_0_StandardClassRequest_Handler)(usb_StandardRequest_t* pStandardRequest, usb_ReturnData_t* pReturnData);
extern void (*Endpoint_0_ClassRequest_Handler)(usb_StandardRequest_t* pStandardRequest, usb_ReturnData_t* pReturnData);
extern void (*Endpoint_0_VendorRequest_Handler)(usb_StandardRequest_t* pStandardRequest, usb_ReturnData_t* pReturnData);
extern void (*Endpoint_0_DataOut_Handler)(void);
extern void (*Endpoints_Handler)(uint8_t RxStatus, uint8_t TxStatus);
extern void (*USB_SOF_Handler)(void);
extern void (*USB_Reset_Handler)(void);
extern void (*USB_Resume_Handler)(void);
extern void (*USB_Suspend_Handler)(void);
extern void (*USB_Connect_Handler)(void);
extern void (*USB_InterfaceAlternateSet_callback)(uint8_t Interface);
/* Exported functions --------------------------------------------------------*/
/* usbdev_get_dev_desc */
void usbdev_get_dev_desc(uint8_t *Descriptor);
/* usbdev_get_config_desc */
void usbdev_get_config_desc(uint8_t *Descriptor);
/* string Descriptor */
void usbdev_get_string_Manufacture(uint8_t *Descriptor);
void usbdev_get_string_Product(uint8_t *Descriptor);
void usbdev_get_string_SerialNumber(uint8_t *Descriptor);
void usbdev_get_string_LanuageID(uint8_t *Descriptor);
void usbdev_get_string_OS(uint8_t *Descriptor);
uint16_t usbdev_get_device_status(void);
uint16_t usbdev_get_in_endpoints_status(uint32_t index);
uint16_t usbdev_get_out_endpoints_status(uint32_t index);
uint8_t usbdev_get_device_configuration_num(void);
uint8_t usbdev_get_interface_alternate_num(uint32_t index);
#endif

View File

@ -0,0 +1,65 @@
/*
******************************************************************************
* @file usb_hid.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief Header file for usb_hid.c file
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __USB_HID_H__
#define __USB_HID_H__
#include "stdint.h"
#include "stdbool.h"
#include "string.h"
#include "usb_core.h"
#include "usb_dev.h"
#define KEY_LEFT_CONTROL (0x1001)
#define KEY_LEFT_SHIFT (0x1002)
#define KEY_LEFT_ALT (0x1004)
#define KEY_LEFT_GUI (0x1008)
#define KEY_RIGHT_CONTROL (0x1010)
#define KEY_RIGHT_SHIFT (0x1020)
#define KEY_RIGHT_ALT (0x1040)
#define KEY_RIGHT_GUI (0x1080)
/*------------------------------------------------------------------*/
/* HID Class-Specific Requests */
/*------------------------------------------------------------------*/
#define HID_GET_REPORT (0x01)
#define HID_GET_IDLE (0x02)
#define HID_GET_PROTOCOL (0x03)
#define HID_SET_REPORT (0x09)
#define HID_SET_IDLE (0x0A)
#define HID_SET_PROTOCOL (0x0B)
/* Exported inline functions --------------------------------------------------------*/
/* usb_hid_set_mouse_report */
void usb_hid_set_mouse_report(uint8_t fu8_Index, uint8_t fu8_Value);
/* usb_hid_set_keyboard_report */
void usb_hid_set_keyboard_report(uint16_t fu16_Key);
/* usb_hid_clear_keyboard_report */
void usb_hid_clear_keyboard_report(uint16_t fu16_Key);
/* usb_hid_send_mouse_report */
void usb_hid_send_mouse_report(void);
/* usb_hid_send_keyboard_report */
void usb_hid_send_keyboard_report(void);
/* usb_hid_init */
void usb_hid_init(void);
#endif

View File

@ -0,0 +1,78 @@
/*
******************************************************************************
* @file usb_mass_storage.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief Header file for usb_mass_storage.c file
******************************************************************************
* @attention
*
* Copyright (c) 2023 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __USB_MASS_STORAGE_H__
#define __USB_MASS_STORAGE_H__
#include "fr30xx.h"
/* mass storage device max lun */
#define FREQCHIP_MASS_STORAGE_MAX_LUN (1)
/* Bulk Only Transport Calss Request descriptor */
#define BULK_ONLY_MASS_STORAGE_RESET (0xFF)
#define GET_MAX_LUN (0xFE)
#define CBW_SIGNATURE (0x43425355)
#define CSW_SIGNATURE (0x53425355)
/* UFI SCSI Command */
#define SCSI_CMD_FormatUnit (0x04)
#define SCSI_CMD_Inquiry (0x12)
#define SCSI_CMD_ModeSENSE6 (0x1A)
#define SCSI_CMD_Start_Stop (0x1B)
#define SCSI_CMD_ModeSelect (0x55)
#define SCSI_CMD_ModeSense (0x5A)
#define SCSI_CMD_Prevent (0x1E)
#define SCSI_CMD_Read10 (0x28)
#define SCSI_CMD_Read12 (0xA8)
#define SCSI_CMD_ReadCapacity (0x25)
#define SCSI_CMD_ReadForamtCapacity (0x23)
#define SCSI_CMD_RequestSense (0x03)
#define SCSI_CMD_RexeroUnit (0x01)
#define SCSI_CMD_Seek (0x2B)
#define SCSI_CMD_SendDianostic (0x1D)
#define SCSI_CMD_TestUnitReady (0x00)
#define SCSI_CMD_Verify (0x2F)
#define SCSI_CMD_Write10 (0x2A)
#define SCSI_CMD_Write12 (0xAA)
#define SCSI_CMD_WriteAndVerify (0x2E)
/* CBW (Command Block Wrapper) */
typedef struct
{
uint32_t dCBWSignature; // 0x43425355
uint32_t dCBWTag;
uint32_t dCBWDataTransferLength;
uint8_t bmCBWFlags;
uint8_t bCBWLUN;
uint8_t bCBWCBLength;
uint8_t CBWCB[16];
}usb_CBW_t;
/* CSW (Command Status Wrapper) */
typedef struct
{
uint32_t dCSWSignature; // 0x53425355
uint32_t dCSWTag;
uint32_t dCSWDataResidue;
uint8_t bmCSWStatus;
}usb_CSW_t;
/* Exported inline functions --------------------------------------------------------*/
/* usb_mass_storage_init */
void usb_mass_storage_init(void);
#endif

View File

@ -0,0 +1,38 @@
/*
******************************************************************************
* @file usb_winusb.h
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief Header file for usb_hid.c file
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#ifndef __USB_WINUSB_H__
#define __USB_WINUSB_H__
#include "stdint.h"
#include "stdbool.h"
#include "string.h"
#include "usb_core.h"
#include "usb_dev.h"
/* WinUSB Descriptor type and number */
#define GET_MS_DESCRIPTOR (1)
/* Request OS OS feature descriptor */
#define EXTENDED_COMPAT_ID (0x04)
#define EXTENDED_PROPERTIES (0x05)
/* Exported inline functions --------------------------------------------------------*/
/* usb_winusb_init */
void usb_winusb_init(void);
#endif

View File

@ -0,0 +1,155 @@
/*
******************************************************************************
* @file driver_adc.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief ADC module driver.
* This file provides firmware functions to manage the
* Analog to Digital Converter (ADC) peripheral
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
/******************************************************************************
* @fn adc_init
*
* @brief Initialize the ADC according to the specified parameters
* in the adc_InitConfig_t
*
* @param InitParam : adc_InitConfig_t structure that contains the
* configuration information for ADC module.
*/
void adc_init(adc_InitConfig_t InitConfig)
{
/* ADC reset */
__ADC_RESET();
/* analog config */
if (InitConfig.ADC_Reference == ADC_REF_1P2V)
ADC->ACT0 = ADC_ACT0_REF_1P2V;
else
ADC->ACT0 = ADC_ACT0_REF_IOLDO;
ADC->ACT1 = ADC_ACT1_VBE_EN | ADC_ACT1_VBAT_EN | ADC_ACT1_IS;
/* Timing config */
__ADC_SET_CLK_DIV(2); /*!< ADC clock = 24Mhz / ((ADC_CLK_DIV + 1) * 2). Fixed 2 */
__ADC_SET_SETUP_CYCLE(60); /*!< Convert setup cycle. Fixed 60 */
__ADC_SET_SAMPLE_CYCLE(30); /*!< Convert sample cycle. Fixed 30 */
__ADC_SET_TIMEOUT_CYCLE(0x1F); /*!< Convert timeoout cycle. Fixed 31 */
/* Init default channel maping */
for (int i = 0; i < ADC_MAX_IO_INPUT_MAP; i++)
{
__ADC_SET_CHANNEL_MAP(i, i);
}
/* Hrad trigger mode */
if (InitConfig.ADC_TriggerMode == ADC_HARDWARE_TRIGGER)
{
__ADC_SET_TRIGGER_MODE(ADC_HARDWARE_TRIGGER);
/* set Max channel */
__ADC_SET_MAX_CHANNEL(InitConfig.HardTriggerConfig.ADC_Channel_Max - 1);
/* set convert mode */
__ADC_SET_CONVERT_MODE(InitConfig.HardTriggerConfig.ADC_Convert_Mode);
}
/* Soft trigger mode */
else
{
__ADC_SET_TRIGGER_MODE(ADC_SOFTWARE_TRIGGER);
/* Soft trigger mode default use single convert */
__ADC_SET_CONVERT_MODE(ADC_SINGLE_MODE);
}
}
/******************************************************************************
* @fn adc_soft_trigger_convert
*
* @brief Software triggers the specified channel convert.
*
* @param fu8_Channel : channel number(0 ~ 7)
*/
void adc_soft_trigger_convert(uint8_t fu8_Channel)
{
/* select soft trigger channel */
__ADC_SET_SOFT_TRIGGER_CHANNEL(fu8_Channel);
/* soft trigger */
__ADC_SOFT_TRIGGER();
}
/******************************************************************************
* @fn adc_convert_start/stop
*
* @brief hardware triggers channel convert start/stop.
*/
void adc_convert_start(void)
{
__ADC_CONVERT_ENABLE();
}
void adc_convert_start_IT(void)
{
__ADC_CONVERT_ENABLE();
__ADC_INT_ENABLE(ADC_INT_CHANNEL_VALID);
}
void adc_convert_stop(void)
{
__ADC_CONVERT_DISABLE();
__ADC_INT_DISABLE(ADC_INT_CHANNEL_VALID);
}
/******************************************************************************
* @fn adc_channel_valid_int_enable/disable
*
* @brief channel valid interrupt enable/disable.
*/
void adc_channel_valid_int_enable(void)
{
__ADC_INT_ENABLE(ADC_INT_CHANNEL_VALID);
}
void adc_channel_valid_int_disable(void)
{
__ADC_INT_DISABLE(ADC_INT_CHANNEL_VALID);
}
/******************************************************************************
* @fn adc_get_channel_valid_status
*
* @brief get Channel valid status.
*
* @param fu8_Channel : channel number(0 ~ 7)
*/
bool adc_get_channel_valid_status(uint8_t fu8_Channel)
{
return (__ADC_GET_CHANNEL_STATUS() & (1 << fu8_Channel)) ? true : false;
}
/******************************************************************************
* @fn adc_get_channel_data
*
* @brief get Channel convert Data.
* @param fu8_Channel : channel number(0 ~ 7)
*/
uint32_t adc_get_channel_data(uint8_t fu8_Channel)
{
return __ADC_GET_CHANNEL_DATA(fu8_Channel);
}
/******************************************************************************
* @fn adc_set_channel_maping
*
* @brief set Channel maping.
*
* @param fu8_Channel : channel number(0 ~ 7)
* @param fe_Map : channel map select.
*/
void adc_set_channel_maping(uint8_t fu8_Channel, enum_ADC_Channel_Map_t fe_Map)
{
__ADC_SET_CHANNEL_MAP(fu8_Channel, fe_Map);
}

View File

@ -0,0 +1,179 @@
/*
******************************************************************************
* @file driver_aes.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2022
* @brief IIR module driver.
* This file provides firmware functions to manage the
* SEC AES peripheral
******************************************************************************
* @attention
*
* Copyright (c) 2022 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
/*********************************************************************
* @fn aes_config
*
* @brief config the aes mode and Endia.
*
* @param fe_Mode : select AES mode.
* @param fe_Endian: select AES Endian.
*/
void aes_config(enum_AES_MODE_t fe_Mode, enum_ENDIAN_t fe_Endian)
{
/* AES Endian */
SEC_AES->AES_CTRL.Bits.ENDIAN_SEL = fe_Endian;
/* AES Mode */
if (fe_Mode >= AES_CBC_128){
SEC_AES->AES_CTRL.Bits.CBC = AES_CBC_MODE_ENABLE;
SEC_AES->AES_CTRL.Bits.KEY_LEN = fe_Mode - AES_CBC_128;
}
else{
SEC_AES->AES_CTRL.Bits.CBC = AES_CBC_MODE_DISABLE;
SEC_AES->AES_CTRL.Bits.KEY_LEN = fe_Mode;
}
}
/*********************************************************************
* @fn aes_set_encrypt_key
*
* @brief Set AES encryption key.
*
* @param key : points to the AES key.
*/
void aes_set_encrypt_key(uint8_t *key)
{
uint32_t *lp_Key = (uint32_t *)key;
SEC_AES->KEY_0 = lp_Key[0];
SEC_AES->KEY_1 = lp_Key[1];
SEC_AES->KEY_2 = lp_Key[2];
SEC_AES->KEY_3 = lp_Key[3];
switch(SEC_AES->AES_CTRL.Bits.KEY_LEN)
{
case AES_ECB_192:{
SEC_AES->KEY_4 = lp_Key[4];
SEC_AES->KEY_5 = lp_Key[5];
}break;
case AES_ECB_256:{
SEC_AES->KEY_4 = lp_Key[4];
SEC_AES->KEY_5 = lp_Key[5];
SEC_AES->KEY_6 = lp_Key[6];
SEC_AES->KEY_7 = lp_Key[7];
}break;
default:break;
}
}
/*********************************************************************
* @fn aes_set_encrypt_iv
*
* @brief Set IV for the encrypt/decrypt.
*
* @param key : points to the AES key.
*/
void aes_set_encrypt_iv(uint8_t *iv)
{
uint32_t *lp_IV = (uint32_t *)iv;
SEC_AES->IV_0 = lp_IV[0];
SEC_AES->IV_1 = lp_IV[1];
SEC_AES->IV_2 = lp_IV[2];
SEC_AES->IV_3 = lp_IV[3];
}
/*********************************************************************
* @fn aes_encrypt
*
* @brief aes encrypt.
*
* @param fp_Data_In: the pointer of data which is to encrypt.
* @param fu32_Size: encrypt size.
* @param fp_Data_Out: the pointer of data which saves the encryption data.
*/
void aes_encrypt(uint8_t *fp_Data_In, uint32_t fu32_Size, uint8_t *fp_Data_Out)
{
uint32_t *DataIN = (uint32_t *)fp_Data_In;
uint32_t *DataOUT = (uint32_t *)fp_Data_Out;
uint32_t InIndex = 0;
uint32_t lu32_size;
lu32_size = fu32_Size/16;
if (fu32_Size % 16)
lu32_size++;
/* Block 16 byte */
while(InIndex < lu32_size)
{
SEC_AES->DATAIN_0 = *DataIN++;
SEC_AES->DATAIN_1 = *DataIN++;
SEC_AES->DATAIN_2 = *DataIN++;
SEC_AES->DATAIN_3 = *DataIN++;
__AES_SET_OPCODE(AES_OPCODE_ENCRYPT);
__AES_WORK_START();
while(__AES_IS_BUSY());
*DataOUT++ = SEC_AES->DATAOUT_0;
*DataOUT++ = SEC_AES->DATAOUT_1;
*DataOUT++ = SEC_AES->DATAOUT_2;
*DataOUT++ = SEC_AES->DATAOUT_3;
InIndex++;
}
}
/*********************************************************************
* @fn aes_decrypt
*
* @brief aes decrypt
*
* @param fp_Data_In: the pointer of data which is to decrypt.
* @param fu32_Size: decrypt size.
* @param fp_Data_Out: the pointer of data which saves the decryption data.
*/
void aes_decrypt(uint8_t *fp_Data_In, uint32_t fu32_Size, uint8_t *fp_Data_Out)
{
uint32_t *DataIN = (uint32_t *)fp_Data_In;
uint32_t *DataOUT = (uint32_t *)fp_Data_Out;
uint32_t InIndex = 0;
uint32_t lu32_size;
lu32_size = fu32_Size/16;
if (fu32_Size % 16)
lu32_size++;
while (InIndex < lu32_size)
{
SEC_AES->DATAIN_0 = *DataIN++;
SEC_AES->DATAIN_1 = *DataIN++;
SEC_AES->DATAIN_2 = *DataIN++;
SEC_AES->DATAIN_3 = *DataIN++;
__AES_SET_OPCODE(AES_OPCODE_KEY_EXPAND);
__AES_WORK_START();
while(__AES_IS_BUSY());
__AES_SET_OPCODE(AES_OPCODE_DECRYPT);
__AES_WORK_START();
while(__AES_IS_BUSY());
*DataOUT++ = SEC_AES->DATAOUT_0;
*DataOUT++ = SEC_AES->DATAOUT_1;
*DataOUT++ = SEC_AES->DATAOUT_2;
*DataOUT++ = SEC_AES->DATAOUT_3;
InIndex++;
}
}

View File

@ -0,0 +1,264 @@
/*
******************************************************************************
* @file driver_blend.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2022
* @brief BLEND module driver.
* This file provides firmware functions to manage the
* BLEND peripheral
******************************************************************************
* @attention
*
* Copyright (c) 2022 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
/************************************************************************************
* @fn blend_IRQHandler
*
* @brief Handle BLEND interrupt request.
*
* @param hblend: BLEND handle.
*/
void blend_IRQHandler(BLEND_HandleTypeDef *hblend)
{
uint32_t isr_status;
isr_status = BLEND_AHB0->ISR_STATUS.Word;
/*Out image interrupt handle*/
if(BLEND_AHB0->ISR_STATUS.Bits.ORGB_ALFULL_INT_STS == 1)
{
while(BLEND_AHB0->FIFO_STATUS.Bits.ORGB_EMPTY == 0)
{
if(hblend->DataOutIndex >= hblend->OutSize)
{
__BLEND_INT_ORGB_FIFO_ALFULL_DISABLE();
if(hblend->Callback)
{
hblend->Callback(hblend);
}
return;
}
hblend->OutRgb[hblend->DataOutIndex++] = BLEND_AHB1->ORGB_DATA;
}
}
/*Src image interrupt handle*/
if(isr_status & BLEND_RGB0_EMPTY_INT_STS)
{
while(!__RGB0_FIFO_IS_ALFULL())
{
BLEND_AHB0->RGB0_DATA = hblend->SrcRgb[hblend->SrcInIndex++];
if(hblend->SrcInIndex >= hblend->SrcSize)
{
__BLEND_INT_RGB0_FIFO_EMPTY_DISABLE();
break;
}
}
}
/*Back image interrupt handle*/
if(isr_status & BLEND_RGB1_EMPTY_INT_STS)
{
while(!__RGB1_FIFO_IS_ALFULL())
{
BLEND_AHB0->RGB1_DATA = hblend->BackRgb[hblend->BackInIndex++];
if(hblend->BackInIndex >= hblend->BackSize)
{
__BLEND_INT_RGB1_FIFO_EMPTY_DISABLE();
break;
}
}
}
/*Mask image interrupt handle*/
if(isr_status & BLEND_MASK_EMPTY_INT_STS)
{
while(!__MASK_FIFO_IS_ALFULL())
{
BLEND_AHB1->MASK_DATA = hblend->MaskRgb[hblend->MaskInIndex++];
if(hblend->MaskInIndex >= hblend->MaskSize)
{
__BLEND_INT_MASK_FIFO_EMPTY_DISABLE();
break;
}
}
}
}
/******************************************************************************
* @fn blend_init
*
* @brief Initialize the BLEND according to the specified parameters
* in the BLEND_HandleTypeDef
*
* @param hblend : BLEND_HandleTypeDef structure that contains the
* configuration information for blend module.
*/
void blend_init(BLEND_HandleTypeDef *hblend)
{
/*general config*/
BLEND_AHB0->CONFIG.Bits.BLEND_MODE = hblend->BlendInit.Bits.BLEND_MODE;
BLEND_AHB0->CONFIG.Bits.ORGB_FORMAT = hblend->BlendInit.Bits.OUTRGB_FORMAT;
BLEND_AHB0->CONFIG.Bits.RGB0_FORMAT = hblend->BlendInit.Bits.INRGB0_FORMAT;
BLEND_AHB0->CONFIG.Bits.RGB1_FORMAT = hblend->BlendInit.Bits.INRGB1_FORMAT;
BLEND_AHB0->SRC_ALPHA.Bits.SRC_ALPHA = hblend->BlendInit.Bits.SRC_ALPHA;
BLEND_AHB0->CONFIG.Bits.MASK_CAL_EN = hblend->BlendInit.Bits.MASK_CAL_EN;
BLEND_AHB0->CONFIG.Bits.RGB0_CAL_EN = 1;
BLEND_AHB0->CONFIG.Bits.RGB1_CAL_EN = 1;
BLEND_AHB0->CTRL.Bits.MASK_FF_RST = 1;
BLEND_AHB0->CTRL.Bits.ORGB_FF_RST = 1;
BLEND_AHB0->CTRL.Bits.RGB0_FF_RST = 1;
BLEND_AHB0->CTRL.Bits.RGB1_FF_RST = 1;
BLEND_AHB0->CONFIG.Bits.R_MUL_TC_EN = 1;
BLEND_AHB0->CONFIG.Bits.G_MUL_TC_EN = 1;
BLEND_AHB0->CONFIG.Bits.B_MUL_TC_EN = 1;
BLEND_AHB0->CONFIG.Bits.A_MUL_TC_EN = 1;
BLEND_AHB0->CONFIG.Bits.ORGB_565_R_TC_EN = 1;
BLEND_AHB0->CONFIG.Bits.ORGB_565_G_TC_EN = 1;
BLEND_AHB0->CONFIG.Bits.ORGB_565_B_TC_EN = 1;
BLEND_AHB0->CONFIG.Bits.ORGB_332_R_TC_EN = 1;
BLEND_AHB0->CONFIG.Bits.ORGB_332_G_TC_EN = 1;
BLEND_AHB0->CONFIG.Bits.ORGB_332_B_TC_EN = 1;
BLEND_AHB0->PIXEL_THR.Bits.O565_B_THR = 4;
BLEND_AHB0->PIXEL_THR.Bits.O565_G_THR = 2;
BLEND_AHB0->PIXEL_THR.Bits.O565_R_THR = 4;
BLEND_AHB0->PIXEL_THR.Bits.O332_B_THR = 32;
BLEND_AHB0->PIXEL_THR.Bits.O332_G_THR = 16;
BLEND_AHB0->PIXEL_THR.Bits.O332_R_THR = 16;
/*some option select to config*/
if(hblend->BlendInit.Bits.SRC_IS_PURE == 1)
{
BLEND_AHB0->PIXEL.Bits.PIXEL_ALPHA = hblend->BlendInit.Bits.SRC_ALPHA;
BLEND_AHB0->PIXEL.Bits.PIXEL_DATA = hblend->Pure.Bits.PIXEL;
BLEND_AHB0->CONFIG.Bits.ORGB_MODE = 0;
}
else
{
BLEND_AHB0->CONFIG.Bits.ORGB_MODE = 1;
}
if(hblend->BlendInit.Bits.DMA_IN_EN == 1)
{
BLEND_AHB0->DMAC.Bits.RGB0_DMA_EN = 1;
BLEND_AHB0->DMAC.Bits.RGB1_DMA_EN = 1;
BLEND_AHB0->DMAC.Bits.MASK_DMA_EN = 1;
}
if(hblend->BlendInit.Bits.DMA_OUT_EN == 1)
{
BLEND_AHB0->DMAC.Bits.ORGB_DMA_EN = 1;
}
/*fifo threshold config*/
BLEND_AHB0->INFIFO0_THR_CTL.Bits.RGB0_ALEMPTY_THR = hblend->Infifo0Thr.Bits.ALEMPTY_THR;
BLEND_AHB0->INFIFO0_THR_CTL.Bits.RGB0_ALFULL_THR = 30;
BLEND_AHB0->INFIFO0_THR_CTL.Bits.RGB0_DMA_THR = hblend->Infifo0Thr.Bits.DMA_THR;
BLEND_AHB0->INFIFO1_THR_CTL.Bits.RGB1_ALEMPTY_THR = hblend->Infifo1Thr.Bits.ALEMPTY_THR;
BLEND_AHB0->INFIFO1_THR_CTL.Bits.RGB1_ALFULL_THR = 30;
BLEND_AHB0->INFIFO1_THR_CTL.Bits.RGB1_DMA_THR = hblend->Infifo1Thr.Bits.DMA_THR;
BLEND_AHB0->INFIFOMASK_THR_CTL.Bits.MASK_ALEMPTY_THR = hblend->InfifoMaskThr.Bits.ALEMPTY_THR;
BLEND_AHB0->INFIFOMASK_THR_CTL.Bits.MASK_ALFULL_THR = 30;
BLEND_AHB0->INFIFOMASK_THR_CTL.Bits.MASK_DMA_THR = hblend->InfifoMaskThr.Bits.DMA_THR;
BLEND_AHB0->OUTFIFO_THR_CTL.Bits.ORGB_ALFULL_THR = hblend->OutfifoThr.Bits.ALFULL_THR;
BLEND_AHB0->OUTFIFO_THR_CTL.Bits.ORGB_DMA_THR = hblend->OutfifoThr.Bits.DMA_THR;
BLEND_AHB0->CTRL.Bits.BLEND_EN = 1;
}
/******************************************************************************
* @fn blend_start
*
* @brief Blend start without interrupt.
*
* @param hblend : BLEND HANDLE
* DataParam : BLEND_DataParam_t structure contain pixel need to handle
*/
void blend_start(BLEND_HandleTypeDef *hblend, BLEND_DataParam_t DataParam)
{
uint32_t *SrcRgb;
uint32_t *BackRgb;
uint32_t *Mask;
uint32_t *OutRgb;
uint32_t SrcSize;
uint32_t BackSize;
uint32_t MaskSize;
uint32_t OutSize;
SrcRgb = (uint32_t *)DataParam.SrcRgb;
BackRgb = (uint32_t *)DataParam.BackRgb;
Mask = (uint32_t *)DataParam.MaskRgb;
OutRgb = (uint32_t *)DataParam.OutRgb;
SrcSize = DataParam.PixelCount;
BackSize = DataParam.PixelCount;
MaskSize = DataParam.PixelCount;
OutSize = DataParam.PixelCount;
uint32_t MaskAddValue = 0;
while(hblend->DataOutIndex < OutSize)
{
/*whether txfifo 0 is almost full or not*/
if((!__RGB0_FIFO_IS_ALFULL()) && (hblend->SrcInIndex < SrcSize))
{
BLEND_AHB0->RGB0_DATA = SrcRgb[hblend->SrcInIndex++];
}
/*whether txfifo 1 is full or not*/
if((!__RGB1_FIFO_IS_ALFULL()) && (hblend->BackInIndex < BackSize))
{
BLEND_AHB0->RGB1_DATA = BackRgb[hblend->BackInIndex++];
}
/*whether txfifo mask is full or not*/
if((!__MASK_FIFO_IS_ALFULL()) && (hblend->MaskInIndex < MaskSize) &&
(hblend->BlendInit.Bits.MASK_CAL_EN))
{
BLEND_AHB1->MASK_DATA = Mask[hblend->MaskInIndex++];
}
/*whether rx fifo is empty or not*/
if(BLEND_AHB0->FIFO_STATUS.Bits.ORGB_EMPTY != 1)
{
DataParam.OutRgb[hblend->DataOutIndex++] = BLEND_AHB1->ORGB_DATA;
}
}
}
/******************************************************************************
* @fn blend_start_IT
*
* @brief Blend start with interrupt.
*
* @param hblend : BLEND HANDLE
* DataParam : BLEND_DataParam_t structure contain pixel need to handle
*/
void blend_start_IT(BLEND_HandleTypeDef *hblend, BLEND_DataParam_t DataParam)
{
hblend->SrcRgb = (uint32_t *)DataParam.SrcRgb;
hblend->BackRgb = (uint32_t *)DataParam.BackRgb;
hblend->OutRgb = (uint32_t *)DataParam.OutRgb;
hblend->SrcSize = DataParam.PixelCount;
hblend->BackSize = DataParam.PixelCount;
hblend->MaskSize = DataParam.PixelCount;
hblend->OutSize = DataParam.PixelCount;
hblend->PixelCount = DataParam.PixelCount;
if(hblend->BlendInit.Bits.MASK_CAL_EN == 1)
{
hblend->MaskRgb = (uint32_t *)DataParam.MaskRgb;
__BLEND_INT_MASK_FIFO_EMPTY_ENABLE();
}
__BLEND_INT_RGB0_FIFO_EMPTY_ENABLE();
__BLEND_INT_RGB1_FIFO_EMPTY_ENABLE();
__BLEND_INT_ORGB_FIFO_ALFULL_ENABLE();
}

View File

@ -0,0 +1,117 @@
/*
******************************************************************************
* @file driver_cali.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2023
* @brief Calibration module driver.
* This file provides firmware functions to calibrate RC frequency
******************************************************************************
* @attention
*
* Copyright (c) 2023 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
#include "co_util.h"
/************************************************************************************
* @fn cali_IRQHandler
*
* @brief Handle Calibration interrupt request.
*
* @param hcali: Calibration handle.
*/
__WEAK void cali_IRQHandler(CALI_HandleTypeDef *hcali)
{
__CALI_INT_CLR();
if (hcali->DoneCallback) {
hcali->DoneCallback(hcali, __CALI_RESULT_GET());
}
}
/************************************************************************************
* @fn cali_init
*
* @brief Initialize the calibration module
*
* @param hcali: calibration handle.
*/
void cali_init(CALI_HandleTypeDef *hcali)
{
__CALI_DISABLE();
__CALI_INT_DISABLE();
__CALI_UP_MODE_SET(hcali->mode);
__CALI_CNT_SET(hcali->rc_cnt);
}
/************************************************************************************
* @fn cali_start
*
* @brief start calibration with block mode, call cali_calc_rc_freq to calcuate RC
* frequency with calibration result.
*
* @param hcali: calibration handle.
*
* @return calibration result
*/
uint32_t cali_start(CALI_HandleTypeDef *hcali)
{
uint32_t result;
__CALI_ENABLE();
while (__CALI_IS_DONE() == 0);
result = __CALI_RESULT_GET();
__CALI_DISABLE();
return result;
}
/************************************************************************************
* @fn cali_start_IT
*
* @brief start calibration with interrupt mode
*
* @param hcali: calibration handle.
*/
void cali_start_IT(CALI_HandleTypeDef *hcali)
{
__CALI_INT_ENABLE();
__CALI_ENABLE();
}
/************************************************************************************
* @fn cali_stop
*
* @brief stop on-going calibration
*
* @param hcali: calibration handle.
*/
void cali_stop(CALI_HandleTypeDef *hcali)
{
__CALI_DISABLE();
}
/************************************************************************************
* @fn cali_calc_rc_freq
*
* @brief calculate RC frequency with calibrated result
*
* @param hcali: calibration handle.
* cali_result: calibration result from cali_start or DoneCallback
*
* @return calculate result
*/
uint32_t cali_calc_rc_freq(CALI_HandleTypeDef *hcali, uint32_t cali_result)
{
uint32_t tmp_high,tmp_low;
uint32_t lp_frequency;
mul_64(&tmp_low, &tmp_high, 24000000, hcali->rc_cnt);
lp_frequency = simple_div_64(tmp_low, tmp_high, cali_result);
return lp_frequency;
}

View File

@ -0,0 +1,743 @@
/*
******************************************************************************
* @file driver_can.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2022
* @brief SD controller HAL module driver.
* This file provides firmware functions to manage the
* Controller Area Network (CAN) peripheral
******************************************************************************
* @attention
*
* Copyright (c) 2022 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
/************************************************************************************
* @fn can_init
*
* @brief Initializes the CAN peripheral according to the specified
* parameters in the struct_CANInit_t
*
* @param hcan: CAN handle.
*/
void can_init(CAN_HandleTypeDef *hcan)
{
/* Initialization start */
__CAN_INIT_START(hcan->CANx);
__CAN_CHANGE_ENABLE(hcan->CANx);
/* Timestamp enable */
__CAN_SET_TIMESTAMP_SELECT_INTERNAL(hcan->CANx);
/* Bit Rate Prescaler */
__CAN_SET_NOMINAL_RATE_PRESCALER(hcan->CANx, hcan->Init.Prescaler);
/* Data time segment1/segment2 */
__CAN_SET_NOMINAL_TIME_SEG_1(hcan->CANx, hcan->Init.TimeSeg1);
__CAN_SET_NOMINAL_TIME_SEG_2(hcan->CANx, hcan->Init.TimeSeg2);
/* Synchronization Jump Width */
__CAN_SET_NOMINAL_SYNC_WIDTH(hcan->CANx, hcan->Init.SyncJumpWidth);
/* Bus Monitor Mode */
hcan->CANx->CCCtrl.MON = hcan->Init.BusMonitorMode ? 1 : 0;
/* Auto Retransmission mode */
hcan->CANx->CCCtrl.DAR = hcan->Init.AutoRetransmission ? 0 : 1;
/* default transmit Pause enable */
hcan->CANx->CCCtrl.TXP = 1;
hcan->CANx->CCCtrl.BRSE = CAN_FUNC_DISABLE;
/* Global Filter Config */
__CAN_STANDARD_REJECT_UNMATCHED_FRAME(hcan->CANx);
__CAN_EXTENDED_REJECT_UNMATCHED_FRAME(hcan->CANx);
__CAN_STANDARD_FILTER_REMOTE_FRAME(hcan->CANx);
__CAN_EXTENDED_FILTER_REMOTE_FRAME(hcan->CANx);
/* Tx Buffer Transmission Occurred enable */
__CAN_Tx_OCCURRED_INT_ENABLE(hcan->CANx, 0xFFFFFFFF);
/* Int status enable */
__CAN_INT_LINE_ENABLE(hcan->CANx);
}
/************************************************************************************
* @fn can_message_ram_init
*
* @brief initialize standard ID filter / extended ID filter /
* Tx queue Buffer /
* Rx FIFO 0/1 / Rx Buffer
* element size, Nums and start address.
*
* @param hcan: CAN handle.
*/
void can_message_ram_init(CAN_HandleTypeDef *hcan)
{
uint16_t lu16_AddrOffset;
uint16_t lu16_ElementSize;
/* Set message ram high 16bit address */
__CAN_SET_MESSAGE_RAM_HIGHH_16BIT_ADDR(hcan->CANx, hcan->RAMConfig.StartAddress >> 16);
/* ---------------------------------------------*/
/* ----- standard ID filter Buffer config ------*/
/* ---------------------------------------------*/
/* Calculate Start address */
lu16_AddrOffset = hcan->RAMConfig.StartAddress;
/* Set the number of standard message ID filter element */
__CAN_SET_STANDARD_ID_FILTER_LIST_NUMS(hcan->CANx, hcan->RAMConfig.StandardIDFilterNums);
/* Set the start address of standard Message ID filter list */
__CAN_SET_STANDARD_ID_FILTER_LIST_START_ADDRESS(hcan->CANx, lu16_AddrOffset);
/* ---------------------------------------------*/
/* ----- extended ID filter Buffer config ------*/
/* ---------------------------------------------*/
/* Calculate offset address */
lu16_AddrOffset += hcan->RAMConfig.StandardIDFilterNums * 4;
/* Set the number of extended message ID filter element */
__CAN_SET_EXTENDED_ID_FILTER_LIST_NUMS(hcan->CANx, hcan->RAMConfig.ExtendedIDFilterNums);
/* Set the start address of extended Message ID filter list */
__CAN_SET_EXTENDED_ID_FILTER_LIST_START_ADDRESS(hcan->CANx, lu16_AddrOffset);
/* ---------------------------------------------*/
/* ---------- Tx queue Buffer congfig ----------*/
/* ---------------------------------------------*/
/* Calculate offset address */
lu16_AddrOffset += hcan->RAMConfig.ExtendedIDFilterNums * 8;
/* Tx queue operation */
__CAN_SET_Tx_QUEUE_OPERATION(hcan->CANx);
/* Set the Number of Tx Queue element */
__CAN_SET_Tx_FIFO_QUEUE_NUMS(hcan->CANx, hcan->RAMConfig.TxQueueNums);
__CAN_SET_Tx_BUFFER_NUMS(hcan->CANx, 0);
/* Set the start address of Tx Queue section in Message RAM */
__CAN_SET_Tx_BUFFER_START_ADDRESS(hcan->CANx, lu16_AddrOffset);
/* Tx queue element size /
Rx FIFO0 element size /
Rx FIFO1 element size /
Rx Buffer element size */
lu16_ElementSize = 16;
/* classical CAN fixed 16byte */
/* Record element size */
hcan->ElementSize = lu16_ElementSize;
/* ---------------------------------------------*/
/* ------------- Rx FIFO 0 congfig -------------*/
/* ---------------------------------------------*/
/* Calculate offset address */
lu16_AddrOffset += hcan->RAMConfig.TxQueueNums * lu16_ElementSize;
/* FIFO 0 blocking mode */
__CAN_SET_Rx_FIFO0_BLOCKING_MODE(hcan->CANx);
/* Set the Number of Rx FIFO0 element */
__CAN_SET_Rx_FIFO0_NUMS(hcan->CANx, hcan->RAMConfig.RxFIFO0Nums);
/* Set the start address of Rx FIFO 0 section in Message RAM */
__CAN_SET_Rx_FIFO0_START_ADDRESS(hcan->CANx, lu16_AddrOffset);
/* ---------------------------------------------*/
/* ------------- Rx FIFO 1 congfig -------------*/
/* ---------------------------------------------*/
/* Calculate offset address */
lu16_AddrOffset += hcan->RAMConfig.RxFIFO0Nums * lu16_ElementSize;
/* FIFO 1 blocking mode */
__CAN_SET_Rx_FIFO1_BLOCKING_MODE(hcan->CANx);
/* Set the Number of Rx FIFO1 element */
__CAN_SET_Rx_FIFO1_NUMS(hcan->CANx, hcan->RAMConfig.RxFIFO1Nums);
/* Set the start address of Rx FIFO 1 section in Message RAM */
__CAN_SET_Rx_FIFO1_START_ADDRESS(hcan->CANx, lu16_AddrOffset);
/* ---------------------------------------------*/
/* -------- Rx dedicated buffer congfig --------*/
/* ---------------------------------------------*/
/* Calculate offset address */
lu16_AddrOffset += hcan->RAMConfig.RxFIFO1Nums * lu16_ElementSize;
/* Set the start address of Rx dedicated buffer section in Message RAM */
__CAN_SET_Rx_BUFFER_START_ADDRESS(hcan->CANx, lu16_AddrOffset);
/* Initialization stop */
__CAN_CHANGE_DISABLE(hcan->CANx);
__CAN_INIT_STOP(hcan->CANx);
}
/************************************************************************************
* @fn can_ram_watch_dog_config
*
* @brief ram watch dog config.
*
* @param fu8_InitValue: Start value of the Message RAM Watchdog Counter.
* if the value config '00' the counter is disabled.
*/
void can_ram_watch_dog_config(CAN_HandleTypeDef *hcan, uint8_t fu8_InitValue)
{
/* Initialization start */
__CAN_INIT_START(hcan->CANx);
__CAN_CHANGE_ENABLE(hcan->CANx);
__CAM_SET_RAM_WATCHDOG_INITIAL_VALUE(hcan->CANx, fu8_InitValue);
/* Initialization stop */
__CAN_CHANGE_DISABLE(hcan->CANx);
__CAN_INIT_STOP(hcan->CANx);
}
/************************************************************************************
* @fn can_get_ram_watch_dog_value
*
* @brief get ram watch dog counter value.
*/
uint8_t can_get_ram_watch_dog_value(CAN_HandleTypeDef *hcan)
{
return __CAM_GET_RAM_WATCHDOG_VALUE(hcan->CANx);
}
/************************************************************************************
* @fn can_timestamp_Prescaler_config
*
* @brief Configures the timestamp unit in multiples of CAN bit times 1 ~ 16.
*
* @param fu8_prescaler: prescaler value can be 1 ~ 16.
*/
void can_timestamp_prescaler_config(CAN_HandleTypeDef *hcan, uint8_t fu8_prescaler)
{
/* Initialization start */
__CAN_INIT_START(hcan->CANx);
__CAN_CHANGE_ENABLE(hcan->CANx);
__CAN_SET_TIMESTAMP_PRESCALER(hcan->CANx, fu8_prescaler);
/* Initialization stop */
__CAN_CHANGE_DISABLE(hcan->CANx);
__CAN_INIT_STOP(hcan->CANx);
}
/************************************************************************************
* @fn can_timestamp_counter_reset
*
* @brief timestamp counter reset 0.
*/
void can_timestamp_counter_reset(CAN_HandleTypeDef *hcan)
{
__CAN_SET_TIMESTAMP(hcan->CANx);
}
/************************************************************************************
* @fn can_timestamp_counter_reset
*
* @brief get timestamp counter value.
*/
uint16_t can_get_timestamp_counter(CAN_HandleTypeDef *hcan)
{
return __CAN_GET_TIMESTAMP(hcan->CANx);
}
/************************************************************************************
* @fn can_get_transmit_error_counter
* @fn can_get_receive_error_counter
*
* @brief get transmit/receive error counter value.
*/
uint8_t can_get_transmit_error_counter(CAN_HandleTypeDef *hcan)
{
return __CAN_GET_TRANSMIT_ERROR_COUNTER(hcan->CANx);
}
uint8_t can_get_receive_error_counter(CAN_HandleTypeDef *hcan)
{
return __CAN_GET_RECEIVE_ERROR_COUNTER(hcan->CANx);
}
/************************************************************************************
* @fn can_add_tx_message
*
* @brief Add a message to the Tx queue.(classics can)
*
* @param hcan: CAN handle.
* fstr_TxHeader: Tx message header.
* Data: Data buffer pointer.
* @return lu32_PutIndex > 0: Put index in Tx queue.
* Error < 0.
*/
int32_t can_add_tx_message(CAN_HandleTypeDef *hcan, struct_CANTxHeaderDef_t fstr_TxHeader, uint8_t *Data)
{
uint32_t i;
struct_CanTxElement_t *CanTxElement;
uint32_t lu32_Address;
uint32_t lu32_PutIndex;
/* Tx queue full */
if (__CAN_IS_TxFIFO_QUEUE_FULL(hcan->CANx))
return CAN_ERR_TXFIFO_FULL;
/* the start address of Tx Queue section in Message RAM */
lu32_Address = __CAN_GET_MESSAGE_RAM_HIGHH_16BIT_ADDR(hcan->CANx) << 16;
lu32_Address |= __CAN_GET_Tx_BUFFER_START_ADDRESS(hcan->CANx);
/* Calculate element offset address */
lu32_PutIndex = __CAN_GET_TxFIFO_QUEUE_PUT_INDEX(hcan->CANx);
lu32_Address += lu32_PutIndex * hcan->ElementSize;
/* write param/data to message ram */
CanTxElement = (struct_CanTxElement_t *)lu32_Address;
/* Frame type, data or remote */
CanTxElement->FrameCFG.XTD = fstr_TxHeader.IdType;
if (fstr_TxHeader.IdType == CAN_ID_STANDARD)
CanTxElement->FrameCFG.ID = fstr_TxHeader.Identifier << 18;
else
CanTxElement->FrameCFG.ID = fstr_TxHeader.Identifier;
/* Data frame */
if (fstr_TxHeader.FrameType == CAN_DATA_FRAME)
{
CanTxElement->FrameCFG.DLC = fstr_TxHeader.DLC;
CanTxElement->FrameCFG.RTR = CAN_DATA_FRAME;
for (i = 0; i < fstr_TxHeader.DLC; i++)
{
CanTxElement->Data[i] = Data[i];
}
}
/* Remote frame */
else
{
CanTxElement->FrameCFG.DLC = 0;
CanTxElement->FrameCFG.RTR = CAN_REMOTE_FRAM;
}
/* Add request */
__CAN_ADD_Tx_REQUEST(hcan->CANx, 1 << lu32_PutIndex);
return lu32_PutIndex;
}
/************************************************************************************
* @fn can_is_tx_message_pending
*
* @brief Check if a transmission request is pending.
*
* @param hcan: CAN handle.
* fu32_PutIndex: tx message index in Tx queue.
* @return true: tx message pending.
* false: tx message not pending.
*/
bool can_is_tx_message_pending(CAN_HandleTypeDef *hcan, uint32_t fu32_PutIndex)
{
bool lb_status;
return lb_status = (__CAN_GET_Tx_REQUEST_PENDING(hcan->CANx) & (1 << fu32_PutIndex)) ? true : false;
}
/************************************************************************************
* @fn can_abort_tx_message
*
* @brief abort a message from the Tx queue.
*
* @param hcan: CAN handle.
* fu32_PutIndex: tx message index in Tx queue.
*/
void can_abort_tx_message(CAN_HandleTypeDef *hcan, uint32_t fu32_PutIndex)
{
/* Tx Buffer Cancellation Request */
__CAN_CANCELLATION_Tx_REQUEST(hcan->CANx, 1 << fu32_PutIndex);
}
/************************************************************************************
* @fn can_add_standard_filter
*
* @brief Added standard filter config.
*
* @param hcan: CAN handle.
* fstr_FilterCfg: standard filter config param.
* fu32_Index: filter number index.
*/
void can_add_standard_filter(CAN_HandleTypeDef *hcan, struct_FilterCfg_t fstr_FilterCfg, uint32_t fu32_Index)
{
uint32_t lu32_Address;
struct_StdFilterElement_t *StdFilterElement;
/* Set the start address of standard Message ID filter list */
lu32_Address = __CAN_GET_MESSAGE_RAM_HIGHH_16BIT_ADDR(hcan->CANx) << 16;
lu32_Address |= __CAN_GET_STANDARD_ID_FILTER_LIST_START_ADDRESS(hcan->CANx);
/* Calculate element offset address */
lu32_Address += fu32_Index * 4;
/* write param/data to message ram */
StdFilterElement = (struct_StdFilterElement_t *)lu32_Address;
StdFilterElement->SFT = fstr_FilterCfg.FilterType;
StdFilterElement->SFEC = fstr_FilterCfg.ProcessMode;
StdFilterElement->SFID1 = fstr_FilterCfg.StdFilterID_1;
StdFilterElement->SFID2 = fstr_FilterCfg.StdFilterID_2;
if (fstr_FilterCfg.ProcessMode == FILTER_PROCESS_STORE_IN_RxBUFFER)
{
StdFilterElement->SFID2 = fstr_FilterCfg.RxBufferIndex;
if (fstr_FilterCfg.RxBufferIndex < 32)
hcan->RxBufferUsed_L |= 1 << fstr_FilterCfg.RxBufferIndex;
else
hcan->RxBufferUsed_H |= 1 << (fstr_FilterCfg.RxBufferIndex - 32);
}
}
/************************************************************************************
* @fn can_add_extended_filter
*
* @brief Added extended filter config.
*
* @param hcan: CAN handle.
* fstr_FilterCfg: extended filter config param.
* fu32_Index: filter number index.
*/
void can_add_extended_filter(CAN_HandleTypeDef *hcan, struct_FilterCfg_t fstr_FilterCfg, uint32_t fu32_Index)
{
uint32_t lu32_Address;
struct_ExtFilterElement_t *ExtFilterElement;
/* Set the start address of extended Message ID filter list */
lu32_Address = __CAN_GET_MESSAGE_RAM_HIGHH_16BIT_ADDR(hcan->CANx) << 16;
lu32_Address |= __CAN_GET_EXTENDED_ID_FILTER_LIST_START_ADDRESS(hcan->CANx);
/* Calculate element offset address */
lu32_Address += fu32_Index * 8;
/* write param/data to message ram */
ExtFilterElement = (struct_ExtFilterElement_t *)lu32_Address;
ExtFilterElement->EFT = fstr_FilterCfg.FilterType;
ExtFilterElement->EFEC = fstr_FilterCfg.ProcessMode;
ExtFilterElement->EFID1 = fstr_FilterCfg.StdFilterID_1;
ExtFilterElement->EFID2 = fstr_FilterCfg.StdFilterID_2;
if (fstr_FilterCfg.ProcessMode == FILTER_PROCESS_STORE_IN_RxBUFFER)
{
ExtFilterElement->EFID2 = fstr_FilterCfg.RxBufferIndex;
if (fstr_FilterCfg.RxBufferIndex < 32)
hcan->RxBufferUsed_L |= 1 << fstr_FilterCfg.RxBufferIndex;
else
hcan->RxBufferUsed_H |= 1 << (fstr_FilterCfg.RxBufferIndex - 32);
}
}
/************************************************************************************
* @fn can_remove_standard_filter
*
* @brief Remove standard filter config.
*
* @param hcan: CAN handle.
* fu32_Index: filter number index.
*/
void can_remove_standard_filter(CAN_HandleTypeDef *hcan, uint32_t fu32_Index)
{
uint32_t lu32_Address;
struct_StdFilterElement_t *StdFilterElement;
/* Set the start address of standard Message ID filter list */
lu32_Address = __CAN_GET_MESSAGE_RAM_HIGHH_16BIT_ADDR(hcan->CANx) << 16;
lu32_Address |= __CAN_GET_STANDARD_ID_FILTER_LIST_START_ADDRESS(hcan->CANx);
/* Calculate element offset address */
lu32_Address += fu32_Index * 4;
/* write param/data to message ram */
StdFilterElement = (struct_StdFilterElement_t *)lu32_Address;
/* Disable selected element */
if (StdFilterElement->SFEC == FILTER_PROCESS_STORE_IN_RxBUFFER)
{
if (StdFilterElement->SFID2 < 32)
hcan->RxBufferUsed_L &= ~(1 << StdFilterElement->SFID2);
else
hcan->RxBufferUsed_H &= ~(1 << (StdFilterElement->SFID2 - 32));
}
StdFilterElement->SFT = CAN_FILTER_DISABLE;
StdFilterElement->SFEC = FILTER_PROCESS_DISABLE;
}
/************************************************************************************
* @fn can_remove_extended_filter
*
* @brief Remove extended filter config.
*
* @param hcan: CAN handle.
* fu32_Index: filter number index.
*/
void can_remove_extended_filter(CAN_HandleTypeDef *hcan, uint32_t fu32_Index)
{
uint32_t lu32_Address;
struct_ExtFilterElement_t *ExtFilterElement;
/* Set the start address of extended Message ID filter list */
lu32_Address = __CAN_GET_MESSAGE_RAM_HIGHH_16BIT_ADDR(hcan->CANx) << 16;
lu32_Address |= __CAN_GET_EXTENDED_ID_FILTER_LIST_START_ADDRESS(hcan->CANx);
/* Calculate element offset address */
lu32_Address += fu32_Index * 8;
/* write param/data to message ram */
ExtFilterElement = (struct_ExtFilterElement_t *)lu32_Address;
/* Disable selected element */
if (ExtFilterElement->EFEC == FILTER_PROCESS_STORE_IN_RxBUFFER)
{
if (ExtFilterElement->EFID2 < 32)
hcan->RxBufferUsed_L &= ~(1 << ExtFilterElement->EFID2);
else
hcan->RxBufferUsed_H &= ~(1 << (ExtFilterElement->EFID2 - 32));
}
ExtFilterElement->EFEC = FILTER_PROCESS_DISABLE;
}
/************************************************************************************
* @fn can_get_rxbuffer_message
*
* @brief Get an CAN frame from the Rx buffer.
*
* @param hcan: CAN handle.
* fu32_RxBufferIndex: The message index in the RxBuffer.
*/
void can_get_rxbuffer_message(CAN_HandleTypeDef *hcan, uint32_t fu32_RxBufferIndex, struct_CANRxHeaderDef_t *RxHeader, uint8_t *Data)
{
uint32_t lu32_Address;
struct_CanRxElement_t *CanRxElement;
/* Get the start address of Rx dedicated buffer section in Message RAM */
lu32_Address = __CAN_GET_MESSAGE_RAM_HIGHH_16BIT_ADDR(hcan->CANx) << 16;
lu32_Address |= __CAN_GET_Rx_BUFFER_START_ADDRESS(hcan->CANx);
/* Calculate element offset address */
lu32_Address += fu32_RxBufferIndex * hcan->ElementSize;
/* Read message param/data from RxBuffer ram */
CanRxElement = (struct_CanRxElement_t *)lu32_Address;
RxHeader->IdType = CanRxElement->FrameCFG.XTD ? CAN_ID_EXTENDED : CAN_ID_STANDARD;
RxHeader->Identifier = CanRxElement->FrameCFG.ID;
RxHeader->FrameType = CanRxElement->FrameCFG.RTR ? CAN_REMOTE_FRAM : CAN_DATA_FRAME;
if (RxHeader->FrameType == CAN_DATA_FRAME)
{
RxHeader->DLC = CanRxElement->FrameCFG.DLC;
for (int i = 0; i < RxHeader->DLC; i++)
{
Data[i] = CanRxElement->Data[i];
}
}
RxHeader->Timestamp = CanRxElement->FrameCFG.RXTS;
if (CanRxElement->FrameCFG.ANMF == 0)
{
RxHeader->FilterMatchIndex = CanRxElement->FrameCFG.FIDX;
}
}
/************************************************************************************
* @fn can_get_rxfifo0_message
*
* @brief Get an CAN frame from the Rx FIFO 0.
*
* @param hcan: CAN handle.
*/
uint32_t can_get_rxfifo0_message(CAN_HandleTypeDef *hcan, struct_CANRxHeaderDef_t *RxHeader, uint8_t *Data)
{
uint32_t lu32_Address, lu32_GetIndex;
struct_CanRxElement_t *CanRxElement;
/* Rx FIFO0 get index */
lu32_GetIndex = __CAN_GET_Rx_FIFO0_GET_INDEX(hcan->CANx);
/* Get the start address of Rx FIFO 0 section in Message RAM */
lu32_Address = __CAN_GET_MESSAGE_RAM_HIGHH_16BIT_ADDR(hcan->CANx) << 16;
lu32_Address |= __CAN_GET_Rx_FIFO0_START_ADDRESS(hcan->CANx);
/* Calculate element offset address */
lu32_Address += lu32_GetIndex * hcan->ElementSize;
/* Read message param/data from RxBuffer ram */
CanRxElement = (struct_CanRxElement_t *)lu32_Address;
RxHeader->IdType = CanRxElement->FrameCFG.XTD ? CAN_ID_EXTENDED : CAN_ID_STANDARD;
RxHeader->FrameType = CanRxElement->FrameCFG.RTR ? CAN_REMOTE_FRAM : CAN_DATA_FRAME;
if (RxHeader->IdType == CAN_ID_STANDARD)
RxHeader->Identifier = CanRxElement->FrameCFG.ID >> 18;
else
RxHeader->Identifier = CanRxElement->FrameCFG.ID;
if (RxHeader->FrameType == CAN_DATA_FRAME)
{
RxHeader->DLC = CanRxElement->FrameCFG.DLC;
for (int i = 0; i < RxHeader->DLC; i++)
{
Data[i] = CanRxElement->Data[i];
}
}
RxHeader->Timestamp = CanRxElement->FrameCFG.RXTS;
if (CanRxElement->FrameCFG.ANMF == 0)
{
RxHeader->FilterMatchIndex = CanRxElement->FrameCFG.FIDX;
}
/* Read message ack */
__CAN_SET_Rx_FIFO0_ACKNOWLEDGE(hcan->CANx, lu32_GetIndex);
return lu32_GetIndex;
}
/************************************************************************************
* @fn can_get_rxfifo1_message
*
* @brief Get an CAN frame from the Rx FIFO 1.
*
* @param hcan: CAN handle.
*/
uint32_t can_get_rxfifo1_message(CAN_HandleTypeDef *hcan, struct_CANRxHeaderDef_t *RxHeader, uint8_t *Data)
{
uint32_t lu32_Address, lu32_GetIndex;
struct_CanRxElement_t *CanRxElement;
/* Rx FIFO1 get index */
lu32_GetIndex = __CAN_GET_Rx_FIFO1_GET_INDEX(hcan->CANx);
/* Get the start address of Rx FIFO 1 section in Message RAM */
lu32_Address = __CAN_GET_MESSAGE_RAM_HIGHH_16BIT_ADDR(hcan->CANx) << 16;
lu32_Address |= __CAN_GET_Rx_FIFO1_START_ADDRESS(hcan->CANx);
/* Calculate element offset address */
lu32_Address += lu32_GetIndex * hcan->ElementSize;
/* Read message param/data from RxBuffer ram */
CanRxElement = (struct_CanRxElement_t *)lu32_Address;
RxHeader->IdType = CanRxElement->FrameCFG.XTD ? CAN_ID_EXTENDED : CAN_ID_STANDARD;
RxHeader->FrameType = CanRxElement->FrameCFG.RTR ? CAN_REMOTE_FRAM : CAN_DATA_FRAME;
if (RxHeader->IdType == CAN_ID_STANDARD)
RxHeader->Identifier = CanRxElement->FrameCFG.ID >> 18;
else
RxHeader->Identifier = CanRxElement->FrameCFG.ID;
if (RxHeader->FrameType == CAN_DATA_FRAME)
{
RxHeader->DLC = CanRxElement->FrameCFG.DLC;
for (int i = 0; i < RxHeader->DLC; i++)
{
Data[i] = CanRxElement->Data[i];
}
}
RxHeader->Timestamp = CanRxElement->FrameCFG.RXTS;
if (CanRxElement->FrameCFG.ANMF == 0)
{
RxHeader->FilterMatchIndex = CanRxElement->FrameCFG.FIDX;
}
/* Read message ack */
__CAN_SET_Rx_FIFO1_ACKNOWLEDGE(hcan->CANx, lu32_GetIndex);
return lu32_GetIndex;
}
/************************************************************************************
* @fn can_get_rxfifo0_fill_level
*
* @brief Get number of elements stored in Rx FIFO 0, range 0 to 64.
*
* @param hcan: CAN handle.
*/
uint32_t can_get_rxfifo0_fill_level(CAN_HandleTypeDef *hcan)
{
return __CAN_GET_Rx_FIFO0_FILL_LEVEL(hcan->CANx);
}
/************************************************************************************
* @fn can_get_rxfifo1_fill_level
*
* @brief Get number of elements stored in Rx FIFO 0, range 0 to 64.
*
* @param hcan: CAN handle.
*/
uint32_t can_get_rxfifo1_fill_level(CAN_HandleTypeDef *hcan)
{
return __CAN_GET_Rx_FIFO1_FILL_LEVEL(hcan->CANx);
}
/************************************************************************************
* @fn can_get_rxbuffer_0_31_status
*
* @brief get rx buffer new data 0~31 status.
*
* @param hcan: CAN handle.
*/
uint32_t can_get_rxbuffer_0_31_status(CAN_HandleTypeDef *hcan)
{
return hcan->CANx->NewData1;
}
/************************************************************************************
* @fn can_get_rxbuffer_32_63_status
*
* @brief get rx buffer new data 32~63 status.
*
* @param hcan: CAN handle.
*/
uint32_t can_get_rxbuffer_32_63_status(CAN_HandleTypeDef *hcan)
{
return hcan->CANx->NewData2;
}
/************************************************************************************
* @fn can_int_enable
*
* @brief can interrupt enable.
*/
void can_int_enable(CAN_HandleTypeDef *hcan, enum_CAN_INT_Status_t fe_INT_Index)
{
__CAN_INT_ENABLE(hcan->CANx, fe_INT_Index);
}
/************************************************************************************
* @fn can_int_disable
*
* @brief can interrupt disable.
*/
void can_int_disable(CAN_HandleTypeDef *hcan, enum_CAN_INT_Status_t fe_INT_Index)
{
__CAN_INT_DISABLE(hcan->CANx, fe_INT_Index);
}
/************************************************************************************
* @fn can_get_int_status
*
* @brief get interrupt status.
*/
bool can_get_int_status(CAN_HandleTypeDef *hcan, enum_CAN_INT_Status_t fe_INT_Index)
{
bool lb_Status = (__CAN_INT_GET_STATUS(hcan->CANx) & fe_INT_Index) ? true : false;
return lb_Status;
}
/************************************************************************************
* @fn can_clear_int_status
*
* @brief clear interrupt status.
*/
void can_clear_int_status(CAN_HandleTypeDef *hcan, enum_CAN_INT_Status_t fe_INT_Index)
{
__CAN_INT_CLEAR(hcan->CANx, fe_INT_Index);
}

View File

@ -0,0 +1,876 @@
/*
******************************************************************************
* @file driver_codec.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2022
* @brief codec HAL module driver.
* This file provides firmware functions to manage the
* codec, include ADC, DAC, DRC, GPF, etc.
******************************************************************************
* @attention
*
* Copyright (c) 2022 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
/************************************************************************************
* @fn codec_ASRC0_config
*
* @brief Asynchronous Sampling Rate converter Config.
*/
__attribute__((weak)) void codec_ASRC0_config(CODEC_HandleTypeDef *hcodec)
{
__CODEC_ASRC0_BYPASS();
}
/************************************************************************************
* @fn codec_GPF0_config
*
* @brief general purpose filter Config.
*/
__attribute__((weak)) void codec_GPF0_config(CODEC_HandleTypeDef *hcodec)
{
__CODEC_GPF0_BYPASS();
}
/************************************************************************************
* @fn codec_ALC_config
*
* @brief automatic gain control Config.
*/
__attribute__((weak)) void codec_ALC_config(CODEC_HandleTypeDef *hcodec)
{
__CODEC_ALC_BYPASS();
}
/************************************************************************************
* @fn codec_ASRC1_config
*
* @brief Asynchronous Sampling Rate converter Config.
*/
__attribute__((weak)) void codec_ASRC1_config(CODEC_HandleTypeDef *hcodec)
{
__CODEC_ASRC1_BYPASS();
}
/************************************************************************************
* @fn codec_GPF1_config
*
* @brief general purpose filter Config.
*/
__attribute__((weak)) void codec_GPF1_config(CODEC_HandleTypeDef *hcodec)
{
__CODEC_GPF1_BYPASS();
}
/************************************************************************************
* @fn codec_DRC_config
*
* @brief Dynamic Range Control Config.
*/
__attribute__((weak)) void codec_DRC_config(CODEC_HandleTypeDef *hcodec)
{
__CODEC_DRC_BYPASS();
}
/************************************************************************************
* @fn codec_analog_config
*
* @brief analog Config.
*/
__attribute__((weak)) void codec_analog_config(CODEC_HandleTypeDef *hcodec)
{
CODEC->CodecAna0 = CODEC_ANALOG0_CFG;
CODEC->CodecAna1 = CODEC_ANALOG1_CFG;
CODEC->CodecAna2 = CODEC_ANALOG2_CFG;
CODEC->CodecAna3 = CODEC_ANALOG3_CFG;
}
/************************************************************************************
* @fn codec_input_config
*
* @brief Input routing config.
*/
void codec_input_config(CODEC_HandleTypeDef *hcodec)
{
/* Input ADC config */
if (hcodec->Init.Codec_Input_sel == INPUT_SELECT_ADC)
{
/* ADC clock cource */
CODEC->AdcCfg.CLK_SOURCE = hcodec->InputConfig.ADC_ClockSource; /* Default USB 24M */
if (CODEC->AdcCfg.CLK_SOURCE == CODEC_CLOCK_SOURCE_24M_MODE)
CODEC->AdcCfg.USB_MODE = 1;
else
CODEC->AdcCfg.USB_MODE = 0;
/* ADC Over sampling Level */
CODEC->AdcCfg.OV_SAMPLE_MODE = hcodec->InputConfig.ADC_Oversampling_Level;
/* ADC Sample Rate */
CODEC->AdcCfg.SAMPLE_RATE = hcodec->InputConfig.ADC_SampleRate;
/* Clock/Module control */
__CODEC_ADC_CLK_ENABLE();
__CODEC_I2S_RX_CLK_DISABLE();
__CODEC_ADC_RESET();
while(__CODEC_GET_RESET_STATUS() & CODEC_RESET_ADC);
__CODEC_ADC_ENABLE();
__CODEC_I2S_RX_DISABLE();
}
/* Input I2S config */
else
{
/* Master/Slave */
CODEC->I2SRxCtrl.I2S_MODE = hcodec->InputConfig.I2S_RX_Mode;
/* communication standard */
CODEC->I2SRxCtrl.FORMAT = hcodec->InputConfig.I2S_RX_Standard;
/* data format */
CODEC->I2SRxCtrl.DCI_WL = hcodec->InputConfig.I2S_RX_DataFormat;
/* Channel Copy Enable */
CODEC->I2SRxCtrl.CHANNEL_CP = hcodec->InputConfig.I2S_RX_ChannelCopy;
if (hcodec->InputConfig.I2S_RX_Mode == CODEC_I2S_MODE_MASTER)
{
/* frequency */
//hcodec->InputConfig.I2S_TX_AudioFreq;
}
/* Clock/Module control */
__CODEC_ADC_CLK_DISABLE();
__CODEC_I2S_RX_CLK_ENABLE();
__CODEC_ADC_DISABLE();
__CODEC_I2S_RX_ENABLE();
}
/* Input routing config */
switch (hcodec->Init.Codec_Input_Routing_sel)
{
/* IN -> ASRC0 -> GPF0 -> ALC -> ADC_FIFO */
case INPUT_ROUTING_ASRC0_GPF0_ALC_ADCFF:
{
/* Codec rxin */
__CODEC_ASRC0_SOURCE_SELECT(0);
/* ASRC0 out */
__CODEC_GPF0_CH0_SOURCE_SELECT(2);
__CODEC_GPF0_CH1_SOURCE_SELECT(2);
/* Clock control */
__CODEC_ASRC0_CLK_ENABLE();
__CODEC_ASRC0_INPUT_SAMPLE_CLK_ENABLE();
__CODEC_ASRC0_OUTPUT_SAMPLE_CLK_ENABLE();
__CODEC_ASRC0_OUT_LVD_CLK_ENABLE();
__CODEC_GPF0_CLK_ENABLE();
__CODEC_ALC_CLK_ENABLE();
__CODEC_ADCFIFO_CLK_ENABLE();
/* Module control */
__CODEC_ASRC0_ENABLE();
__CODEC_GPF0_ENABLE();
__CODEC_ALC_ENABLE();
codec_ASRC0_config(hcodec);
codec_GPF0_config(hcodec);
codec_ALC_config(hcodec);
}break;
/* IN -> GPF0 -> ALC -> ADC_FIFO */
case INPUT_ROUTING_GPF0_ALC_ADCFF:
{
/* ASRC0 bypass */
__CODEC_ASRC0_BYPASS();
/* Codec rxin */
__CODEC_GPF0_CH0_SOURCE_SELECT(3);
__CODEC_GPF0_CH1_SOURCE_SELECT(3);
/* Clock control */
__CODEC_ASRC0_CLK_DISABLE();
__CODEC_ASRC0_INPUT_SAMPLE_CLK_DISABLE();
__CODEC_ASRC0_OUTPUT_SAMPLE_CLK_DISABLE();
__CODEC_ASRC0_OUT_LVD_CLK_DISABLE();
__CODEC_GPF0_CLK_ENABLE();
__CODEC_ALC_CLK_ENABLE();
__CODEC_ADCFIFO_CLK_ENABLE();
/* Module control */
__CODEC_ASRC0_DISABLE();
__CODEC_GPF0_ENABLE();
__CODEC_ALC_ENABLE();
codec_GPF0_config(hcodec);
codec_ALC_config(hcodec);
}break;
default:break;
}
}
/************************************************************************************
* @fn codec_input_config
*
* @brief output routing config.
*/
void codec_output_config(CODEC_HandleTypeDef *hcodec)
{
/* Output DAC config */
if (hcodec->Init.Codec_Output_sel == OUTPUT_SELECT_DAC)
{
/* ADC clock cource */
CODEC->DacCfg.CLK_SOURCE = hcodec->OutputConfig.DAC_ClockSource; /* Default USB 24M */
if (CODEC->DacCfg.CLK_SOURCE == CODEC_CLOCK_SOURCE_24M_MODE)
CODEC->DacCfg.USB_MODE = 1;
else
CODEC->DacCfg.USB_MODE = 0;
/* DAC Over sampling Level */
CODEC->DacCfg.OV_SAMPLE_MODE = hcodec->OutputConfig.DAC_Oversampling_Level;
/* DAC Sample Rate */
CODEC->DacCfg.SAMPLE_RATE = hcodec->OutputConfig.DAC_SampleRate;
/* Clock control */
__CODEC_DAC_CLK_ENABLE();
__CODEC_I2S_TX_CLK_DISABLE();
__CODEC_DAC_RESET();
while(__CODEC_GET_RESET_STATUS() & CODEC_RESET_DAC);
__CODEC_DAC_ENABLE();
__CODEC_I2S_TX_DISABLE();
}
/* Output I2S config */
else
{
/* Master/Slave */
CODEC->I2STxCtrl.I2S_MODE = hcodec->OutputConfig.I2S_TX_Mode;
/* communication standard */
CODEC->I2STxCtrl.FORMAT = hcodec->OutputConfig.I2S_TX_Standard;
/* data format */
CODEC->I2STxCtrl.DCI_WL = hcodec->OutputConfig.I2S_TX_DataFormat;
/* Channel Copy Enable */
CODEC->I2STxCtrl.CHANNEL_CP = hcodec->OutputConfig.I2S_TX_ChannelCopy;
if (hcodec->OutputConfig.I2S_TX_Mode == CODEC_I2S_MODE_MASTER)
{
/* frequency */
//hcodec->InputConfig.I2S_TX_AudioFreq;
}
/* Clock control */
__CODEC_DAC_CLK_DISABLE();
__CODEC_I2S_TX_CLK_ENABLE();
}
/* Output routing config */
switch (hcodec->Init.Codec_Output_Routing_sel)
{
/* DACFIFO_LR -> ASRC1 -> GPF1 -> DRC -> OUT */
case OUTPUT_ROUTING_DACFFLR_ASRC1_GPF1_DRC:
{
/* TxFIFO_LR */
__CODEC_ASRC1_SOURCE_SELECT(1);
/* ASRC1 out */
__CODEC_GPF1_CH0_SOURCE_SELECT(3);
__CODEC_GPF1_CH1_SOURCE_SELECT(3);
/* Clock control */
__CODEC_ASRC1_CLK_ENABLE();
__CODEC_ASRC1_INPUT_SAMPLE_CLK_ENABLE();
__CODEC_ASRC1_OUTPUT_SAMPLE_CLK_ENABLE();
__CODEC_ASRC1_OUT_LVD_CLK_ENABLE();
__CODEC_GPF1_CLK_ENABLE();
__CODEC_DRC_CLK_ENABLE();
__CODEC_DACFIFO_LR_CLK_ENABLE();
__CODEC_DACFIFO_01_CLK_DISABLE();
/* Module control */
__CODEC_DAC_FIFO_LR_ENABLE();
__CODEC_DAC_FIFO_01_DISABLE();
__CODEC_ASRC1_ENABLE();
__CODEC_GPF1_ENABLE();
__CODEC_DRC_ENABLE();
codec_ASRC1_config(hcodec);
codec_GPF1_config(hcodec);
codec_DRC_config(hcodec);
}break;
/* DACFIFO_LR -> GPF1 -> DRC -> OUT */
case OUTPUT_ROUTING_DACFFLR_GPF1_DRC:
{
/* ASRC1 bypass */
__CODEC_ASRC1_BYPASS();
/* TxFIFO_LR*/
__CODEC_GPF1_CH0_SOURCE_SELECT(1);
__CODEC_GPF1_CH1_SOURCE_SELECT(1);
/* Clock control */
__CODEC_ASRC1_CLK_DISABLE();
__CODEC_ASRC1_INPUT_SAMPLE_CLK_DISABLE();
__CODEC_ASRC1_OUTPUT_SAMPLE_CLK_DISABLE();
__CODEC_ASRC1_OUT_LVD_CLK_DISABLE();
__CODEC_GPF1_CLK_ENABLE();
__CODEC_DRC_CLK_ENABLE();
__CODEC_DACFIFO_LR_CLK_ENABLE();
__CODEC_DACFIFO_01_CLK_DISABLE();
/* Module control */
__CODEC_DAC_FIFO_LR_ENABLE();
__CODEC_DAC_FIFO_01_DISABLE();
__CODEC_ASRC1_DISABLE();
__CODEC_GPF1_ENABLE();
__CODEC_DRC_ENABLE();
codec_GPF1_config(hcodec);
codec_DRC_config(hcodec);
}break;
/* DACFIFO_LR & DACFIFO_01 -> ASRC1 -> GPF1 -> DRC -> OUT */
case OUTPUT_ROUTING_DACFFLR_DACFF01_ASRC1_GPF1_DRC:
{
/* TxFIFO_01 */
__CODEC_ASRC1_SOURCE_SELECT(2);
/* TxFIFO_LR*/
__CODEC_GPF1_CH0_SOURCE_SELECT(1);
/* ASRC1 out */
__CODEC_GPF1_CH1_SOURCE_SELECT(3);
/* Clock control */
__CODEC_ASRC1_CLK_ENABLE();
__CODEC_ASRC1_INPUT_SAMPLE_CLK_ENABLE();
__CODEC_ASRC1_OUTPUT_SAMPLE_CLK_ENABLE();
__CODEC_ASRC1_OUT_LVD_CLK_ENABLE();
__CODEC_GPF1_CLK_ENABLE();
__CODEC_DRC_CLK_ENABLE();
__CODEC_DACFIFO_LR_CLK_ENABLE();
__CODEC_DACFIFO_01_CLK_ENABLE();
/* Module control */
__CODEC_DAC_FIFO_LR_ENABLE();
__CODEC_DAC_FIFO_01_ENABLE();
__CODEC_ASRC1_ENABLE();
__CODEC_GPF1_ENABLE();
__CODEC_DRC_ENABLE();
codec_ASRC1_config(hcodec);
codec_GPF1_config(hcodec);
codec_DRC_config(hcodec);
}break;
/* DACFIFO_LR & DACFIFO_01 -> GPF1 -> DRC -> OUT */
case OUTPUT_ROUTING_DACFFLR_DACFF01_GPF1_DRC:
{
/* ASRC1 bypass */
__CODEC_ASRC1_BYPASS();
/* TxFIFO_LR*/
__CODEC_GPF1_CH0_SOURCE_SELECT(1);
/* TxFIFO_01 */
__CODEC_GPF1_CH1_SOURCE_SELECT(0);
/* Clock control */
__CODEC_ASRC1_CLK_DISABLE();
__CODEC_ASRC1_INPUT_SAMPLE_CLK_DISABLE();
__CODEC_ASRC1_OUTPUT_SAMPLE_CLK_DISABLE();
__CODEC_ASRC1_OUT_LVD_CLK_DISABLE();
__CODEC_GPF1_CLK_ENABLE();
__CODEC_DRC_CLK_ENABLE();
__CODEC_DACFIFO_LR_CLK_ENABLE();
__CODEC_DACFIFO_01_CLK_ENABLE();
/* Module control */
__CODEC_DAC_FIFO_LR_ENABLE();
__CODEC_DAC_FIFO_01_ENABLE();
__CODEC_ASRC1_DISABLE();
__CODEC_GPF1_ENABLE();
__CODEC_DRC_ENABLE();
codec_GPF1_config(hcodec);
codec_DRC_config(hcodec);
}break;
default:break;
}
}
/************************************************************************************
* @fn codec_init
*
* @brief Initialize the Codec according to the specified parameters.
*
* @param hcodec: Codec handle.
*/
void codec_init(CODEC_HandleTypeDef *hcodec)
{
/* FIFO Data Format */
CODEC->FFRoute.ADCFF_L_SRC = 0;
CODEC->FFRoute.ADCFF_R_SRC = 0;
CODEC->FFRoute.ADCFF_BITWD = hcodec->Init.ADC_DataFormat;
CODEC->FFRoute.DACFF_LR_BITWD = hcodec->Init.DAC_LR_DataFormat;
CODEC->FFRoute.DACFF_01_BITWD = hcodec->Init.DAC_01_DataFormat;
/* Analog config */
codec_analog_config(hcodec);
/* Input routing config */
if (hcodec->Init.Codec_Input_sel < INPUT_SELECT_BYPASS)
{
/* Input select */
CODEC->CodecRoute.ADC_SEL = hcodec->Init.Codec_Input_sel;
codec_input_config(hcodec);
}
/* Output routing config */
if (hcodec->Init.Codec_Output_sel < OUTPUT_SELECT_BYPASS)
{
/* Output select */
CODEC->CodecRoute.DAC_SEL = hcodec->Init.Codec_Output_sel;
codec_output_config(hcodec);
}
/* MCLK Out config */
if (hcodec->Init.Codec_Input_sel == INPUT_SELECT_I2S_RX || \
hcodec->Init.Codec_Output_sel == OUTPUT_SELECT_I2S_TX)
{
if (hcodec->MCLKConfig.MCLK_Out_Enable == MCLK_OUT_ENABLE)
{
CODEC->MCLKCfg.EN = MCLK_OUT_ENABLE;
CODEC->MCLKCfg.MCLK_SRC = hcodec->MCLKConfig.MCLK_Source;
CODEC->MCLKCfg.DIV_TYPE = hcodec->MCLKConfig.MCLK_DIV_Mode;
CODEC->MCLKCfg.DIV = hcodec->MCLKConfig.MCLK_DIV;
}
}
}
/************************************************************************************
* @fn codec_deinit
*
* @brief Close the Codec.
*
* @param hcodec: Codec handle.
*/
void codec_deinit(CODEC_HandleTypeDef *hcodec)
{
__CODEC_ALL_MODULE_RESET();
__CODEC_ALL_DISABLE();
__SYSTEM_CODEC_RESET();
}
/************************************************************************************
* @fn codec_Set_ADC_Volume
*
* @brief Set ADC Volume.
*
* @param fu32_Volume: volume = 20*lg(fu32_Volume/2^13)
*/
void codec_Set_ADC_Volume(uint32_t fu32_Volume)
{
CODEC->AdcVolume.VOLUME = fu32_Volume;
}
/************************************************************************************
* @fn codec_Set_DAC_Volume
*
* @brief Set DAC Volume.
*
* @param fu32_Volume: volume = 20*lg(fu32_Volume/2^13)
*/
void codec_Set_DAC_Volume(uint32_t fu32_Volume)
{
CODEC->DacVolume.VOLUME = fu32_Volume;
}
/************************************************************************************
* @fn codec_int_enable
*
* @brief Codec interrupt enable.
*
* @param fe_Int_Status: interrupt source select
*/
void codec_int_enable(enum_Codec_INT_Status_t fe_Int_Status)
{
CODEC->CodecIntEn.STATUS |= fe_Int_Status;
}
/************************************************************************************
* @fn codec_int_enable
*
* @brief Codec interrupt enable.
*
* @param fe_Int_Status: interrupt source select
*/
void codec_int_disable(enum_Codec_INT_Status_t fe_Int_Status)
{
CODEC->CodecIntEn.STATUS &= ~fe_Int_Status;
}
/************************************************************************************
* @fn codec_init_clear
*
* @brief Codec interrupt enable.
*
* @param fe_Int_Status: interrupt source select
*/
void codec_init_clear(enum_Codec_INT_Status_t fe_Int_Status)
{
CODEC->CodecIntClear.STATUS |= fe_Int_Status;
}
/************************************************************************************
* @fn codec_read_adc_fifo_left/
* codec_read_adc_fifo_right/
* codec_read_adc_fifo_left_right/
*
* @brief Codec read ADC fifo.
*
* @param fp_buffer: codec ADC data buffer.
* @param fu32_size: read data length.
*/
void codec_read_adc_fifo_left(void *fp_buffer, uint32_t fu32_length)
{
union_DataFormat_t Data;
switch (CODEC->FFRoute.ADCFF_BITWD)
{
case CODEC_FIFO_FORMAT_8BIT:
{
Data.p_u8 = fp_buffer;
while(fu32_length--)
*Data.p_u8++ = (uint8_t)CODEC->ADCDataL;
}break;
case CODEC_FIFO_FORMAT_16BIT:
{
Data.p_u16 = fp_buffer;
while(fu32_length--)
*Data.p_u16++ = (uint16_t)CODEC->ADCDataL;
}break;
case CODEC_FIFO_FORMAT_24BIT:
{
Data.p_u32 = fp_buffer;
while(fu32_length--)
*Data.p_u32++ = CODEC->ADCDataL;
}break;
default:break;
}
}
void codec_read_adc_fifo_right(void *fp_buffer, uint32_t fu32_length)
{
union_DataFormat_t Data;
switch (CODEC->FFRoute.ADCFF_BITWD)
{
case CODEC_FIFO_FORMAT_8BIT:
{
Data.p_u8 = fp_buffer;
while(fu32_length--)
*Data.p_u8++ = (uint8_t)CODEC->ADCDataR;
}break;
case CODEC_FIFO_FORMAT_16BIT:
{
Data.p_u16 = fp_buffer;
while(fu32_length--)
*Data.p_u16++ = (uint16_t)CODEC->ADCDataR;
}break;
case CODEC_FIFO_FORMAT_24BIT:
{
Data.p_u32 = fp_buffer;
while(fu32_length--)
*Data.p_u32++ = CODEC->ADCDataR;
}break;
default:break;
}
}
void codec_read_adc_fifo_left_right(void *fp_buffer, uint32_t fu32_length)
{
union_DataFormat_t Data;
switch (CODEC->FFRoute.ADCFF_BITWD)
{
case CODEC_FIFO_FORMAT_8BIT:
{
Data.p_u8 = fp_buffer;
while(fu32_length--){
*Data.p_u8++ = (uint8_t)CODEC->ADCDataL;
*Data.p_u8++ = (uint8_t)CODEC->ADCDataR;
}
}break;
case CODEC_FIFO_FORMAT_16BIT:
{
Data.p_u16 = fp_buffer;
while(fu32_length--){
*Data.p_u16++ = (uint16_t)CODEC->ADCDataL;
*Data.p_u16++ = (uint16_t)CODEC->ADCDataR;
}
}break;
case CODEC_FIFO_FORMAT_24BIT:
{
Data.p_u32 = fp_buffer;
while(fu32_length--){
*Data.p_u32++ = CODEC->ADCDataL;
*Data.p_u32++ = CODEC->ADCDataR;
}
}break;
default:break;
}
}
/************************************************************************************
* @fn codec_write_dac_fifo_left/
* codec_write_dac_fifo_right/
* codec_write_dac_fifo_left_right/
*
* @brief Codec write dac fifo LR.
*
* @param fp_buffer: codec dac data buffer.
* @param fu32_size: read data length.
*/
void codec_write_dac_fifo_left(void *fp_buffer, uint32_t fu32_length)
{
union_DataFormat_t Data;
switch (CODEC->FFRoute.DACFF_LR_BITWD)
{
case CODEC_FIFO_FORMAT_8BIT:
{
Data.p_u8 = fp_buffer;
while(fu32_length--)
CODEC->DACLRDataL = *Data.p_u8++;
}break;
case CODEC_FIFO_FORMAT_16BIT:
{
Data.p_u16 = fp_buffer;
while(fu32_length--)
CODEC->DACLRDataL = *Data.p_u16++;
}break;
case CODEC_FIFO_FORMAT_24BIT:
{
Data.p_u32 = fp_buffer;
while(fu32_length--)
CODEC->DACLRDataL = *Data.p_u32++;
}break;
default:break;
}
}
void codec_write_dac_fifo_right(void *fp_buffer, uint32_t fu32_length)
{
union_DataFormat_t Data;
switch (CODEC->FFRoute.DACFF_LR_BITWD)
{
case CODEC_FIFO_FORMAT_8BIT:
{
Data.p_u8 = fp_buffer;
while(fu32_length--)
CODEC->DACLRDataR = *Data.p_u8++;
}break;
case CODEC_FIFO_FORMAT_16BIT:
{
Data.p_u16 = fp_buffer;
while(fu32_length--)
CODEC->DACLRDataR = *Data.p_u16++;
}break;
case CODEC_FIFO_FORMAT_24BIT:
{
Data.p_u32 = fp_buffer;
while(fu32_length--)
CODEC->DACLRDataR = *Data.p_u32++;
}break;
default:break;
}
}
void codec_write_dac_fifo_left_right(void *fp_buffer, uint32_t fu32_length)
{
union_DataFormat_t Data;
switch (CODEC->FFRoute.DACFF_LR_BITWD)
{
case CODEC_FIFO_FORMAT_8BIT:
{
Data.p_u8 = fp_buffer;
while(fu32_length--){
CODEC->DACLRDataL = *Data.p_u8++;
CODEC->DACLRDataR = *Data.p_u8++;
}
}break;
case CODEC_FIFO_FORMAT_16BIT:
{
Data.p_u16 = fp_buffer;
while(fu32_length--){
CODEC->DACLRDataL = *Data.p_u16++;
CODEC->DACLRDataR = *Data.p_u16++;
}
}break;
case CODEC_FIFO_FORMAT_24BIT:
{
Data.p_u32 = fp_buffer;
while(fu32_length--){
CODEC->DACLRDataL = *Data.p_u32++;
CODEC->DACLRDataR = *Data.p_u32++;
}
}break;
default:break;
}
}
/************************************************************************************
* @fn codec_write_dac_fifo_0/
* codec_write_dac_fifo_1/
* codec_write_dac_fifo_01/
*
* @brief Codec write dac fifo 01.
*
* @param fp_buffer: codec DAC data buffer.
* @param fu32_size: read data length.
*/
void codec_write_dac_fifo_0(void *fp_buffer, uint32_t fu32_length)
{
union_DataFormat_t Data;
switch (CODEC->FFRoute.DACFF_01_BITWD)
{
case CODEC_FIFO_FORMAT_8BIT:
{
Data.p_u8 = fp_buffer;
while(fu32_length--)
CODEC->DAC01DataL = *Data.p_u8++;
}break;
case CODEC_FIFO_FORMAT_16BIT:
{
Data.p_u16 = fp_buffer;
while(fu32_length--)
CODEC->DAC01DataL = *Data.p_u16++;
}break;
case CODEC_FIFO_FORMAT_24BIT:
{
Data.p_u32 = fp_buffer;
while(fu32_length--)
CODEC->DAC01DataL = *Data.p_u32++;
}break;
default:break;
}
}
void codec_write_dac_fifo_1(void *fp_buffer, uint32_t fu32_length)
{
union_DataFormat_t Data;
switch (CODEC->FFRoute.DACFF_01_BITWD)
{
case CODEC_FIFO_FORMAT_8BIT:
{
Data.p_u8 = fp_buffer;
while(fu32_length--)
CODEC->DAC01DataR = *Data.p_u8++;
}break;
case CODEC_FIFO_FORMAT_16BIT:
{
Data.p_u16 = fp_buffer;
while(fu32_length--)
CODEC->DAC01DataR = *Data.p_u16++;
}break;
case CODEC_FIFO_FORMAT_24BIT:
{
Data.p_u32 = fp_buffer;
while(fu32_length--)
CODEC->DAC01DataR = *Data.p_u32++;
}break;
default:break;
}
}
void codec_write_dac_fifo_01(void *fp_buffer, uint32_t fu32_length)
{
union_DataFormat_t Data;
switch (CODEC->FFRoute.DACFF_01_BITWD)
{
case CODEC_FIFO_FORMAT_8BIT:
{
Data.p_u8 = fp_buffer;
while(fu32_length--){
CODEC->DAC01DataL = *Data.p_u8++;
CODEC->DAC01DataR = *Data.p_u8++;
}
}break;
case CODEC_FIFO_FORMAT_16BIT:
{
Data.p_u16 = fp_buffer;
while(fu32_length--){
CODEC->DAC01DataL = *Data.p_u16++;
CODEC->DAC01DataR = *Data.p_u16++;
}
}break;
case CODEC_FIFO_FORMAT_24BIT:
{
Data.p_u32 = fp_buffer;
while(fu32_length--){
CODEC->DAC01DataL = *Data.p_u32++;
CODEC->DAC01DataR = *Data.p_u32++;
}
}break;
default:break;
}
}
/************************************************************************************
* @fn codec_get_int_status
*
* @brief get Codec interrupt status.
*/
enum_Codec_INT_Status_t codec_get_int_status(void)
{
return CODEC->CodecIntRawStatus.STATUS;
}
/************************************************************************************
* @fn codec_mute_output
*
* @brief codec mute output enable/disable.
*
* @param fb_mute: true: mute.
*/
void codec_mute_output(bool fb_mute)
{
CODEC->Enable.CDC_TXOUT = fb_mute;
}

View File

@ -0,0 +1,53 @@
/*
******************************************************************************
* @file driver_crc.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2023
* @brief CRC module driver.
* This file provides firmware functions to manage the
* CRC(Cyclic Redundancy Check) peripheral
******************************************************************************
* @attention
*
* Copyright (c) 2023 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
/************************************************************************************
* @fn crc_init
*
* @brief Initial crc according to the mode
*
* @param fe_crc_mode: crc mode.
*/
void crc_init(enum_CRC_MODE_SEL_t fe_crc_mode)
{
/* CRC control config */
CRC->CRC_CTRL = fe_crc_mode | CRC_START;
}
/************************************************************************************
* @fn crc_Calculate
*
* @brief Calculate CRC from the input data.
*
* @param fp_Data: Input calculated data.
* @param fu32_size: The data size need to do crc.
*/
uint32_t crc_Calculate(uint8_t *fp_Data, uint32_t fu32_size)
{
if (fu32_size == 0)
{
return 0;
}
while(fu32_size--)
{
CRC->CRC_FIFO_DATA = *(fp_Data++);
}
return CRC->CRC_RESULT;
}

View File

@ -0,0 +1,394 @@
/*
******************************************************************************
* @file driver_dma.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief DMA module driver.
* This file provides firmware functions to manage the
* Direct Memory Access (DMA) peripheral
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
/*********************************************************************
* @fn dma_init
*
* @brief Initialize the DMA according to the specified parameters
* in the dma_InitParameter_t
*
* @param hdma : pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for DMA module
*
* @return None.
*/
void dma_init(DMA_HandleTypeDef *hdma)
{
struct_DMA_t *DMA = hdma->DMAx;
/* FIFO_MODE_1 */
DMA->Channels[hdma->Channel].CFG2.FIFO_MODE = 1;
/* Clear Linked List Pointer Register */
DMA->Channels[hdma->Channel].LLP.LOC = 0;
DMA->Channels[hdma->Channel].LLP.LMS = 0;
/* Interrupt Enable */
DMA->Channels[hdma->Channel].CTL1.INT_EN = 1;
/* Bus Master Selection */
DMA->Channels[hdma->Channel].CTL1.SMS = hdma->Init.Source_Master_Sel;
DMA->Channels[hdma->Channel].CTL1.DMS = hdma->Init.Desination_Master_Sel;
/* Transfer Width */
DMA->Channels[hdma->Channel].CTL1.SRC_TR_WIDTH = hdma->Init.Source_Width;
DMA->Channels[hdma->Channel].CTL1.DST_TR_WIDTH = hdma->Init.Desination_Width;
/* Burst Length */
DMA->Channels[hdma->Channel].CTL1.DEST_MSIZE = hdma->Init.Desination_Burst_Len;
DMA->Channels[hdma->Channel].CTL1.SRC_MSIZE = hdma->Init.Source_Burst_Len;
/* Address Increment */
DMA->Channels[hdma->Channel].CTL1.SINC = hdma->Init.Source_Inc;
DMA->Channels[hdma->Channel].CTL1.DINC = hdma->Init.Desination_Inc;
/* DMA Data Flow */
DMA->Channels[hdma->Channel].CTL1.TT_FC = hdma->Init.Data_Flow;
/* Set Peripheral Request ID */
if (hdma->Init.Data_Flow == DMA_M2P_DMAC)
{
DMA->Channels[hdma->Channel].CFG2.DEST_PER = hdma->Init.Request_ID;
}
else if (hdma->Init.Data_Flow == DMA_P2M_DMAC)
{
DMA->Channels[hdma->Channel].CFG2.SRC_PER = hdma->Init.Request_ID;
}
/* Hardware handshaking interface */
DMA->Channels[hdma->Channel].CFG1.HS_SEL_SRC = 0;
DMA->Channels[hdma->Channel].CFG1.HS_SEL_DST = 0;
/* AHB dmac Enabled */
DMA->Misc_Reg.DmaCfgReg.DMA_EN = 1;
}
/*********************************************************************
* @fn dma_start
*
* @brief DMA transfer start.
*
* @param hdma : pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for DMA module
* SrcAddr: source address
* DstAddr: desination address
* Size: transfer size (This parameter can be a 12-bit Size)
* @return None.
*/
void dma_start(DMA_HandleTypeDef *hdma, uint32_t SrcAddr, uint32_t DstAddr, uint32_t Size)
{
struct_DMA_t *DMA = hdma->DMAx;
/* Set source address and desination address */
DMA->Channels[hdma->Channel].SAR = SrcAddr;
DMA->Channels[hdma->Channel].DAR = DstAddr;
/* Set Transfer Size */
DMA->Channels[hdma->Channel].CTL2.BLOCK_TS = Size;
/* Enable the channel */
DMA->Misc_Reg.ChEnReg |= (1 << hdma->Channel | (1 << (hdma->Channel + 8)));
}
/*********************************************************************
* @fn dma_start_IT
*
* @brief DMA transfer start and enable interrupt
*
* @param hdma : pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for DMA module
* SrcAddr: source address
* DstAddr: desination address
* Size: transfer size (This parameter can be a 12-bit Size)
* @return None.
*/
void dma_start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddr, uint32_t DstAddr, uint32_t Size)
{
struct_DMA_t *DMA = hdma->DMAx;
/* Set source address and desination address */
DMA->Channels[hdma->Channel].SAR = SrcAddr;
DMA->Channels[hdma->Channel].DAR = DstAddr;
/* Set Transfer Size */
DMA->Channels[hdma->Channel].CTL2.BLOCK_TS = Size;
/* Clear Transfer complete status */
dma_clear_tfr_Status(hdma);
/* channel Transfer complete interrupt enable */
dma_tfr_interrupt_enable(hdma);
/* Enable the channel */
DMA->Misc_Reg.ChEnReg |= (1 << hdma->Channel | (1 << (hdma->Channel + 8)));
}
/*********************************************************************
* @fn dma_linked_list_init
*
* @brief Initialize the linked list parameters
*
* @param link : The list structure that needs to be initialized
* param: Initialization parameter
* @return None
*/
void dma_linked_list_init(DMA_LLI_InitTypeDef *link, dma_LinkParameter_t *param)
{
link->SrcAddr = param->SrcAddr;
link->DstAddr = param->DstAddr;
link->Next = (DMA_LLI_InitTypeDef *)param->NextLink;
link->CTL1.INT_EN = 1;
link->CTL1.SRC_TR_WIDTH = param->Source_Width;
link->CTL1.DST_TR_WIDTH = param->Desination_Width;
link->CTL1.SMS = param->Source_Master_Sel;
link->CTL1.DMS = param->Desination_Master_Sel;
link->CTL1.SINC = param->Source_Inc;
link->CTL1.DINC = param->Desination_Inc;
link->CTL1.TT_FC = param->Data_Flow;
link->CTL1.DEST_MSIZE = param->Desination_Burst_Len;
link->CTL1.SRC_MSIZE = param->Source_Burst_Len;
link->CTL1.SRC_GATHER_EN = param->gather_enable;
link->CTL1.DST_SCATTER_EN = param->scatter_enable;
link->CTL2.BLOCK_TS = param->Size;
/* Block chaining using Linked List is enabled on the Source side */
/* Block chaining using Linked List is enabled on the Destination side */
link->CTL1.LLP_DST_EN = 1;
link->CTL1.LLP_SRC_EN = 1;
}
/*********************************************************************
* @fn dma_linked_list_start.
*
* @brief DMA linked list transfer start.
*
* @param link : The first address of the linked list
* param : Initialization parameter
* hdma : DMA handle
*
* @return None
*/
void dma_linked_list_start(DMA_HandleTypeDef *hdma, DMA_LLI_InitTypeDef *link, dma_LinkParameter_t *param)
{
struct_DMA_t *DMA = hdma->DMAx;
uint32_t Channel = hdma->Channel;
/* Set Peripheral Request ID */
if (link->CTL1.TT_FC == DMA_M2P_DMAC)
{
DMA->Channels[Channel].CFG2.DEST_PER = param->Request_ID;
}
else if (link->CTL1.TT_FC == DMA_P2M_DMAC)
{
DMA->Channels[Channel].CFG2.SRC_PER = param->Request_ID;
}
/* Hardware handshaking interface */
DMA->Channels[Channel].CFG1.HS_SEL_SRC = 0;
DMA->Channels[Channel].CFG1.HS_SEL_DST = 0;
/* Block chaining using Linked List is enabled on the Source side */
/* Block chaining using Linked List is enabled on the Destination side */
DMA->Channels[Channel].CTL1.LLP_DST_EN = link->CTL1.LLP_DST_EN;
DMA->Channels[Channel].CTL1.LLP_SRC_EN = link->CTL1.LLP_SRC_EN;
DMA->Channels[Channel].LLP.LOC = ((uint32_t)link) >> 2;
/* AHB dmac Enabled */
DMA->Misc_Reg.DmaCfgReg.DMA_EN = 1;
DMA->Misc_Reg.ChEnReg |= (1 << Channel | (1 << (Channel + 8)));
}
/*********************************************************************
* @fn dma_linked_list_start_IT
*
* @brief DMA linked list transfer start and enable interrupt
*
* @param link : The first address of the linked list
* param : Initialization parameter
* hdma : DMA handle
*
* @return None
*/
void dma_linked_list_start_IT(DMA_HandleTypeDef *hdma, DMA_LLI_InitTypeDef *link, dma_LinkParameter_t *param)
{
struct_DMA_t *DMA = hdma->DMAx;
uint32_t Channel = hdma->Channel;
/* Set Peripheral Request ID */
if (link->CTL1.TT_FC == DMA_M2P_DMAC)
{
DMA->Channels[Channel].CFG2.DEST_PER = param->Request_ID;
}
else if (link->CTL1.TT_FC == DMA_P2M_DMAC)
{
DMA->Channels[Channel].CFG2.SRC_PER = param->Request_ID;
}
/* Hardware handshaking interface */
DMA->Channels[Channel].CFG1.HS_SEL_SRC = 0;
DMA->Channels[Channel].CFG1.HS_SEL_DST = 0;
DMA->Channels[Channel].CTL1.LLP_DST_EN = link->CTL1.LLP_DST_EN;
DMA->Channels[Channel].CTL1.LLP_SRC_EN = link->CTL1.LLP_SRC_EN;
DMA->Channels[Channel].LLP.LOC = ((uint32_t)link) >> 2;
/* Clear Transfer complete status */
dma_clear_tfr_Status(hdma);
/* channel Transfer complete interrupt enable */
dma_tfr_interrupt_enable(hdma);
/* AHB dmac Enabled */
DMA->Misc_Reg.DmaCfgReg.DMA_EN = 1;
DMA->Misc_Reg.ChEnReg |= (1 << Channel | (1 << (Channel + 8)));
}
/*********************************************************************
* @fn dma_tfr_interrupt_enable
*
* @brief channel transfer complete interrupt enable
*
* @param hdma : DMA handle
*
* @return None
*/
void dma_tfr_interrupt_enable(DMA_HandleTypeDef *hdma)
{
hdma->DMAx->Int_Reg.MaskTfr = (1 << (hdma->Channel)) | (1 << ((hdma->Channel) + 8));
}
/*********************************************************************
* @fn dma_tfr_interrupt_disable
*
* @brief channel transfer complete interrupt disable
*
* @param hdma : DMA handle
*
* @return None
*/
void dma_tfr_interrupt_disable(DMA_HandleTypeDef *hdma)
{
hdma->DMAx->Int_Reg.MaskTfr = (1 << ((hdma->Channel) + 8));
}
/*********************************************************************
* @fn dma_get_tfr_Status
*
* @brief Get channel transfer complete status
*
* @param hdma : DMA handle
*
* @return true: channel Transfer complete
* false: Not
*/
bool dma_get_tfr_Status(DMA_HandleTypeDef *hdma)
{
/* Check channel Transfer complete */
if (hdma->DMAx->Int_Reg.RawTfr & (1 << (hdma->Channel)))
{
return true;
}
else
{
return false;
}
}
/*********************************************************************
* @fn dma_clear_tfr_Status
*
* @brief clear channel transfer complete status
*
* @param hdma : DMA handle
*
* @return None
*/
void dma_clear_tfr_Status(DMA_HandleTypeDef *hdma)
{
/* Clear channel Transfer complete Status */
hdma->DMAx->Int_Reg.ClearTfr = 1 << (hdma->Channel);
}
/*********************************************************************
* @fn dma_tfr_interrupt_enable
*
* @brief channel transfer complete interrupt enable
*
* @param hdma : DMA handle
*
* @return None
*/
void dma_error_interrupt_enable(DMA_HandleTypeDef *hdma)
{
hdma->DMAx->Int_Reg.MaskErr = (1 << (hdma->Channel)) | (1 << ((hdma->Channel) + 8));
}
/*********************************************************************
* @fn dma_tfr_interrupt_disable
*
* @brief channel transfer complete interrupt disable
*
* @param hdma : DMA handle
*
* @return None
*/
void dma_error_interrupt_disable(DMA_HandleTypeDef *hdma)
{
hdma->DMAx->Int_Reg.MaskErr = (1 << ((hdma->Channel) + 8));
}
/*********************************************************************
* @fn dma_get_tfr_Status
*
* @brief Get channel transfer complete status
*
* @param hdma : DMA handle
*
* @return true: channel Transfer complete
* false: Not
*/
bool dma_get_error_Status(DMA_HandleTypeDef *hdma)
{
/* Check channel Transfer complete */
if (hdma->DMAx->Int_Reg.RawErr & (1 << (hdma->Channel)))
{
return true;
}
else
{
return false;
}
}
/*********************************************************************
* @fn dma_clear_tfr_Status
*
* @brief clear channel transfer complete status
*
* @param hdma : DMA handle
*
* @return None
*/
void dma_clear_error_Status(DMA_HandleTypeDef *hdma)
{
/* Clear channel Transfer complete Status */
hdma->DMAx->Int_Reg.ClearErr = 1 << (hdma->Channel);
}

View File

@ -0,0 +1,105 @@
/*
******************************************************************************
* @file driver_efuse.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief eFuse module driver.
* This file provides firmware functions to manage the eFuse.
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
/************************************************************************************
* @fn eFuse_siso_read
*
* @brief read eFuse data.
*
* @param fp_Data: read data buffer.
*/
void eFuse_siso_read(uint32_t *fp_Data)
{
/* config read mode */
EFUSE_SISO->eFuse_Ctrl = EFUSE_SISO_READ_MODE;
/* wait config done */
while(!(EFUSE_SISO->eFuse_Ctrl & EFUSE_SISO_CHECK_DONE));
EFUSE_SISO->eFuse_Ctrl |= EFUSE_SISO_CHECK_DONE;
/* read data */
fp_Data[0] = EFUSE_SISO->eFuse_Data0;
fp_Data[1] = EFUSE_SISO->eFuse_Data1;
fp_Data[2] = EFUSE_SISO->eFuse_Data2;
}
/************************************************************************************
* @fn eFuse_siso_write
*
* @brief write eFuse data.
*
* @param fp_Data: write data buffer.
*/
void eFuse_siso_write(uint32_t *fp_Data)
{
/* write data */
EFUSE_SISO->eFuse_Data0 = fp_Data[0];
EFUSE_SISO->eFuse_Data1 = fp_Data[1];
EFUSE_SISO->eFuse_Data2 = fp_Data[2];
/* config write mode */
EFUSE_SISO->eFuse_Ctrl = EFUSE_SISO_WRITE_MODE;
/* wait config done */
while(!(EFUSE_SISO->eFuse_Ctrl & EFUSE_SISO_CHECK_DONE));
EFUSE_SISO->eFuse_Ctrl |= EFUSE_SISO_CHECK_DONE;
}
/************************************************************************************
* @fn eFuse_pipo_read
*
* @brief read eFuse data.
*
* @param fu8_Addr: efuse address, unit byte, range 0x00 ~ 0xFF;
* @param fp_Data: read data buffer.
*/
void eFuse_pipo_read(uint8_t fu8_Addr, uint8_t *fp_Data)
{
EFUSE_PIPO->eFuse_Addr = fu8_Addr;
/* config read mode */
EFUSE_PIPO->eFuse_Ctrl = EFUSE_PIPO_GO | EFUSE_PIPO_READ_MODE;
/* wait config done */
while(!(EFUSE_PIPO->eFuse_Ctrl & EFUSE_PIPO_CHECK_DONE));
EFUSE_PIPO->eFuse_Ctrl |= EFUSE_PIPO_WRITE_MODE;
EFUSE_PIPO->eFuse_Ctrl = 0x00;
fp_Data[0] = EFUSE_PIPO->eFuse_RData;
EFUSE_PIPO->eFuse_Ctrl &= ~EFUSE_PIPO_READ_MODE;
}
/************************************************************************************
* @fn eFuse_pipo_write
*
* @brief write eFuse data.
*
* @param fu8_Addr: efuse address, unit byte, range 0x00 ~ 0xFF;
* @param fp_Data: write data value.
*/
void eFuse_pipo_write(uint8_t fu8_Addr, uint8_t fu8_Data)
{
EFUSE_PIPO->eFuse_Ctrl = EFUSE_PIPO_AVDDEN;
EFUSE_PIPO->eFuse_Addr = fu8_Addr;
EFUSE_PIPO->eFuse_WData = fu8_Data;
/* config write mode */
EFUSE_PIPO->eFuse_Ctrl = EFUSE_PIPO_GO | EFUSE_PIPO_WRITE_MODE | EFUSE_PIPO_AVDDEN;
/* wait config done */
while(!(EFUSE_PIPO->eFuse_Ctrl & EFUSE_PIPO_CHECK_DONE));
EFUSE_PIPO->eFuse_Ctrl |= EFUSE_PIPO_WRITE_MODE;
EFUSE_PIPO->eFuse_Ctrl = 0x00;
}

View File

@ -0,0 +1,156 @@
/*
******************************************************************************
* @file driver_fft.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2022
* @brief FFT module driver.
* This file provides firmware functions to manage the
* FFT (Fast Fourier Transform) peripheral.
******************************************************************************
* @attention
*
* Copyright (c) 2022 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
/************************************************************************************
* @fn fft_IRQHandler
*
* @brief fft interrupt handler
*
* @param hfft: FFT_HandleTypeDef.
*/
void fft_IRQHandler(FFT_HandleTypeDef *hfft)
{
int i;
/* clear int status */
__FFT_INT_STATUS_CLEAR();
/* Data OUT */
for (i = 0; i < hfft->BlockSize; i++)
hfft->DataOut[hfft->DataOutIndex++] = FFT->FFT_ACCESSRAM;
if (hfft->BlockCNT)
{
hfft->BlockCNT--;
/* Data IN */
for (i = 0; i < hfft->BlockSize; i++)
FFT->FFT_ACCESSRAM = hfft->DataIn[hfft->DataIndex++];
}
else
{
__FFT_INT_DISALE();
hfft->FFT_Busy = false;
}
}
/************************************************************************************
* @fn FFT_init
*
* @brief initialize the FFT module.
*
* @param hfft: FFT_HandleTypeDef.
*/
void fft_init(FFT_HandleTypeDef *hfft)
{
/* FFT calculate Mod */
FFT->FFT_CTRL.Bits.MODE_SEL = hfft->FFT_Init.FFT_Cal_Mode;
/* FFT Samples number */
FFT->FFT_CTRL.Bits.NP_SEL = hfft->FFT_Init.FFT_Samples;
/* default DMA enable */
__FFT_DMA_ENABLE();
}
/************************************************************************************
* @fn FFT_start
*
* @brief start fft calculate.
*
* @param hfft: FFT_HandleTypeDef.
* @param fp_Data_In: the pointer of input data.
* @param fp_Data_Out: the pointer of output data.
* @param fu32_BlockCNT: Number of blocks to calculate.
*/
void fft_start(FFT_HandleTypeDef *hfft, uint32_t *fp_Data_In, uint32_t *fp_Data_Out, uint32_t fu32_BlockCNT)
{
int i;
uint32_t BlockSize;
uint32_t DataIndex = 0;
uint32_t DataOutIndex = 0;
/* wait fft calculate idle */
while(!__FFT_IS_IDLE());
switch (hfft->FFT_Init.FFT_Samples)
{
case FFT_128: BlockSize = 128; break;
case FFT_256: BlockSize = 256; break;
case FFT_512: BlockSize = 512; break;
default:break;
}
while(fu32_BlockCNT--)
{
/* Data IN */
for (i = 0; i < BlockSize; i++)
FFT->FFT_ACCESSRAM = fp_Data_In[DataIndex++];
/* Wait calculate done */
while(!__FFT_CAL_IS_DONE());
/* Data OUT */
for (i = 0; i < BlockSize; i++)
fp_Data_Out[DataOutIndex++] = FFT->FFT_ACCESSRAM;
}
}
/************************************************************************************
* @fn FFT_start_IT
*
* @brief start fft calculate with isr.
*
* @param hfft: FFT_HandleTypeDef.
* @param fp_Data_In: the pointer of input data.
* @param fp_Data_Out: the pointer of output data.
* @param fu32_BlockCNT: Number of blocks to calculate.
*/
int fft_start_IT(FFT_HandleTypeDef *hfft, uint32_t *fp_Data_In, uint32_t *fp_Data_Out, uint32_t fu32_BlockCNT)
{
int i;
uint32_t BlockSize;
if (hfft->FFT_Busy)
return -1;
/* wait fft calculate idle */
while(!__FFT_IS_IDLE());
switch (hfft->FFT_Init.FFT_Samples)
{
case FFT_128: BlockSize = 128; break;
case FFT_256: BlockSize = 256; break;
case FFT_512: BlockSize = 512; break;
default:break;
}
__FFT_INT_ENALE();
hfft->FFT_Busy = true;
hfft->BlockCNT = fu32_BlockCNT;
hfft->BlockSize = BlockSize;
hfft->DataIndex = 0;
hfft->DataOutIndex = 0;
hfft->DataIn = fp_Data_In;
hfft->DataOut = fp_Data_Out;
hfft->BlockCNT--;
/* Data IN */
for (i = 0; i < hfft->BlockSize; i++)
FFT->FFT_ACCESSRAM = hfft->DataIn[hfft->DataIndex++];
return 0;
}

View File

@ -0,0 +1,979 @@
/*
******************************************************************************
* @file driver_flash.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief Internal XIP Flash module driver.
* This file provides firmware functions to manage the internal
* stacked xip flash
******************************************************************************
* @attention
*
* Copyright (c) 2022 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
#define FLASH_ID_PUYA_P25Q32 0x00166085
#define FLASH_ID_XMC_XM25LU32 0x00165020
#define FLASH_ID_GIANTEC_GT25Q16A 0x001560c4
#define FLASH_ID_PUYA_P25Q16 0x00156085
#define FLASH_ID_PUYA_P25Q80 0x00146085
#define FLASH_ID_GD_GD25WQ80E 0x001465c8
struct qspi_stig_reg_t sector_erase_cmd = {
.enable_bank = 0,
.dummy_cycles = 0,
.write_bytes = 0,
.enable_write = 0,
.addr_bytes = QSPI_STIG_ADDR_BYTES_3,
.enable_mode = 0,
.enable_cmd_addr = 1,
.read_bytes = 0,
.enable_read = 0,
.opcode = FLASH_SECTORE_ERASE_OPCODE,
};
struct qspi_stig_reg_t read_id_cmd = {
.enable_bank = 0,
.dummy_cycles = 0,
.write_bytes = 0,
.enable_write = 0,
.addr_bytes = 0,
.enable_mode = 0,
.enable_cmd_addr = 0,
.read_bytes = 3,
.enable_read = 1,
.opcode = FLASH_READ_IDENTIFICATION,
};
struct qspi_stig_reg_t read_status_cmd = {
.enable_bank = 0,
.dummy_cycles = 0,
.write_bytes = 0,
.enable_write = 0,
.addr_bytes = 0,
.enable_mode = 0,
.enable_cmd_addr = 0,
.read_bytes = 1,
.enable_read = 1,
.opcode = 0x05,
};
struct qspi_stig_reg_t read_status_h_cmd = {
.enable_bank = 0,
.dummy_cycles = 0,
.write_bytes = 0,
.enable_write = 0,
.addr_bytes = 0,
.enable_mode = 0,
.enable_cmd_addr = 0,
.read_bytes = 1,
.enable_read = 1,
.opcode = 0x35,
};
struct qspi_stig_reg_t write_enable_cmd = {
.enable_bank = 0,
.dummy_cycles = 0,
.write_bytes = 0,
.enable_write = 0,
.addr_bytes = 0,
.enable_mode = 0,
.enable_cmd_addr = 0,
.read_bytes = 0,
.enable_read = 0,
.opcode = 0x06,
};
struct qspi_stig_reg_t write_volatile_enable_cmd = {
.enable_bank = 0,
.dummy_cycles = 0,
.write_bytes = 0,
.enable_write = 0,
.addr_bytes = 0,
.enable_mode = 0,
.enable_cmd_addr = 0,
.read_bytes = 0,
.enable_read = 0,
.opcode = 0x50,
};
struct qspi_stig_reg_t write_status_cmd = {
.enable_bank = 0,
.dummy_cycles = 0,
.write_bytes = 1,
.enable_write = 1,
.addr_bytes = 0,
.enable_mode = 0,
.enable_cmd_addr = 0,
.read_bytes = 0,
.enable_read = 0,
.opcode = 0x01,
};
struct qspi_stig_reg_t write_status_2_cmd = {
.enable_bank = 0,
.dummy_cycles = 0,
.write_bytes = 1,
.enable_write = 1,
.addr_bytes = 0,
.enable_mode = 0,
.enable_cmd_addr = 0,
.read_bytes = 0,
.enable_read = 0,
.opcode = 0x31,
};
struct qspi_stig_reg_t write_status_3_cmd = {
.enable_bank = 0,
.dummy_cycles = 0,
.write_bytes = 1,
.enable_write = 1,
.addr_bytes = 0,
.enable_mode = 0,
.enable_cmd_addr = 0,
.read_bytes = 0,
.enable_read = 0,
.opcode = 0x11,
};
struct qspi_stig_reg_t write_status_h_cmd = {
.enable_bank = 0,
.dummy_cycles = 0,
.write_bytes = 1,
.enable_write = 1,
.addr_bytes = 0,
.enable_mode = 0,
.enable_cmd_addr = 0,
.read_bytes = 0,
.enable_read = 0,
.opcode = 0x31,
};
struct qspi_stig_reg_t block_erase_cmd = {
.enable_bank = 0,
.dummy_cycles = 0,
.write_bytes = 0,
.enable_write = 0,
.addr_bytes = QSPI_STIG_ADDR_BYTES_3,
.enable_mode = 0,
.enable_cmd_addr = 1,
.read_bytes = 0,
.enable_read = 0,
.opcode = 0xD8,
};
struct qspi_stig_reg_t chip_erase_cmd = {
.enable_bank = 0,
.dummy_cycles = 0,
.write_bytes = 0,
.enable_write = 0,
.addr_bytes = 0,
.enable_mode = 0,
.enable_cmd_addr = 0,
.read_bytes = 0,
.enable_read = 0,
.opcode = 0x60,
};
struct qspi_stig_reg_t write_cmd = {
.enable_bank = 0,
.dummy_cycles = 0,
.write_bytes = 0,
.enable_write = 1,
.addr_bytes = QSPI_STIG_ADDR_BYTES_3,
.enable_mode = 0,
.enable_cmd_addr = 1,
.read_bytes = 0,
.enable_read = 0,
.opcode = 0x02,
};
struct qspi_stig_reg_t write_disable_cmd = {
.enable_bank = 0,
.dummy_cycles = 0,
.write_bytes = 0,
.enable_write = 0,
.addr_bytes = 0,
.enable_mode = 0,
.enable_cmd_addr = 0,
.read_bytes = 0,
.enable_read = 0,
.opcode = 0x04,
};
struct qspi_stig_reg_t read_cmd = {
.enable_bank = 0,
.dummy_cycles = 0,
.write_bytes = 0,
.enable_write = 0,
.addr_bytes = QSPI_STIG_ADDR_BYTES_3,
.enable_mode = 0,
.enable_cmd_addr = 1,
.read_bytes = 0,
.enable_read = 1,
.opcode = 0x03,
};
struct qspi_stig_reg_t deep_sleep_cmd = {
.enable_bank = 0,
.dummy_cycles = 0,
.write_bytes = 0,
.enable_write = 0,
.addr_bytes = 0,
.enable_mode = 0,
.enable_cmd_addr = 0,
.read_bytes = 0,
.enable_read = 0,
.opcode = 0xB9,
};
struct qspi_stig_reg_t wakeup_cmd = {
.enable_bank = 0,
.dummy_cycles = 0,
.write_bytes = 0,
.enable_write = 0,
.addr_bytes = 0,
.enable_mode = 0,
.enable_cmd_addr = 0,
.read_bytes = 0,
.enable_read = 0,
.opcode = 0xAB,
};
struct qspi_stig_reg_t sec_sector_erase_cmd = {
.enable_bank = 0,
.dummy_cycles = 0,
.write_bytes = 0,
.enable_write = 0,
.addr_bytes = QSPI_STIG_ADDR_BYTES_3,
.enable_mode = 0,
.enable_cmd_addr = 1,
.read_bytes = 0,
.enable_read = 0,
.opcode = FLASH_SEC_REG_ERASE_OPCODE,
};
struct qspi_stig_reg_t sec_sector_read_cmd = {
.enable_bank = 0,
.dummy_cycles = 1,
.write_bytes = 0,
.enable_write = 0,
.addr_bytes = QSPI_STIG_ADDR_BYTES_3,
.enable_mode = 0,
.enable_cmd_addr = 1,
.read_bytes = 0,
.enable_read = 1,
.opcode = FLASH_SEC_REG_READ_OPCODE,
};
struct qspi_stig_reg_t sec_sector_write_cmd = {
.enable_bank = 0,
.dummy_cycles = 0,
.write_bytes = 0,
.enable_write = 1,
.addr_bytes = QSPI_STIG_ADDR_BYTES_3,
.enable_mode = 0,
.enable_cmd_addr = 1,
.read_bytes = 0,
.enable_read = 0,
.opcode = FLASH_SEC_REG_PROGRAM_OPCODE,
};
__RAM_CODE void flash_wait_wip_clear(struct qspi_regs_t *qspi)
{
uint8_t status;
while(1) {
system_delay_us(100);
qspi_stig_cmd(qspi, read_status_cmd, QSPI_STIG_CMD_READ, 1, &status);
if((status & 0x01) == 0) {
break;
}
}
}
__RAM_CODE void flash_enable_quad(struct qspi_regs_t *qspi)
{
uint8_t status[2];
uint32_t flash_id;
qspi_stig_cmd(qspi, read_status_cmd, QSPI_STIG_CMD_READ, 1, &status[0]);
qspi_stig_cmd(qspi, read_status_h_cmd, QSPI_STIG_CMD_READ, 1, &status[1]);
if((status[1] & 0x02) == 0x02) {
return;
}
flash_id = flash_read_id(qspi);
if ((flash_id == FLASH_ID_PUYA_P25Q32)
|| (flash_id == FLASH_ID_XMC_XM25LU32)
|| (flash_id == FLASH_ID_GIANTEC_GT25Q16A )
|| (flash_id == FLASH_ID_PUYA_P25Q16)) {
status[1] |= 0x02; //enable quad mode
qspi_stig_cmd(qspi, write_enable_cmd, QSPI_STIG_CMD_EXE, 0, 0);
qspi_stig_cmd(qspi, write_status_h_cmd, QSPI_STIG_CMD_WRITE, 1, &status[1]);
}
else if ((flash_id == FLASH_ID_GD_GD25WQ80E)
|| (flash_id == FLASH_ID_PUYA_P25Q80)) {
status[1] |= 0x02; //enable quad mode
qspi_stig_cmd(qspi, write_enable_cmd, QSPI_STIG_CMD_EXE, 0, 0);
qspi_stig_cmd(qspi, write_status_cmd, QSPI_STIG_CMD_WRITE, 2, &status[0]);
}
else {
while(1);
}
flash_wait_wip_clear(qspi);
}
__RAM_CODE void flash_set_IO_DRV(struct qspi_regs_t *qspi, uint8_t drv)
{
uint8_t data;
data = (drv<<5);
qspi_stig_cmd(qspi, write_volatile_enable_cmd, QSPI_STIG_CMD_EXE, 0, 0);
qspi_stig_cmd(qspi, write_status_3_cmd, QSPI_STIG_CMD_WRITE, 1, &data);
}
__RAM_CODE void flash_set_capture_delay(struct qspi_regs_t *qspi, uint8_t delay)
{
__QSPI_READ_CAPTURE_DELAY_SET(qspi, delay);
}
__RAM_CODE void flash_set_read_dtr_fast_quad(struct qspi_regs_t *qspi)
{
__QSPI_READ_OPCODE_SET(qspi, FLASH_PAGE_DTR_QUAL_READ_OPCODE);
__QSPI_READ_INSTRUCTION_TYPE_SET(qspi, QSPI_WIRE_TYPE_STAND);
__QSPI_READ_ADDRESS_TYPE_SET(qspi, QSPI_WIRE_TYPE_QIO);
__QSPI_READ_DATA_TYPE_SET(qspi, QSPI_WIRE_TYPE_QIO);
__QSPI_READ_DUMMY_CYCLES_SET(qspi, 7);
__QSPI_READ_MODE_ENABLE_SET(qspi, 1);
__QSPI_MODE_BIT_SET(qspi, 0);
// __QSPI_CFG_DTR_ENABLE(qspi);
__QSPI_READ_DDR_ENABLE(qspi);
}
__RAM_CODE void flash_set_read_fast_quad(struct qspi_regs_t *qspi)
{
__QSPI_READ_OPCODE_SET(qspi, FLASH_PAGE_QUAL_READ_OPCODE);
__QSPI_READ_INSTRUCTION_TYPE_SET(qspi, QSPI_WIRE_TYPE_STAND);
__QSPI_READ_ADDRESS_TYPE_SET(qspi, QSPI_WIRE_TYPE_QIO);
__QSPI_READ_DATA_TYPE_SET(qspi, QSPI_WIRE_TYPE_QIO);
__QSPI_READ_DUMMY_CYCLES_SET(qspi, 4);
__QSPI_READ_MODE_ENABLE_SET(qspi, 1);
__QSPI_MODE_BIT_SET(qspi, 0);
}
__RAM_CODE void flash_set_read_quad(struct qspi_regs_t *qspi)
{
__QSPI_READ_OPCODE_SET(qspi, FLASH_PAGE_QUAL_READ_OPCODE_2);
__QSPI_READ_INSTRUCTION_TYPE_SET(qspi, QSPI_WIRE_TYPE_STAND);
__QSPI_READ_ADDRESS_TYPE_SET(qspi, QSPI_WIRE_TYPE_STAND);
__QSPI_READ_DATA_TYPE_SET(qspi, QSPI_WIRE_TYPE_QIO);
__QSPI_READ_DUMMY_CYCLES_SET(qspi, 8);
__QSPI_READ_MODE_ENABLE_SET(qspi, 0);
__QSPI_MODE_BIT_SET(qspi, 0);
}
__RAM_CODE void flash_set_read_dtr_fast_dual(struct qspi_regs_t *qspi)
{
__QSPI_READ_OPCODE_SET(qspi, FLASH_READ_DTR_DUAL_OPCODE);
__QSPI_READ_INSTRUCTION_TYPE_SET(qspi, QSPI_WIRE_TYPE_STAND);
__QSPI_READ_ADDRESS_TYPE_SET(qspi, QSPI_WIRE_TYPE_DIO);
__QSPI_READ_DATA_TYPE_SET(qspi, QSPI_WIRE_TYPE_DIO);
__QSPI_READ_DUMMY_CYCLES_SET(qspi, 0);
__QSPI_READ_MODE_ENABLE_SET(qspi, 0);
__QSPI_MODE_BIT_SET(qspi, 0);
// __QSPI_CFG_DTR_ENABLE(qspi);
__QSPI_READ_DDR_ENABLE(qspi);
}
__RAM_CODE void flash_set_read_fast_dual(struct qspi_regs_t *qspi)
{
__QSPI_READ_OPCODE_SET(qspi, FLASH_READ_DUAL_OPCODE);
__QSPI_READ_INSTRUCTION_TYPE_SET(qspi, QSPI_WIRE_TYPE_STAND);
__QSPI_READ_ADDRESS_TYPE_SET(qspi, QSPI_WIRE_TYPE_DIO);
__QSPI_READ_DATA_TYPE_SET(qspi, QSPI_WIRE_TYPE_DIO);
__QSPI_READ_DUMMY_CYCLES_SET(qspi, 0);
__QSPI_READ_MODE_ENABLE_SET(qspi, 1);
__QSPI_MODE_BIT_SET(qspi, 0);
}
__RAM_CODE void flash_set_read_dual(struct qspi_regs_t *qspi)
{
__QSPI_READ_OPCODE_SET(qspi, FLASH_READ_DUAL_OPCODE_2);
__QSPI_READ_INSTRUCTION_TYPE_SET(qspi, QSPI_WIRE_TYPE_STAND);
__QSPI_READ_ADDRESS_TYPE_SET(qspi, QSPI_WIRE_TYPE_STAND);
__QSPI_READ_DATA_TYPE_SET(qspi, QSPI_WIRE_TYPE_DIO);
__QSPI_READ_DUMMY_CYCLES_SET(qspi, 8);
__QSPI_READ_MODE_ENABLE_SET(qspi, 0);
__QSPI_MODE_BIT_SET(qspi, 0);
}
__RAM_CODE void flash_set_read_dtr_fast_single(struct qspi_regs_t *qspi)
{
__QSPI_READ_OPCODE_SET(qspi, FLASH_FAST_DTR_READ_OPCODE);
__QSPI_READ_INSTRUCTION_TYPE_SET(qspi, QSPI_WIRE_TYPE_STAND);
__QSPI_READ_ADDRESS_TYPE_SET(qspi, QSPI_WIRE_TYPE_STAND);
__QSPI_READ_DATA_TYPE_SET(qspi, QSPI_WIRE_TYPE_STAND);
__QSPI_READ_DUMMY_CYCLES_SET(qspi, 6);
__QSPI_READ_MODE_ENABLE_SET(qspi, 0);
__QSPI_MODE_BIT_SET(qspi, 0);
// __QSPI_CFG_DTR_ENABLE(qspi);
__QSPI_READ_DDR_ENABLE(qspi);
}
__RAM_CODE void flash_set_read_fast_single(struct qspi_regs_t *qspi)
{
__QSPI_READ_OPCODE_SET(qspi, FLASH_FAST_READ_OPCODE);
__QSPI_READ_INSTRUCTION_TYPE_SET(qspi, QSPI_WIRE_TYPE_STAND);
__QSPI_READ_ADDRESS_TYPE_SET(qspi, QSPI_WIRE_TYPE_STAND);
__QSPI_READ_DATA_TYPE_SET(qspi, QSPI_WIRE_TYPE_STAND);
__QSPI_READ_DUMMY_CYCLES_SET(qspi, 8);
__QSPI_READ_MODE_ENABLE_SET(qspi, 0);
__QSPI_MODE_BIT_SET(qspi, 0);
}
__RAM_CODE void flash_set_read_single(struct qspi_regs_t *qspi)
{
__QSPI_READ_OPCODE_SET(qspi, FLASH_READ_OPCODE);
__QSPI_READ_INSTRUCTION_TYPE_SET(qspi, QSPI_WIRE_TYPE_STAND);
__QSPI_READ_ADDRESS_TYPE_SET(qspi, QSPI_WIRE_TYPE_STAND);
__QSPI_READ_DATA_TYPE_SET(qspi, QSPI_WIRE_TYPE_STAND);
__QSPI_READ_DUMMY_CYCLES_SET(qspi, 0);
__QSPI_READ_MODE_ENABLE_SET(qspi, 0);
__QSPI_MODE_BIT_SET(qspi, 0);
}
__RAM_CODE void flash_set_write_quad(struct qspi_regs_t *qspi)
{
__QSPI_WRITE_OPCODE_SET(qspi, FLASH_PAGE_QUAL_PROGRAM_OPCODE);
__QSPI_WRITE_ADDRESS_TYPE_SET(qspi, QSPI_WIRE_TYPE_STAND);
__QSPI_WRITE_DATA_TYPE_SET(qspi, QSPI_WIRE_TYPE_QIO);
__QSPI_WRITE_DUMMY_CYCLES_SET(qspi, 0);
}
__RAM_CODE void flash_set_write_dual(struct qspi_regs_t *qspi)
{
__QSPI_WRITE_OPCODE_SET(qspi, FLASH_PAGE_DUAL_PROGRAM_OPCODE);
__QSPI_WRITE_ADDRESS_TYPE_SET(qspi, QSPI_WIRE_TYPE_STAND);
__QSPI_WRITE_DATA_TYPE_SET(qspi, QSPI_WIRE_TYPE_DIO);
__QSPI_WRITE_DUMMY_CYCLES_SET(qspi, 0);
}
__RAM_CODE void flash_set_write_single(struct qspi_regs_t *qspi)
{
__QSPI_WRITE_OPCODE_SET(qspi, FLASH_PAGE_PROGRAM_OPCODE);
__QSPI_WRITE_ADDRESS_TYPE_SET(qspi, QSPI_WIRE_TYPE_STAND);
__QSPI_WRITE_DATA_TYPE_SET(qspi, QSPI_WIRE_TYPE_STAND);
__QSPI_WRITE_DUMMY_CYCLES_SET(qspi, 0);
}
__RAM_CODE __USED void flash_set_read_type(struct qspi_regs_t *qspi, uint8_t rd_type)
{
switch(rd_type) {
case FLASH_RD_TYPE_SINGLE:
flash_set_read_single(qspi);
break;
case FLASH_RD_TYPE_SINGLE_FAST:
flash_set_read_fast_single(qspi);
break;
case FLASH_RD_TYPE_DUAL:
flash_set_read_dual(qspi);
break;
case FLASH_RD_TYPE_DUAL_FAST:
flash_set_read_fast_dual(qspi);
break;
case FLASH_RD_TYPE_QUAD:
flash_set_read_quad(qspi);
break;
case FLASH_RD_TYPE_QUAD_FAST:
flash_set_read_fast_quad(qspi);
break;
case FLASH_RD_TYPE_DTR_SINGLE_FAST:
flash_set_read_dtr_fast_single(qspi);
break;
case FLASH_RD_TYPE_DTR_DUAL_FAST:
flash_set_read_dtr_fast_dual(qspi);
break;
case FLASH_RD_TYPE_DTR_QUAD_FAST:
flash_set_read_dtr_fast_quad(qspi);
break;
default:
flash_set_read_single(qspi);
break;
}
}
__RAM_CODE __USED void flash_set_write_type(struct qspi_regs_t *qspi, uint8_t wr_type)
{
switch(wr_type) {
case FLASH_WR_TYPE_SINGLE:
flash_set_write_single(qspi);
break;
case FLASH_WR_TYPE_DUAL:
flash_set_write_dual(qspi);
break;
case FLASH_WR_TYPE_QUAD:
flash_set_write_quad(qspi);
break;
default:
flash_set_write_single(qspi);
break;
}
}
__RAM_CODE __USED void flash_init_controller(struct qspi_regs_t *qspi, enum flash_rd_type_t rd_type, enum flash_wr_type_t wr_type)
{
while(__QSPI_IS_BUSY(qspi));
flash_set_read_type(qspi, rd_type);
flash_set_write_type(qspi, wr_type);
__QSPI_POLL_OPCODE_SET(qspi, 0x05);
__QSPI_POLL_BIT_INDEX_SET(qspi, 0);
__QSPI_POLL_POLARITY_SET(qspi, 0);
__QSPI_POLL_EXPIRATION_SET(qspi, 0);
__QSPI_POLL_EXPIRE_DISABLE(qspi);
__QSPI_POLL_COUNT_SET(qspi, 2);
__QSPI_POLL_DELAY_SET(qspi, 16);
__QSPI_POLL_DISABLE(qspi);
//init configuration register
__QSPI_CFG_CPOL_SET(qspi, 1);
__QSPI_CFG_CPHA_SET(qspi, 1);
__QSPI_CFG_DAC_ENABLE(qspi);
__QSPI_CFG_LEGACY_DISABLE(qspi);
__QSPI_CFG_REMAP_ENABLE(qspi);
__QSPI_CFG_BAUDRATE_SET(qspi, QSPI_BAUDRATE_DIV_16);
__QSPI_CFG_AHB_DECODER_ENABLE(qspi);
__QSPI_DELAY_CS_START_SET(qspi, 2);
__QSPI_DELAY_CS_END_SET(qspi, 2);
__QSPI_REMAP_ADDRESS_SET(qspi, 0);
__QSPI_ENABLE(qspi);
}
uint32_t flash_read_id(struct qspi_regs_t *qspi)
{
uint32_t flash_id;
qspi_stig_cmd(qspi, read_id_cmd, QSPI_STIG_CMD_READ, 3, (uint8_t *)&flash_id);
return (flash_id&0xffffff);
}
__RAM_CODE void flash_set_baudrate(struct qspi_regs_t *qspi, uint8_t baudrate)
{
if (baudrate <= QSPI_BAUDRATE_DIV_32) {
GLOBAL_INT_DISABLE();
while(__QSPI_IS_BUSY(qspi));
__QSPI_CFG_BAUDRATE_SET(qspi, baudrate);
if ((baudrate == QSPI_BAUDRATE_DIV_2)
|| ((baudrate == QSPI_BAUDRATE_DIV_4) && (__QSPI_READ_DDR_GET(qspi) == 1))) {
__QSPI_READ_CAPTURE_DELAY_SET(qspi, 2);
}
GLOBAL_INT_RESTORE();
}
}
uint32_t flash_init(struct qspi_regs_t *qspi)
{
flash_exit_deep_sleep(qspi);
return flash_read_id(qspi);
}
uint16_t flash_read_status(struct qspi_regs_t *qspi, bool read_high)
{
uint8_t *status;
uint16_t status_entity;
status = (uint8_t *)&status_entity;
qspi_stig_cmd(qspi, read_status_cmd, QSPI_STIG_CMD_READ, 1, &status[0]);
if(read_high) {
qspi_stig_cmd(qspi, read_status_h_cmd, QSPI_STIG_CMD_READ, 1, &status[1]);
}
return status_entity;
}
__RAM_CODE void flash_write_status(struct qspi_regs_t *qspi, uint16_t status, bool write_high)
{
uint8_t count = 1;
if(write_high) {
count++;
}
qspi_stig_cmd(qspi, write_enable_cmd, QSPI_STIG_CMD_EXE, 0, 0);
qspi_stig_cmd(qspi, write_status_cmd, QSPI_STIG_CMD_WRITE, count, (void *)&status);
flash_wait_wip_clear(qspi);
}
__RAM_CODE void flash_write_status_2(struct qspi_regs_t *qspi, uint8_t status)
{
qspi_stig_cmd(qspi, write_enable_cmd, QSPI_STIG_CMD_EXE, 0, 0);
qspi_stig_cmd(qspi, write_status_2_cmd, QSPI_STIG_CMD_WRITE, 1, (void *)&status);
flash_wait_wip_clear(qspi);
}
__RAM_CODE void flash_write_status_volatile(struct qspi_regs_t *qspi, uint16_t status, bool write_high)
{
uint8_t count = 1;
uint8_t poll_status;
if(write_high) {
count++;
}
qspi_stig_cmd(qspi, write_volatile_enable_cmd, QSPI_STIG_CMD_EXE, 0, 0);
qspi_stig_cmd(qspi, write_status_cmd, QSPI_STIG_CMD_WRITE, count, (void *)&status);
}
__RAM_CODE void flash_write_status_2_volatile(struct qspi_regs_t *qspi, uint8_t status)
{
qspi_stig_cmd(qspi, write_volatile_enable_cmd, QSPI_STIG_CMD_EXE, 0, 0);
qspi_stig_cmd(qspi, write_status_2_cmd, QSPI_STIG_CMD_WRITE, 1, (void *)&status);
}
/************************************************************************************
* @fn flash_protect_bit_set
*
* @brief set flash protection relevant bits.
*
* @param qspi: qspi controller base address
* bits: flash protection bits in status 1, BIT4:0 is valid.
* cmp: flash protection compare bit in status 2.
* 0xff means this field should be ignored
* BIT7: clear or set CMP bit
* BIT0-2: CMP bit offset in status 2
* wr_volatile: write status registers in volatile mode or not
* status_2_separate: write status 2 together with status 1 or separately
*/
__RAM_CODE void flash_protect_bit_set(struct qspi_regs_t *qspi, uint8_t bits, uint8_t cmp, uint8_t wr_volatile, uint8_t status_2_separate)
{
uint8_t status[2];
uint16_t status_tmp;
uint8_t skip_status_1 = 0;
if(cmp != 0xff) {
status_tmp = flash_read_status(qspi, true);
status[0] = status_tmp & 0xff;
status[1] = (status_tmp>>8) & 0xff;
if(cmp & 0x80) {
// set cmp bit
if((status[1] & (1<<(cmp&0x07))) != 0) {
cmp = 0xff;
}
else {
status[1] |= (1<<(cmp&0x07));
}
}
else {
// clear cmp bit
if((status[1] & (1<<(cmp&0x07))) == 0) {
cmp = 0xff;
}
else {
status[1] &= (~(1<<(cmp&0x07)));
}
}
}
else {
status_tmp = flash_read_status(qspi, false);
status[0] = status_tmp & 0xff;
}
bits &= 0x1f;
if((status[0] & 0x7C) == (bits << 2)) {
skip_status_1 = 1;
if (cmp == 0xff) {
return;
}
}
status[0] &= 0x80;
status[0] |= (bits << 2);
GLOBAL_INT_DISABLE();
if(cmp != 0xff) {
if(status_2_separate) {
if(wr_volatile) {
if(skip_status_1 == 0) {
flash_write_status_volatile(qspi, status[0], false);
}
flash_write_status_2_volatile(qspi, status[1]);
}
else {
if(skip_status_1 == 0) {
flash_write_status(qspi, status[0], false);
}
flash_write_status_2(qspi, status[1]);
}
}
else {
status_tmp = status[0] | (status[1]<<8);
if(wr_volatile) {
flash_write_status_volatile(qspi, status_tmp, true);
}
else {
flash_write_status(qspi, status_tmp, true);
}
}
}
else {
if(wr_volatile) {
flash_write_status_volatile(qspi, status[0], false);
}
else {
flash_write_status(qspi, status[0], false);
}
}
GLOBAL_INT_RESTORE();
}
__RAM_CODE __attribute__((noinline)) uint8_t flash_write(struct qspi_regs_t *qspi, uint32_t offset, uint32_t length, const uint8_t *buffer)
{
uint32_t page_left;
uint32_t dac_addr_offset;
uint8_t *dst;
if(length == 0) {
return 0;
}
if ((uint32_t)qspi == FLASH_QSPI_BASE) {
dac_addr_offset = FLASH_DAC_BASE;
}
else if ((uint32_t)qspi == DSP_QSPI_BASE) {
dac_addr_offset = DSP_FLASH_DAC_BASE;
}
else {
return 0;
}
page_left = 0x100 - (offset & 0xff);
if(length < page_left) {
page_left = length;
}
dst = (void *)(offset | dac_addr_offset);
GLOBAL_INT_DISABLE();
if ((uint32_t)qspi == FLASH_QSPI_BASE) {
system_cache_disable();
}
while(length) {
for (int32_t i=0; i<page_left; i++) {
*dst++ = *buffer++;
}
flash_wait_wip_clear(qspi);
length -= page_left;
page_left = (length > 256) ? 256 : length;
}
if ((uint32_t)qspi == FLASH_QSPI_BASE) {
system_cache_enable(true);
}
GLOBAL_INT_RESTORE();
return 0;
}
__USED uint8_t flash_read(struct qspi_regs_t *qspi, uint32_t offset, uint32_t length, uint8_t *buffer)
{
if ((uint32_t)qspi == FLASH_QSPI_BASE) {
memcpy(buffer, (void *)(offset | FLASH_DAC_BASE), length);
}
else if((uint32_t)qspi == DSP_QSPI_BASE) {
memcpy(buffer, (void *)(offset | DSP_FLASH_DAC_BASE), length);
}
return 0;
}
__RAM_CODE __attribute__((noinline)) uint8_t flash_erase(struct qspi_regs_t *qspi, uint32_t offset, uint32_t size)
{
if(size == 0) {
size = 0x1000;
}
offset &= 0xFFFFF000;
GLOBAL_INT_DISABLE();
system_cache_disable();
while(size) {
qspi_stig_cmd(qspi, write_enable_cmd, QSPI_STIG_CMD_EXE, 0, 0);
__QSPI_CMD_ADDRESS_SET(qspi, offset);
qspi_stig_cmd(qspi, sector_erase_cmd, QSPI_STIG_CMD_EXE, 0, 0);
flash_wait_wip_clear(qspi);
offset += 0x1000;
if(size > 0x1000)
size -= 0x1000;
else {
size = 0;
}
}
system_cache_enable(true);
GLOBAL_INT_RESTORE();
return 0;
}
__RAM_CODE void flash_chip_erase(struct qspi_regs_t *qspi)
{
qspi_stig_cmd(qspi, write_enable_cmd, QSPI_STIG_CMD_EXE, 0, 0);
qspi_stig_cmd(qspi, chip_erase_cmd, QSPI_STIG_CMD_EXE, 0, 0);
system_delay_us(20);
flash_wait_wip_clear(qspi);
}
__RAM_CODE void flash_enter_deep_sleep(struct qspi_regs_t *qspi)
{
qspi_stig_cmd(qspi, deep_sleep_cmd, QSPI_STIG_CMD_EXE, 0, 0);
system_delay_us(20);
}
__RAM_CODE void flash_exit_deep_sleep(struct qspi_regs_t *qspi)
{
qspi_stig_cmd(qspi, wakeup_cmd, QSPI_STIG_CMD_EXE, 0, 0);
system_delay_us(20);
}
/*********************************************************************
* @fn flash_OTP_read
*
* @brief read data from OTP sections. otp section size: 512 = 0x200
*
* @param offset - Security flash section offset, only valid for 0x1000,0x2000,0x3000
* length - buffer length to be read from security flash section. rang[1,512]
* buffer - pointer to buffer which will store data
*
* @return None.
*/
__RAM_CODE void flash_OTP_read(struct qspi_regs_t *qspi,uint32_t offset, uint32_t length, uint8_t *buffer)
{
uint32_t i = 0;
offset &= 0x3000;
if(length > 512)
length = 512;
GLOBAL_INT_DISABLE();
for(; (i+8) <= length; )
{
__QSPI_CMD_ADDRESS_SET(qspi, offset);
qspi_stig_cmd(qspi,sec_sector_read_cmd, QSPI_STIG_CMD_READ, 8, buffer + i );
i+=8;
offset+=8;
}
if(i < length)
{
__QSPI_CMD_ADDRESS_SET(qspi, offset);
qspi_stig_cmd(qspi,sec_sector_read_cmd, QSPI_STIG_CMD_READ, (length-i), (buffer+i));
}
GLOBAL_INT_RESTORE();
}
/*********************************************************************
* @fn flash_OTP_write
*
* @brief write data to OTP sections. otp section size: 512 = 0x200
*
* @param offset - Security flash section offset, only valid for 0x1000,0x2000,0x3000
* length - buffer length to be written into security flash section. rang[1,512]
* buffer - pointer to buffer which will be written
*
* @return None.
*/
__RAM_CODE void flash_OTP_write(struct qspi_regs_t *qspi,uint32_t offset, uint32_t length, uint8_t *buffer)
{
uint8_t status[1];
uint32_t i = 0;
#define SINGLE_LENGTH 8
offset &= 0x3000;
if(length > 512)
length = 512;
GLOBAL_INT_DISABLE();
for(; (i+SINGLE_LENGTH) <= length; )
{
qspi_stig_cmd(qspi,write_enable_cmd, QSPI_STIG_CMD_EXE, 0, 0);
__QSPI_CMD_ADDRESS_SET(qspi, offset);
qspi_stig_cmd(qspi,sec_sector_write_cmd, QSPI_STIG_CMD_WRITE, SINGLE_LENGTH, buffer+i);
while(1) {
system_delay_us(20);
qspi_stig_cmd(qspi,read_status_cmd, QSPI_STIG_CMD_READ, 1, &status[0]);
if((status[0] & 0x01) == 0) {
break;
}
}
qspi_stig_cmd(qspi,write_disable_cmd, QSPI_STIG_CMD_EXE, 0, 0);
i+=SINGLE_LENGTH;
offset+=SINGLE_LENGTH;
}
if(i < length)
{
qspi_stig_cmd(qspi,write_enable_cmd, QSPI_STIG_CMD_EXE, 0, 0);
__QSPI_CMD_ADDRESS_SET(qspi, offset);
qspi_stig_cmd(qspi,sec_sector_write_cmd, QSPI_STIG_CMD_WRITE, (length-i), (buffer+i));
while(1) {
system_delay_us(20);
qspi_stig_cmd(qspi,read_status_cmd, QSPI_STIG_CMD_READ, 1, &status[0]);
if((status[0] & 0x01) == 0) {
break;
}
}
qspi_stig_cmd(qspi,write_disable_cmd, QSPI_STIG_CMD_EXE, 0, 0);
}
GLOBAL_INT_RESTORE();
}
/*********************************************************************
* @fn flash_OTP_erase
*
* @brief erase whole OTP section .
*
* @param offset - Security flash section offset, only valid for 0x1000,0x2000,0x3000
*
* @return None.
*/
__RAM_CODE void flash_OTP_erase(struct qspi_regs_t *qspi,uint32_t offset)
{
uint8_t status;
offset &= 0x3000;
GLOBAL_INT_DISABLE();
qspi_stig_cmd(qspi,write_enable_cmd, QSPI_STIG_CMD_EXE, 0, 0);
__QSPI_CMD_ADDRESS_SET(qspi, offset);
qspi_stig_cmd(qspi,sec_sector_erase_cmd, QSPI_STIG_CMD_EXE, 0, 0);
while(1) {
system_delay_us(20);
qspi_stig_cmd(qspi,read_status_cmd, QSPI_STIG_CMD_READ, 1, &status);
if((status & 0x01) == 0) {
break;
}
}
qspi_stig_cmd(qspi,write_disable_cmd, QSPI_STIG_CMD_EXE, 0, 0);
GLOBAL_INT_RESTORE();
}

View File

@ -0,0 +1,148 @@
/**
****************************************************************************************
*
* @file frspim.c
*
* @brief freqchip spi master initialization and specific functions
*
* Copyright (C) RivieraWaves 2009-2013
*
*
****************************************************************************************
*/
/**
****************************************************************************************
* @addtogroup RF_FR
* @ingroup RF
* @brief FREQCHIP Radio Driver
*
* This is the driver block for FR radio
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "fr30xx.h"
/*
* DEFINES
****************************************************************************************
*/
volatile struct frspim_reg_t * const frspim_reg = (volatile struct frspim_reg_t * )FRSPIM_BASE;
/*
* FUNCTION DEFINITIONS
****************************************************************************************
*/
void frspim_init(uint8_t ratio)
{
frspim_reg->ctrl.ratio = ratio;
}
/*****************************************************************************************
* @brief SPI access
****************************************************************************************
*/
/*****************************************************************************************
* @brief Bluejay specific read access
*
* @param[in] addr register address
*
* @return uint32_t value
****************************************************************************************
*/
__RAM_CODE uint32_t frspim_rd (uint8_t chan_num, uint8_t addr, uint8_t len)
{
uint32_t data;
GLOBAL_INT_DISABLE();
frspim_reg->ctrl.len = len;
frspim_reg->ctrl.sel = chan_num;
frspim_reg->ctrl.op = 0;
frspim_reg->ctrl.addr = addr;
frspim_reg->ctrl.go = 1;
while(!frspim_reg->ctrl.done);
data = (*((uint32_t *)(&frspim_reg->rdat)));
GLOBAL_INT_RESTORE();
return data;
}
/*****************************************************************************************
* @brief Bluejay specific read access for ram
*
* @param[in] addr register address
*
* @return uint32_t value
****************************************************************************************
*/
__RAM_CODE uint32_t frspim_rd_ram (uint8_t chan_num, uint8_t addr, uint8_t len)
{
uint32_t data;
GLOBAL_INT_DISABLE();
*(volatile uint32_t *)(&frspim_reg->ctrl) = 0x00001011 | (addr<<16);
while(!frspim_reg->ctrl.done);
data = *(volatile uint32_t *)(&frspim_reg->rdat);
GLOBAL_INT_RESTORE();
return data;
}
/*****************************************************************************************
* @brief Freqchip specific write access
*
* @param[in] addr register address
* @param[in] value value to write
*
* @return uint32_t value
****************************************************************************************
*/
__RAM_CODE void frspim_wr (uint8_t chan_num, uint8_t addr, uint8_t len, uint32_t val)
{
GLOBAL_INT_DISABLE();
frspim_reg->ctrl.len = len;
frspim_reg->ctrl.sel = chan_num;
frspim_reg->ctrl.op = 1;
frspim_reg->ctrl.addr = addr;
(*((uint32_t *)(&frspim_reg->wdat))) = val;
frspim_reg->ctrl.go = 1;
while(!frspim_reg->ctrl.done);
GLOBAL_INT_RESTORE();
}
/*****************************************************************************************
* @brief Freqchip specific write access for ram
*
* @param[in] addr register address
* @param[in] value value to write
*
* @return uint32_t value
****************************************************************************************
*/
__RAM_CODE void frspim_wr_ram (uint8_t chan_num, uint8_t addr, uint8_t len, uint32_t val)
{
GLOBAL_INT_DISABLE();
*(volatile uint32_t *)(&frspim_reg->wdat) = val;
*(volatile uint32_t *)(&frspim_reg->ctrl) = 0x00001111 | (addr<<16);;
while(!frspim_reg->ctrl.done);
GLOBAL_INT_RESTORE();
}

View File

@ -0,0 +1,426 @@
/*
******************************************************************************
* @file driver_gpio.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief GPIO module driver.
* This file provides firmware functions to manage the
* General Purpose Input/Output (GPIO) peripheral
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
/************************************************************************************
* @fn gpio_init
*
* @brief Initializes the GPIOx peripheral according to the specified
* parameters in the GPIO_Init
*
* @param fe_GPIO: to select the GPIO peripheral.
* GPIO_Init: pointer to a GPIO_InitTypeDef structure that contains the
* configuration information for the specified GPIO peripheral.
*/
__RAM_CODE void gpio_init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
{
uint32_t lu32_Position = 0;
uint32_t lu32_Current_Pin;
volatile uint32_t *GPIO_Pull_EN;
volatile uint32_t *GPIO_Pull_Select;
volatile uint32_t *GPIO_FuncMuxL;
volatile uint32_t *GPIO_FuncMuxH;
/* Select the group register */
if (GPIOx == GPIOA)
{
GPIO_Pull_EN = &(SYSTEM->PortA_PullEN);
GPIO_Pull_Select = &(SYSTEM->PortA_PullSelect);
GPIO_FuncMuxL = &(SYSTEM->PortA_L_FuncMux);
GPIO_FuncMuxH = &(SYSTEM->PortA_H_FuncMux);
}
else if (GPIOx == GPIOB)
{
GPIO_Pull_EN = &(SYSTEM->PortB_PullEN);
GPIO_Pull_Select = &(SYSTEM->PortB_PullSelect);
GPIO_FuncMuxL = &(SYSTEM->PortB_L_FuncMux);
GPIO_FuncMuxH = &(SYSTEM->PortB_H_FuncMux);
}
else if (GPIOx == GPIOC)
{
GPIO_Pull_EN = &(SYSTEM->PortC_PullEN);
GPIO_Pull_Select = &(SYSTEM->PortC_PullSelect);
GPIO_FuncMuxL = &(SYSTEM->PortC_L_FuncMux);
GPIO_FuncMuxH = &(SYSTEM->PortC_H_FuncMux);
}
else if (GPIOx == GPIOD)
{
GPIO_Pull_EN = &(SYSTEM->PortD_PullEN);
GPIO_Pull_Select = &(SYSTEM->PortD_PullSelect);
GPIO_FuncMuxL = &(SYSTEM->PortD_L_FuncMux);
GPIO_FuncMuxH = &(SYSTEM->PortD_H_FuncMux);
}
/* Configure Select pins */
while ((GPIO_Init->Pin) >> lu32_Position != 0)
{
/* Get current pin position */
lu32_Current_Pin = (GPIO_Init->Pin) & (1uL << lu32_Position);
if (lu32_Current_Pin)
{
switch (GPIO_Init->Mode)
{
case GPIO_MODE_INPUT:
{
GPIOx->GPIO_OutputEN |= lu32_Current_Pin;
GPIOx->EXTI_EN &= ~lu32_Current_Pin;
GPIOx->EXTI_INT_EN &= ~lu32_Current_Pin;
}break;
case GPIO_MODE_INPUT_HRS:
{
GPIOx->GPIO_OutputEN |= lu32_Current_Pin;
GPIOx->EXTI_EN &= ~lu32_Current_Pin;
GPIOx->EXTI_INT_EN &= ~lu32_Current_Pin;
/* High Resistance Mode does not pull up or down */
GPIO_Init->Pull = GPIO_NOPULL;
}break;
case GPIO_MODE_OUTPUT_PP:
{
GPIOx->GPIO_OutputEN &= ~lu32_Current_Pin;
GPIOx->EXTI_EN &= ~lu32_Current_Pin;
GPIOx->EXTI_INT_EN &= ~lu32_Current_Pin;
}break;
case GPIO_MODE_AF_PP:
{
/* Port 0 ~ 7 */
if (lu32_Position < 8)
{
*GPIO_FuncMuxL = (*GPIO_FuncMuxL & ~(0xF << (lu32_Position * 4))) | (GPIO_Init->Alternate << (lu32_Position * 4));
}
/* Port 8 ~ 15 */
else
{
*GPIO_FuncMuxH = (*GPIO_FuncMuxH & ~(0xF << ((lu32_Position - 8) * 4))) | (GPIO_Init->Alternate << ((lu32_Position - 8) * 4));
}
}break;
case GPIO_MODE_EXTI_IT_RISING:
case GPIO_MODE_EXTI_IT_FALLING:
case GPIO_MODE_EXTI_IT_HIGH_LEVEL:
case GPIO_MODE_EXTI_IT_LOW_LEVEL:
{
GPIOx->EXTI_TYPE = (GPIOx->EXTI_TYPE & ~(0x3 << (lu32_Position * 2))) | ((GPIO_Init->Mode & 0x3) << (lu32_Position * 2));
GPIOx->GPIO_OutputEN |= lu32_Current_Pin;
GPIOx->EXTI_EN |= lu32_Current_Pin;
GPIOx->EXTI_INT_EN &= ~lu32_Current_Pin;
}break;
default: break;
}
/* GPIO Function */
if (GPIO_Init->Mode & GPIO_MODE_IO_MASK)
{
/* Port 0 ~ 7 */
if (lu32_Position < 8)
{
*GPIO_FuncMuxL = *GPIO_FuncMuxL & ~(0xF << (lu32_Position * 4));
}
/* Port 8 ~ 15 */
else
{
*GPIO_FuncMuxH = *GPIO_FuncMuxH & ~(0xF << ((lu32_Position - 8) * 4));
}
}
/* Set Pull UP/DOWN or NO Pull */
if (GPIO_Init->Pull == GPIO_NOPULL)
{
*GPIO_Pull_EN &= ~lu32_Current_Pin;
}
else if (GPIO_Init->Pull == GPIO_PULLUP)
{
*GPIO_Pull_EN |= lu32_Current_Pin;
*GPIO_Pull_Select |= lu32_Current_Pin;
}
else if (GPIO_Init->Pull == GPIO_PULLDOWN)
{
*GPIO_Pull_EN |= lu32_Current_Pin;
*GPIO_Pull_Select &= ~lu32_Current_Pin;
}
}
lu32_Position++;
}
}
/************************************************************************************
* @fn gpio_set_portpull
*
* @brief set port pull
*
* @param GPIOx: where x can be (GPIOA ~ GPIOB) to select the GPIO peripheral.
* @param fu16_Pin: to select the Pin (1bit ~ 1Pin). @ref GPIO_pins
* @param fe_Pull: pull up/pull down/no pull @ref enum_Pull_t
* @return pin status.
*/
void gpio_set_portpull(GPIO_TypeDef *GPIOx, uint16_t fu16_Pin, enum_Pull_t fe_Pull)
{
uint32_t lu32_Position = 0;
uint32_t lu32_Current_Pin;
volatile uint32_t *GPIO_Pull_EN;
volatile uint32_t *GPIO_Pull_Select;
/* Select the group register */
if (GPIOx == GPIOA)
{
GPIO_Pull_EN = &(SYSTEM->PortA_PullEN);
GPIO_Pull_Select = &(SYSTEM->PortA_PullSelect);
}
else if (GPIOx == GPIOB)
{
GPIO_Pull_EN = &(SYSTEM->PortB_PullEN);
GPIO_Pull_Select = &(SYSTEM->PortB_PullSelect);
}
else if (GPIOx == GPIOC)
{
GPIO_Pull_EN = &(SYSTEM->PortC_PullEN);
GPIO_Pull_Select = &(SYSTEM->PortC_PullSelect);
}
else if (GPIOx == GPIOD)
{
GPIO_Pull_EN = &(SYSTEM->PortD_PullEN);
GPIO_Pull_Select = &(SYSTEM->PortD_PullSelect);
}
/* Configure Select pins */
while (fu16_Pin >> lu32_Position != 0)
{
/* Get current pin position */
lu32_Current_Pin = fu16_Pin & (1uL << lu32_Position);
if (lu32_Current_Pin)
{
/* Set Pull UP or DOWN or NO */
if (fe_Pull == GPIO_NOPULL)
{
*GPIO_Pull_EN &= ~lu32_Current_Pin;
}
else if (fe_Pull == GPIO_PULLUP)
{
*GPIO_Pull_EN |= lu32_Current_Pin;
*GPIO_Pull_Select |= lu32_Current_Pin;
}
else if (fe_Pull == GPIO_PULLDOWN)
{
*GPIO_Pull_EN |= lu32_Current_Pin;
*GPIO_Pull_Select &= ~lu32_Current_Pin;
}
}
lu32_Position++;
}
}
/************************************************************************************
* @fn gpio_write_group
*
* @brief write gpio status, The unit is group.
*
* @param GPIOx: where x can be (GPIOA ~ GPIOD) to select the GPIO peripheral.
* @param fu16_GroupStatus: Group Status.(1bit ~ 1Pin)
*/
void gpio_write_group(GPIO_TypeDef *GPIOx, uint16_t fu16_GroupStatus)
{
GPIOx->GPIO_OUT_DATA = fu16_GroupStatus;
}
/************************************************************************************
* @fn gpio_write_pin
*
* @brief write gpio status, The unit is pin.
*
* @param GPIOx: where x can be (GPIOA ~ GPIOD) to select the GPIO peripheral.
* @param fu16_Pin: to select the Pin (1bit ~ 1Pin). @ref GPIO_pins
* @param fe_PinStatus: pin Status. @ref enum_PinStatus_t
*/
void gpio_write_pin(GPIO_TypeDef *GPIOx, uint16_t fu16_Pin, enum_PinStatus_t fe_PinStatus)
{
if (fe_PinStatus)
{
GPIOx->GPIO_BIT_SET = fu16_Pin;
}
else
{
GPIOx->GPIO_BIT_CLEAR = fu16_Pin;
}
}
/************************************************************************************
* @fn gpio_read_group
*
* @brief read gpio status, The unit is group.
*
* @param GPIOx: where x can be (GPIOA ~ GPIOD) to select the GPIO peripheral.
* @return group status.(1bit ~ 1Pin)
*/
uint16_t gpio_read_group(GPIO_TypeDef *GPIOx)
{
return GPIOx->GPIO_IN_DATA;
}
/************************************************************************************
* @fn gpio_read_pin
*
* @brief read gpio status, The unit is pin.
*
* @param GPIOx: where x can be (GPIOA ~ GPIOD) to select the GPIO peripheral.
* @param fu16_Pin: to select the Pin (1bit ~ 1Pin). @ref GPIO_pins
* @return pin status.
*/
enum_PinStatus_t gpio_read_pin(GPIO_TypeDef *GPIOx, uint16_t fu16_Pin)
{
enum_PinStatus_t le_PinStatus;
le_PinStatus = (GPIOx->GPIO_IN_DATA & fu16_Pin) ? GPIO_PIN_SET : GPIO_PIN_CLEAR;
return le_PinStatus;
}
/************************************************************************************
* @fn gpio_drive_current_config
*
* @brief gpio drive current config.
*
* @param GPIOx: where x can be (GPIOA ~ GPIOD) to select the GPIO peripheral.
* @param fu16_Pin: to select the Pin (1bit ~ 1Pin). @ref GPIO_pins
* @param fe_GPIO_Drive: Drive Current. @ref enum_GPIO_Drive_Current_t
*/
void gpio_drive_current_config(GPIO_TypeDef *GPIOx, uint16_t fu16_Pin, enum_GPIO_Drive_Current_t fe_GPIO_Drive)
{
uint32_t lu32_Position = 0;
uint32_t lu32_Current_Pin;
/* Configure Select pins */
while (fu16_Pin >> lu32_Position != 0)
{
/* Get current pin position */
lu32_Current_Pin = fu16_Pin & (1uL << lu32_Position);
if (lu32_Current_Pin)
{
if (GPIOx == GPIOA)
SYSTEM->PortA_DriveCfg = (SYSTEM->PortA_DriveCfg & ~(0x3 << (lu32_Position * 2))) | (fe_GPIO_Drive << (lu32_Position * 2));
else if (GPIOx == GPIOB)
SYSTEM->PortB_DriveCfg = (SYSTEM->PortB_DriveCfg & ~(0x3 << (lu32_Position * 2))) | (fe_GPIO_Drive << (lu32_Position * 2));
else if (GPIOx == GPIOC)
SYSTEM->PortC_DriveCfg = (SYSTEM->PortC_DriveCfg & ~(0x3 << (lu32_Position * 2))) | (fe_GPIO_Drive << (lu32_Position * 2));
else if (GPIOx == GPIOD)
SYSTEM->PortD_DriveCfg = (SYSTEM->PortD_DriveCfg & ~(0x3 << (lu32_Position * 2))) | (fe_GPIO_Drive << (lu32_Position * 2));
}
lu32_Position++;
}
}
/************************************************************************************
* @fn exti_interrupt_enable
*
* @brief exti line interrupt enable.
*
* @param GPIOx: where x can be (GPIOA ~ GPIOD) to select the GPIO peripheral.
* @param fu16_EXTI_Line: to select the EXTI line.(1bit ~ 1Pin)
*/
void exti_interrupt_enable(GPIO_TypeDef *GPIOx, uint16_t fu16_EXTI_Line)
{
GPIOx->EXTI_INT_EN |= fu16_EXTI_Line;
}
/************************************************************************************
* @fn exti_interrupt_disable
*
* @brief exti line interrupt disable.
*
* @param GPIOx: where x can be (GPIOA ~ GPIOD) to select the GPIO peripheral.
* @param fu16_EXTI_Line: to select the EXTI line (1bit ~ 1Pin). @ref EXTI_line_index
*/
void exti_interrupt_disable(GPIO_TypeDef *GPIOx, uint16_t fu16_EXTI_Line)
{
GPIOx->EXTI_INT_EN &= ~fu16_EXTI_Line;
}
/************************************************************************************
* @fn exti_get_LineStatus
*
* @brief get exti line interrupt status.
*
* @param GPIOx: where x can be (GPIOA ~ GPIOD) to select the GPIO peripheral.
* @param fu8_EXTI_Line: to select the EXTI line (1bit ~ 1Pin). @ref EXTI_line_index
* @return true: interrupt activate
* false: interrupt inactivate
*/
bool exti_get_LineStatus(GPIO_TypeDef *GPIOx, uint16_t fu16_EXTI_Line)
{
bool lb_EXTIStatus;
lb_EXTIStatus = (GPIOx->EXTI_INT_STATUS & fu16_EXTI_Line) ? true : false;
return lb_EXTIStatus;
}
/************************************************************************************
* @fn exti_clear_LineStatus
*
* @brief clear exti line interrupt status.
*
* @param GPIOx: where x can be (GPIOA ~ GPIOD) to select the GPIO peripheral.
* @param fu8_EXTI_Line: to select the EXTI line (1bit ~ 1Pin). @ref EXTI_line_index
*/
void exti_clear_LineStatus(GPIO_TypeDef *GPIOx, uint16_t fu16_EXTI_Line)
{
GPIOx->EXTI_INT_STATUS |= fu16_EXTI_Line;
}
/************************************************************************************
* @fn exti_set_FilterCNT
*
* @brief set exti line filer.
*
* @param GPIOx: where x can be (GPIOA ~ GPIOD) to select the GPIO peripheral.
* @param fu16_EXTI_Line: to select the EXTI line (1bit ~ 1Pin). @ref EXTI_line_index
* @param fu8_DIV: filter clock divider. (can be a 4-bit value)
* @param fu16_CNT: filter count. (can be a 12-bit value)
*/
void exti_set_Filter(GPIO_TypeDef *GPIOx, uint16_t fu16_EXTI_Line, uint8_t fu8_DIV, uint16_t fu16_CNT)
{
uint32_t lu32_Position = 0;
uint32_t lu32_Current_Pin;
/* Init write value */
uint32_t lu32_WriteValue = fu8_DIV << 12 | fu16_CNT;
/* Configure Select pins */
while (fu16_EXTI_Line >> lu32_Position != 0)
{
/* Get current pin position */
lu32_Current_Pin = fu16_EXTI_Line & (1uL << lu32_Position);
if (lu32_Current_Pin)
{
GPIOx->EXTI_CNT[lu32_Position] = lu32_WriteValue;
}
lu32_Position++;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,513 @@
/*
******************************************************************************
* @file driver_i2s.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief I2S module driver.
* This file provides firmware functions to manage the
* Inter<65><72>IC Sound (I2S) peripheral
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
/************************************************************************************
* @fn i2s_IRQHandler
*
* @brief Handle I2S interrupt request.
*
* @param huart: I2S handle.
*/
//void i2s_IRQHandler(I2S_HandleTypeDef *hi2s)
//{
// /* Format 20Bit/24Bit/32bit */
// if (hi2s->Init.DataFormat > I2S_DATA_FORMAT_16BIT)
// {
// /* TxFIFO half full interrupt enable */
// if (__I2S_INT_IS_ENANLE(hi2s->I2Sx, I2S_TX_FIFOS_HALF_FULL))
// {
// /* FIFO half full */
// if ((__I2S_GET_INT_STATUS(hi2s->I2Sx) & I2S_TX_FIFOS_HALF_FULL))
// {
// while(!(__I2S_GET_INT_STATUS(hi2s->I2Sx) & I2S_TX_FIFOS_FULL))
// {
// /* right channel*/
// if (hi2s->u32_TxCount % 2)
// {
// hi2s->I2Sx->DATA_R = hi2s->p_TxData[hi2s->u32_TxCount++];
// }
// /* left channel*/
// else
// {
// hi2s->I2Sx->DATA_L = hi2s->p_TxData[hi2s->u32_TxCount++];
// }
//
// if (hi2s->u32_TxCount >= hi2s->u32_TxSize)
// {
// __I2S_INT_DISABLE(hi2s->I2Sx, I2S_TX_FIFOS_HALF_FULL);
//
// hi2s->b_TxBusy = false;
//
// break;
// }
// }
// }
// }
// /* Rx FIFO full interrupt enable */
// if(__I2S_INT_IS_ENANLE(hi2s->I2Sx, I2S_RX_FIFOS_HALF_FULL))
// {
// /* FIFO half full */
// if ((__I2S_GET_INT_STATUS(hi2s->I2Sx) & I2S_RX_FIFOS_HALF_FULL))
// {
// while(!(__I2S_GET_INT_STATUS(hi2s->I2Sx) & I2S_RX_FIFOS_EMPTY))
// {
// /* right channel*/
// if (hi2s->u32_RxCount % 2)
// {
// hi2s->p_RxData[hi2s->u32_RxCount++] = hi2s->I2Sx->DATA_R;
// }
// /* left channel*/
// else
// {
// hi2s->p_RxData[hi2s->u32_RxCount++] = hi2s->I2Sx->DATA_L;
// }
//
// if(hi2s->u32_RxCount >= hi2s->u32_RxSize)
// {
// __I2S_INT_DISABLE(hi2s->I2Sx, I2S_RX_FIFOS_HALF_FULL);
//
// hi2s->b_RxBusy = false;
// break;
// }
// }
// }
// }
// }
// /* Format 8Bit/16Bit */
// else
// {
// /* TxFIFO half full interrupt enable */
// if (__I2S_INT_IS_ENANLE(hi2s->I2Sx, I2S_TX_L_FIFO_HALF_FULL))
// {
// /* FIFO half full */
// if ((__I2S_GET_INT_STATUS(hi2s->I2Sx) & I2S_TX_L_FIFO_HALF_FULL))
// {
// while(!(__I2S_GET_INT_STATUS(hi2s->I2Sx) & I2S_TX_L_FIFO_FULL))
// {
// hi2s->I2Sx->DATA_L = hi2s->p_TxData[hi2s->u32_TxCount++];
//
// if (hi2s->u32_TxCount >= hi2s->u32_TxSize)
// {
// __I2S_INT_DISABLE(hi2s->I2Sx, I2S_TX_L_FIFO_HALF_FULL);
//
// hi2s->b_TxBusy = false;
//
// break;
// }
// }
// }
// }
// /* Rx FIFO full interrupt enable */
// if(__I2S_INT_IS_ENANLE(hi2s->I2Sx, I2S_RX_L_FIFO_HALF_FULL))
// {
// /* FIFO half full */
// if ((__I2S_GET_INT_STATUS(hi2s->I2Sx) & I2S_RX_L_FIFO_HALF_FULL))
// {
// while(!(__I2S_GET_INT_STATUS(hi2s->I2Sx) & I2S_RX_L_FIFO_EMPTY))
// {
// hi2s->p_RxData[hi2s->u32_RxCount++] = hi2s->I2Sx->DATA_L;
//
// if(hi2s->u32_RxCount >= hi2s->u32_RxSize)
// {
// __I2S_INT_DISABLE(hi2s->I2Sx, I2S_RX_L_FIFO_HALF_FULL);
//
// hi2s->b_RxBusy = false;
// break;
// }
// }
// }
// }
// }
//}
void i2s_IRQHandler(I2S_HandleTypeDef *hi2s)
{
/* Format 20Bit/24Bit/32bit */
if (hi2s->Init.DataFormat > I2S_DATA_FORMAT_16BIT)
{
/* TxFIFO half full interrupt enable */
if (__I2S_INT_IS_ENANLE(hi2s->I2Sx, I2S_TX_FIFOS_ALMOST_EMPTY))
{
/* FIFO half full */
if ((__I2S_GET_INT_STATUS(hi2s->I2Sx) & I2S_TX_FIFOS_ALMOST_EMPTY))
{
if (hi2s->TxIntCallback)
{
hi2s->TxIntCallback(hi2s);
}
else
{
for (uint32_t i=0; i<I2S_FIFO_HALF_DEPTH; i++)
{
hi2s->I2Sx->DATA_L = 0;
hi2s->I2Sx->DATA_R = 0;
}
}
}
}
/* Rx FIFO full interrupt enable */
if(__I2S_INT_IS_ENANLE(hi2s->I2Sx, I2S_RX_FIFOS_HALF_FULL))
{
/* FIFO half full */
if ((__I2S_GET_INT_STATUS(hi2s->I2Sx) & I2S_RX_FIFOS_HALF_FULL))
{
if (hi2s->RxIntCallback)
{
hi2s->RxIntCallback(hi2s);
}
else
{
for (uint32_t i=0; i<I2S_FIFO_HALF_DEPTH; i++)
{
volatile uint32_t l_data = hi2s->I2Sx->DATA_L;
volatile uint32_t r_data = hi2s->I2Sx->DATA_R;
}
}
}
}
}
/* Format 8Bit/16Bit */
else
{
/* TxFIFO half full interrupt enable */
if (__I2S_INT_IS_ENANLE(hi2s->I2Sx, I2S_TX_L_FIFO_ALMOST_EMPTY))
{
/* FIFO half full */
if ((__I2S_GET_INT_STATUS(hi2s->I2Sx) & I2S_TX_L_FIFO_ALMOST_EMPTY))
{
if (hi2s->TxIntCallback)
{
hi2s->TxIntCallback(hi2s);
}
else
{
for (uint32_t i=0; i<I2S_FIFO_HALF_DEPTH; i++)
{
hi2s->I2Sx->DATA_L = 0;
}
}
}
}
/* Rx FIFO full interrupt enable */
if(__I2S_INT_IS_ENANLE(hi2s->I2Sx, I2S_RX_L_FIFO_HALF_FULL))
{
/* FIFO half full */
if ((__I2S_GET_INT_STATUS(hi2s->I2Sx) & I2S_RX_L_FIFO_HALF_FULL))
{
if (hi2s->RxIntCallback)
{
hi2s->RxIntCallback(hi2s);
}
else
{
for (uint32_t i=0; i<I2S_FIFO_HALF_DEPTH; i++)
{
volatile uint32_t l_data = hi2s->I2Sx->DATA_L;
}
}
}
}
}
}
/************************************************************************************
* @fn i2s_init
*
* @brief Initialize the I2S peripheral according to the specified
* parameters in the struct_I2SInit_t
*
* @param hi2s: I2S handle.
*/
void i2s_init(I2S_HandleTypeDef *hi2s)
{
hi2s->b_TxBusy = false;
hi2s->b_RxBusy = false;
/* disable all interrupt */
__I2S_INT_DISABLE(hi2s->I2Sx, I2S_ALL_FIFO_STATUS);
/* Enable Rx/Tx FIFO */
__I2S_RxFIFO_EN(hi2s->I2Sx);
__I2S_TxFIFO_EN(hi2s->I2Sx);
/* Clear Rx/Tx FIFO */
__I2S_RxFIFO_CLR(hi2s->I2Sx);
__I2S_TxFIFO_CLR(hi2s->I2Sx);
/* left and right channels operate simultaneously */
__I2S_WD_SWAP_HIGH16SIZE_RIGHT(hi2s->I2Sx);
/* config mode */
hi2s->I2Sx->CTRL0.MSTSLV = hi2s->Init.Mode;
/* Calculate audio frequency */
hi2s->I2Sx->FrmDiv.BCLKDIV = hi2s->Init.BCLKDIV - 1;
/* Calculate channel length */
hi2s->I2Sx->FrmDiv.FRMDIV = hi2s->Init.ChannelLength - 1;
/* Data length */
hi2s->I2Sx->CTRL1.I2S_DATA_LENGTH = hi2s->Init.DataFormat;
switch (hi2s->Init.Standard)
{
/* philips */
case I2S_STANDARD_PHILIPS:
{
hi2s->I2Sx->CTRL1.I2S_NORMAL = 1;
__I2S_ENABLE(hi2s->I2Sx);
}break;
/* MSB */
case I2S_STANDARD_MSB:
{
hi2s->I2Sx->CTRL1.I2S_NORMAL = 0;
hi2s->I2Sx->CTRL1.I2S_ADJUST = 0;
__I2S_FRAME_INV_ENABLE(hi2s->I2Sx);
__I2S_ENABLE(hi2s->I2Sx);
}break;
/* LSB */
case I2S_STANDARD_LSB:
{
uint32_t data_length[5] = {8,16,20,24,32};
hi2s->I2Sx->CTRL1.I2S_NORMAL = 0;
hi2s->I2Sx->CTRL1.I2S_ADJUST = 1;
hi2s->I2Sx->CTRL1.I2SFBOFF = hi2s->Init.ChannelLength - data_length[hi2s->Init.DataFormat];
__I2S_FRAME_INV_ENABLE(hi2s->I2Sx);
__I2S_ENABLE(hi2s->I2Sx);
}break;
/* PCM */
case I2S_STANDARD_PCM:
{
/* Mono or Stereo select*/
hi2s->I2Sx->PCM_RHYCTRL.PCM_SAMPTYPE = 0;
hi2s->I2Sx->PCM_GENCTRL.PCM_MONO_STEREO = 0;
/* Frame Synchronization signal */
hi2s->I2Sx->PCM_RHYCTRL.PCM_FSYNCSHP = 0;
/* Sample size and slots */
__I2S_PCM_SLOTS_SET(hi2s->I2Sx, 1);
__I2S_PCM_SAMPLESIZE_16BIT(hi2s->I2Sx);
/* ENABLE PCM */
hi2s->I2Sx->PCM_RHYCTRL.PCM_DOUTCFG = 1;
__I2S_PCM_ENABLE(hi2s->I2Sx);
}break;
default: break;
}
}
/************************************************************************************
* @fn i2s_deinit
*
* @brief deinit an ongoing i2s.
*
* @param hi2s: I2S handle.
*/
void i2s_deinit(I2S_HandleTypeDef *hi2s)
{
__I2S_PCM_DISABLE(hi2s->I2Sx);
__I2S_DISABLE(hi2s->I2Sx);
hi2s->b_TxBusy = false;
hi2s->b_RxBusy = false;
}
/************************************************************************************
* @fn i2s_transmit_IT
*
* @brief Transmit an I2S data in interrupt mode, user should send data in TxCallback with
* i2s_send_data function.
*
* @param huart: I2S handle.
*/
bool i2s_transmit_IT(I2S_HandleTypeDef *hi2s)
{
if (hi2s->b_TxBusy) return false;
hi2s->b_TxBusy = true;
__I2S_L_TxFIFO_EMPTY_LEVEL(hi2s->I2Sx, I2S_FIFO_HALF_DEPTH);
__I2S_R_TxFIFO_EMPTY_LEVEL(hi2s->I2Sx, I2S_FIFO_HALF_DEPTH);
/* Format 20Bit/24Bit/32bit */
if (hi2s->Init.DataFormat > I2S_DATA_FORMAT_16BIT)
{
__I2S_LR_WD_DISABLE(hi2s->I2Sx);
__I2S_INT_ENABLE(hi2s->I2Sx, I2S_TX_FIFOS_ALMOST_EMPTY);
}
/* Format 8Bit/16Bit */
else
{
__I2S_LR_WD_ENABLE(hi2s->I2Sx);
__I2S_INT_ENABLE(hi2s->I2Sx, I2S_TX_L_FIFO_ALMOST_EMPTY);
}
return true;
}
/************************************************************************************
* @fn i2s_receive_IT
*
* @brief Receive an I2S data in interrupt mode. User read received data with function
* i2s_read_data in RxCallback.
*
* @param huart: I2S handle.
*/
bool i2s_receive_IT(I2S_HandleTypeDef *hi2s)
{
if (hi2s->b_RxBusy) return false;
hi2s->b_RxBusy = true;
__I2S_L_RxFIFO_FULL_LEVEL(hi2s->I2Sx, 16);
__I2S_R_RxFIFO_FULL_LEVEL(hi2s->I2Sx, 16);
/* Format 20Bit/24Bit/32bit */
if (hi2s->Init.DataFormat > I2S_DATA_FORMAT_16BIT)
{
__I2S_LR_WD_DISABLE(hi2s->I2Sx);
__I2S_INT_ENABLE(hi2s->I2Sx, I2S_RX_FIFOS_HALF_FULL);
}
/* Format 8Bit/16Bit */
else
{
__I2S_LR_WD_ENABLE(hi2s->I2Sx);
__I2S_INT_ENABLE(hi2s->I2Sx, I2S_RX_L_FIFO_HALF_FULL);
}
return true;
}
/************************************************************************************
* @fn i2s_read_data
*
* @brief Read data from RX FIFO. One sample contains left and right channel data. When
* DataFormat is not more than 16-bits, one sample takes 32-bits, left channel data
* is stored in high 16-bits and right channel data is stored in low 16-bits. When
* DataFormat is more than 16-bits, one sample takes 2 words.
*
* @param huart: I2S handle.
* buffer: buffer used to store received data.
* samples: How many samples expected to receive.
*
* @return How many samples read from RX FIFO
*/
uint32_t i2s_read_data(I2S_HandleTypeDef *hi2s, uint32_t *buffer, uint32_t samples)
{
uint32_t count = 0;
if (hi2s->Init.DataFormat > I2S_DATA_FORMAT_16BIT)
{
while ((!(__I2S_GET_INT_STATUS(hi2s->I2Sx) & I2S_RX_FIFOS_EMPTY))
&& (count < samples))
{
buffer[count] = hi2s->I2Sx->DATA_L;
buffer[count] = hi2s->I2Sx->DATA_R;
count++;
}
}
else
{
__I2S_LR_WD_ENABLE(hi2s->I2Sx);
while ((!(__I2S_GET_INT_STATUS(hi2s->I2Sx) & I2S_RX_L_FIFO_EMPTY))
&& (count < samples))
{
buffer[count] = hi2s->I2Sx->DATA_L;
count++;
}
}
return count;
}
/************************************************************************************
* @fn i2s_send_data
*
* @brief write data to TX FIFO. One sample contains left and right channel data. When
* DataFormat is not more than 16-bits, one sample takes 32-bits, left channel data
* is stored in high 16-bits and right channel data is stored in low 16-bits. When
* DataFormat is more than 16-bits, one sample takes 2 words.
*
* @param huart: I2S handle.
* buffer: buffer used to store sending data.
* samples: How many samples expected to send.
*
* @return How many samples sent to TX FIFO
*/
uint32_t i2s_send_data(I2S_HandleTypeDef *hi2s, uint32_t *buffer, uint32_t samples)
{
uint32_t count = 0;
if (hi2s->Init.DataFormat > I2S_DATA_FORMAT_16BIT)
{
while ((!(__I2S_GET_INT_STATUS(hi2s->I2Sx) & I2S_TX_FIFOS_FULL))
&& (count < samples))
{
hi2s->I2Sx->DATA_L = buffer[count];
hi2s->I2Sx->DATA_R = buffer[count];
count++;
}
}
else
{
__I2S_LR_WD_ENABLE(hi2s->I2Sx);
while ((!(__I2S_GET_INT_STATUS(hi2s->I2Sx) & I2S_TX_L_FIFO_FULL))
&& (count < samples))
{
hi2s->I2Sx->DATA_L = buffer[count];
count++;
}
}
return count;
}
/************************************************************************************
* @fn i2s_transmit_DMA
*
* @brief Transmit an amount of data in DMA mode.
*/
void i2s_transmit_DMA(I2S_HandleTypeDef *hi2s)
{
hi2s->I2Sx->DMA_CFG.DMACR_L_TX = 1;
hi2s->I2Sx->DMA_CFG.DMACR_R_TX = 1;
/* Tx empty dma level */
__I2S_TX_DMA_EMPTY_LEVEL(hi2s->I2Sx, 16);
}
/************************************************************************************
* @fn i2s_receive_DMA
*
* @brief Receive an amount of data in DMA mode.
*/
void i2s_receive_DMA(I2S_HandleTypeDef *hi2s)
{
hi2s->I2Sx->DMA_CFG.DMACR_L_RX = 1;
hi2s->I2Sx->DMA_CFG.DMACR_R_RX = 1;
/* Rx empty dma level */
__I2S_RX_DMA_EMPTY_LEVEL(hi2s->I2Sx, 16);
}

View File

@ -0,0 +1,74 @@
/*
******************************************************************************
* @file driver_iir.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2023
* @brief IIR module driver.
* This file provides firmware functions to manage the
* IIR filter peripheral
******************************************************************************
* @attention
*
* Copyright (c) 2023 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
/******************************************************************************
* @fn iir_init
*
* @brief Initialize the IIR according to the specified parameters
* in the IIR_HandleTypeDef
*
* @param hiir : IIR Handle.
*/
void iir_init(IIR_InitTypeDef *hiir)
{
__IIR_SOFTRST_SET();
__IIR_SOFTRST_CLEAR();
for(int i = 0; i < 20; i++)
{
IIR_FILTER->IIR_COEF[i] = hiir->IIRCoef[i];
}
IIR_FILTER->IIR_CTRL.N_DIV = hiir->N_Div;
IIR_FILTER->IIR_CTRL.ORDER_SEL = hiir->Order_Sel;
IIR_FILTER->IIR_CTRL.NODE_SEL = hiir->Node_Sel;
IIR_FILTER->IIR_CTRL.NBYTE_SEL = hiir->Nbytes_Sel;
__IIR_RxFIFO_THRESHOLD_LEVEL(0x20);
__IIR_TxFIFO_THRESHOLD_LEVEL(0x20);
}
/******************************************************************************
* @fn iir_filter_start
*
* @brief Start iir filter
*
* @param fp_Data_In : the data need to handle
* fp_Data_Out : the output data
* fu32_Size : the size of data which is need to handle
*/
void iir_filter_start(uint32_t *fp_Data_In, uint32_t *fp_Data_Out, uint32_t fu32_Size)
{
while(fu32_Size)
{
if(!__IIR_GET_FIFO_STATUS(TX_FIFO_FULL))
{
IIR_FILTER->IIR_FIFO = *fp_Data_In++;
fu32_Size--;
}
while(!__IIR_GET_FIFO_STATUS(RX_FIFO_EMPTY))
{
*fp_Data_Out++ = IIR_FILTER->IIR_FIFO;
}
}
__IIR_SOFTRST_SET();
__IIR_SOFTRST_CLEAR();
}

View File

@ -0,0 +1,155 @@
/*
******************************************************************************
* @file driver_ipc.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief ipc module driver.
* This file provides firmware functions to manage the
* IPC peripheral
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
/************************************************************************************
* @fn ipc_IRQHandler
*
* @brief Handle IPC interrupt request.
*
* @param hipc: IPC handle.
*/
void ipc_IRQHandler(IPC_HandleTypeDef *hipc)
{
uint32_t status;
volatile uint32_t msg;
status = hipc->IPCx->IPC_ISR_STA.Word;
if (status & IPC_INT_STATUS_CH0_IN) {
msg = hipc->IPCx->IPC_MSG_IN0;
if (hipc->RxCallback) {
hipc->RxCallback(hipc, IPC_CH_0, msg);
}
hipc->IPCx->IPC_ISR_STA.Word = IPC_INT_STATUS_CH0_IN;
hipc->IPCx->IPC_MSG_CLR.CH0_IN = 1;
}
if (status & IPC_INT_STATUS_CH1_IN) {
msg = hipc->IPCx->IPC_MSG_IN1;
if (hipc->RxCallback) {
hipc->RxCallback(hipc, IPC_CH_1, msg);
}
hipc->IPCx->IPC_ISR_STA.Word = IPC_INT_STATUS_CH1_IN;
hipc->IPCx->IPC_MSG_CLR.CH1_IN = 1;
}
if (status & IPC_INT_STATUS_CH2_IN) {
msg = hipc->IPCx->IPC_MSG_IN2;
if (hipc->RxCallback) {
hipc->RxCallback(hipc, IPC_CH_2, msg);
}
hipc->IPCx->IPC_ISR_STA.Word = IPC_INT_STATUS_CH2_IN;
hipc->IPCx->IPC_MSG_CLR.CH2_IN = 1;
}
if (status & IPC_INT_STATUS_CH3_IN) {
msg = hipc->IPCx->IPC_MSG_IN3;
if (hipc->RxCallback) {
hipc->RxCallback(hipc, IPC_CH_3, msg);
}
hipc->IPCx->IPC_ISR_STA.Word = IPC_INT_STATUS_CH3_IN;
hipc->IPCx->IPC_MSG_CLR.CH3_IN = 1;
}
status = hipc->IPCx->IPC_ISR_STA.Word;
if ((status & IPC_INT_STATUS_CH0_OUT)) {
hipc->IPCx->IPC_ISR_STA.Word = IPC_INT_STATUS_CH0_OUT;
if (hipc->TxCallback) {
hipc->TxCallback(hipc, IPC_CH_0);
}
}
if ((status & IPC_INT_STATUS_CH1_OUT)) {
hipc->IPCx->IPC_ISR_STA.Word = IPC_INT_STATUS_CH1_OUT;
if (hipc->TxCallback) {
hipc->TxCallback(hipc, IPC_CH_1);
}
}
if ((status & IPC_INT_STATUS_CH2_OUT)) {
hipc->IPCx->IPC_ISR_STA.Word = IPC_INT_STATUS_CH2_OUT;
if (hipc->TxCallback) {
hipc->TxCallback(hipc, IPC_CH_2);
}
}
if ((status & IPC_INT_STATUS_CH3_OUT)) {
hipc->IPCx->IPC_ISR_STA.Word = IPC_INT_STATUS_CH3_OUT;
if (hipc->TxCallback) {
hipc->TxCallback(hipc, IPC_CH_3);
}
}
}
void ipc_init(IPC_HandleTypeDef *hipc)
{
if (hipc->RxEnableChannels & IPC_CH_0) {
hipc->IPCx->IPC_CTRL.Bits.CH0_IN_EN = 1;
hipc->IPCx->IPC_ISR_EN.Bits.CH0_IN = 1;
}
if (hipc->RxEnableChannels & IPC_CH_1) {
hipc->IPCx->IPC_CTRL.Bits.CH1_IN_EN = 1;
hipc->IPCx->IPC_ISR_EN.Bits.CH1_IN = 1;
}
if (hipc->RxEnableChannels & IPC_CH_2) {
hipc->IPCx->IPC_CTRL.Bits.CH2_IN_EN = 1;
hipc->IPCx->IPC_ISR_EN.Bits.CH2_IN = 1;
}
if (hipc->RxEnableChannels & IPC_CH_3) {
hipc->IPCx->IPC_CTRL.Bits.CH3_IN_EN = 1;
hipc->IPCx->IPC_ISR_EN.Bits.CH3_IN = 1;
}
if (hipc->TxEnableChannels & IPC_CH_0) {
hipc->IPCx->IPC_CTRL.Bits.CH0_OUT_EN = 1;
hipc->IPCx->IPC_ISR_EN.Bits.CH0_OUT = 1;
}
if (hipc->TxEnableChannels & IPC_CH_1) {
hipc->IPCx->IPC_CTRL.Bits.CH1_OUT_EN = 1;
hipc->IPCx->IPC_ISR_EN.Bits.CH1_OUT = 1;
}
if (hipc->TxEnableChannels & IPC_CH_2) {
hipc->IPCx->IPC_CTRL.Bits.CH2_OUT_EN = 1;
hipc->IPCx->IPC_ISR_EN.Bits.CH2_OUT = 1;
}
if (hipc->TxEnableChannels & IPC_CH_3) {
hipc->IPCx->IPC_CTRL.Bits.CH3_OUT_EN = 1;
hipc->IPCx->IPC_ISR_EN.Bits.CH3_OUT = 1;
}
hipc->TxOngoingChannels = 0;
}
void ipc_msg_send(IPC_HandleTypeDef *hipc, enum_IPC_Chl_Sel_t ch, uint32_t msg)
{
switch (ch) {
case IPC_CH_0:
while (hipc->IPCx->IPC_PENDING.Bits.CH0_OUT);
hipc->IPCx->IPC_MSG_OUT0 = msg;
break;
case IPC_CH_1:
while (hipc->IPCx->IPC_PENDING.Bits.CH1_OUT);
hipc->IPCx->IPC_MSG_OUT1 = msg;
break;
case IPC_CH_2:
while (hipc->IPCx->IPC_PENDING.Bits.CH2_OUT);
hipc->IPCx->IPC_MSG_OUT2 = msg;
break;
case IPC_CH_3:
while (hipc->IPCx->IPC_PENDING.Bits.CH3_OUT);
hipc->IPCx->IPC_MSG_OUT3 = msg;
break;
default:
return;
}
hipc->TxOngoingChannels |= ch;
}

View File

@ -0,0 +1,204 @@
/*
******************************************************************************
* @file driver_mp3_dec.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief MP3 decoder module driver.
* This file provides firmware functions to manage the
* MP3 DECODEER peripheral
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
/******************************************************************************
* @fn mp3_decoder_init
*
* @brief Initialize the mp3 decoder according to the specified parameters
* in the MP3_DEC_HandleTypeDef
*
* @param hmp3dec : MP3_DEC_HandleTypeDef structure that contains the
* configuration information for MP3DEC module.
* pcm_buff : mp3 decoder paddr
* pcm_buf_size : pcm buffer size
*/
void mp3_dec_init(MP3_DEC_HandleTypeDef *hmp3dec, uint32_t *pcm_buff, uint32_t pcm_buf_size)
{
__MP3D_SOFTRST();//softreset
__MP3D_PCM_FIFO_RESET();
__MP3D_ISSUE_NEW_FILE();
MP3D->MP3D_CTRL.Bits.DAI_EN = hmp3dec->mp3dec_ctrl_Init.Bits.DAI_EN;
__MP3D_OPERA_ENABLE();
MP3D->MP3D_CTRL.Bits.ISR_EN = hmp3dec->mp3dec_ctrl_Init.Bits.ISR_EN;
MP3D->MP3D_PADDR = (uint32_t)pcm_buff;
MP3D->MP3D_PSIZE.Word = pcm_buf_size;
memset(pcm_buff,0,pcm_buf_size);
}
/******************************************************************************
* @fn mp3_decoder_start
*
* @brief Start the mp3 decoder
*
* @param src_buff : src data pointer
* src_size : src data size
*/
static void mp3_dec_start(uint8_t *src_buff, uint32_t src_size)
{
MP3D->MP3D_SADDR = (uint32_t)src_buff;
MP3D->MP3D_SSIZE.Word = src_size;
MP3D->MP3D_INTSTA.Bits.SOURCE_CMPLETION_ISR = 1;
MP3D->MP3D_CTRL.Bits.OPERA_START = 1;
}
/******************************************************************************
* @fn mp3_decoder_stop
*
* @brief Stop the mp3 decoder
*
* @param void
*/
static void mp3d_stop(void)
{
__MP3D_PCM_FIFO_RESET();
__MP3D_ISSUE_NEW_FILE();
}
/******************************************************************************
* @fn mp3_clear_isr
*
* @brief Clear the mp3 decoder isr flag
*
* @param isr : enum_mp3d_isr_t contains info
*/
static void mp3d_clear_isr(enum_mp3d_isr_t isr)
{
MP3D->MP3D_INTSTA.Word = (1 << isr);
}
/******************************************************************************
* @fn mp3_dec_playdata
*
* @brief Mp3 decoder play data
*
* @param hmp3dec : mp3 decoder handler
* fp_Data : the data which is needed to decoder
* fu32_Size : the decoded data's size
*/
void mp3_dec_playdata(MP3_DEC_HandleTypeDef *hmp3dec, uint8_t *fp_Data, uint32_t fu32_Size)
{
uint32_t length = 0;
uint32_t CurrentIndex = 0;
uint32_t DataSize = fu32_Size;
while(DataSize != 0)
{
length = fu32_Size > 512 ? 512 : fu32_Size;
mp3_dec_start((uint8_t *)&fp_Data[CurrentIndex], length);
DataSize -= length;
while(1)
{
if(__MP3D_CHECK_NEED_SEC())
{
mp3d_clear_isr(SOURCE_COMPLETE_ISR);
CurrentIndex += length;
break;
}
}
}
mp3d_stop();
}
/******************************************************************************
* @fn mp3_dec_playdata_IT
*
* @brief Mp3 decoder play data with isr
*
* @param hmp3dec : mp3 decoder handler
* fp_Data : the data which is needed to decoder
* fu32_Size : the decoded data's size
*/
void mp3_dec_playdata_IT(MP3_DEC_HandleTypeDef *hmp3dec, uint8_t *fp_Data, uint32_t fu32_Size)
{
__MP3D_COMPLETE_ISR_ENABLE();
hmp3dec->MP3Enced_Data = fp_Data;
hmp3dec->MP3Enced_Index = 0;
hmp3dec->LeftLen = fu32_Size;
hmp3dec->FrameLen = hmp3dec->LeftLen > 512 ? 512 : hmp3dec->LeftLen;
mp3_dec_start((uint8_t *)&hmp3dec->MP3Enced_Data[hmp3dec->MP3Enced_Index], hmp3dec->FrameLen);
hmp3dec->MP3Enced_Index += hmp3dec->FrameLen;
hmp3dec->LeftLen -= hmp3dec->FrameLen;
}
/******************************************************************************
* @fn mp3d_get_stream_info
*
* @brief Mp3 decoder get the decoded frame info
*
* @param info : struct_MP3D_stream_info_t structure contains
*/
void mp3d_get_stream_info(struct_MP3D_stream_info_t *info)
{
info->audio_ver = MP3D->MP3D_INFO.Bits.MP3_STREAM_AUDIO_VER;
info->audio_emphasis = MP3D->MP3D_INFO.Bits.MP3_STREAM_AUDIO_EMPHASIS;
info->audio_mode = MP3D->MP3D_INFO.Bits.MP3_STREAM_AUDIO_MODE;
info->bit_rate = MP3D->MP3D_INFO.Bits.MP3_STREAM_BIT_RATE;
info->copyright = MP3D->MP3D_INFO.Bits.MP3_STREAM_COPYRIGHT;
info->error_protection = MP3D->MP3D_INFO.Bits.MP3_STREAM_ERROR_PROTECT;
info->frame_locked = MP3D->MP3D_INFO.Bits.MP3_FRAME_LOCKED;
info->main_done = MP3D->MP3D_INFO.Bits.MP3_MAIN_DONE;
info->main_exhaust = MP3D->MP3D_INFO.Bits.MP3_MAIN_EXHAUST;
info->mode_extension = MP3D->MP3D_INFO.Bits.MP3_STREAM_AUDIO_MODE_EXTEN;
info->original = MP3D->MP3D_INFO.Bits.MP3_STREAM_ORIGINAL;
info->sample_rate = MP3D->MP3D_INFO.Bits.MP3_STREAM_SAMPLE_RATE;
}
/******************************************************************************
* @fn mp3d_check_dec_failed
*
* @brief check whether the mp3dec is failed or successful
*
* @param void
*/
int mp3d_check_dec_failed(void)
{
if((MP3D->MP3D_INTSTA.Bits.MP3_FRAME_LOCKED_ISR == 1) ||
(MP3D->MP3D_INFO.Bits.MP3_FRAME_LOCKED == 0))
{
MP3D->MP3D_INTSTA.Word = (1 << MP3_FRAME_LOCKED_ISR);
return 1;
}
return 0;
}
/******************************************************************************
* @fn mp3dec_IRQHandler
*
* @brief mp3 decoder handle function in mo3 dec isr
*
* @param hmp3dec : MP3 decoder handle
*/
void mp3dec_IRQHandler(MP3_DEC_HandleTypeDef *hmp3dec)
{
if(__MP3D_SRC_COMPLETE_ISR_IS_SET())
{
if(hmp3dec->LeftLen != 0)
{
hmp3dec->FrameLen = hmp3dec->LeftLen > 512 ? 512 : hmp3dec->LeftLen;
mp3_dec_start((uint8_t *)&hmp3dec->MP3Enced_Data[hmp3dec->MP3Enced_Index], hmp3dec->FrameLen);
hmp3dec->MP3Enced_Index += hmp3dec->FrameLen;
hmp3dec->LeftLen -= hmp3dec->FrameLen;
}
else
{
__MP3D_COMPLETE_ISR_DISABLE();
mp3d_stop();
}
}
}

View File

@ -0,0 +1,202 @@
/*
******************************************************************************
* @file driver_parallel_interface.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief parallel module driver.
* This file provides firmware functions to manage the
* parallel interface 8080/6800 peripheral.
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
/*********************************************************************
* @fn parallel_init
*
* @brief Initialize the parallel_nterface according to the specified parameters
* in the str_ParallelParam_t
*
* @param ParalleInit : pointer to a str_ParallelParam_t structure that contains
* the configuration information for LCD module
*
* @return None.
*/
void parallel_init(PARALLEL_HandTypeDef *hparallel)
{
/* FIFO_RST */
__PARALLEL_TX_FIFO_RESET(hparallel->PARALLELx);
/* DMA Config */
hparallel->PARALLELx->DMA.DMA_TX_LEVEL = 16;
hparallel->PARALLELx->DMA.DMA_ENABLE = 1;
/* select 8080 or 6800 */
hparallel->PARALLELx->INTF_CFG.MODE = hparallel->Init.ParallelMode;
/* select 8bit or 16bit */
hparallel->PARALLELx->INTF_CFG.PARA_WIDTH = hparallel->Init.DataBusSelect;
/* Write Clock DIV */
hparallel->PARALLELx->CRM.WRITE_CLK_CFG = hparallel->Init.WriteClock;
/* Read Clock DIV */
hparallel->PARALLELx->CRM.READ_CLK_CFG = hparallel->Init.ReadClock;
/* FIFO_RELEASE */
__PARALLEL_TX_FIFO_RELEASE(hparallel->PARALLELx);
}
/*********************************************************************
* @fn Parallel_write_cmd
*
* @brief Sending command
*
* @param fp8_CMD : command data
*
* @return None.
*/
void Parallel_write_cmd(PARALLEL_HandTypeDef *hparallel, uint8_t fp8_CMD)
{
/* Write, CMD */
__PARALLEL_WR_CMD(hparallel->PARALLELx, fp8_CMD);
/* wait bus idle */
while(__PARALLEL_IS_BUS_BUSY(hparallel->PARALLELx));
}
/*********************************************************************
* @fn Parallel_write_param
*
* @brief Sending parameter.
*
* @param fu16_Data : parameter. Can be 8 bit or 16 bit, depend on BUS bit.
*
* @return None.
*/
void Parallel_write_param(PARALLEL_HandTypeDef *hparallel, uint16_t fu16_Data)
{
/* Write, param */
__PARALLEL_WR_PARAM(hparallel->PARALLELx, fu16_Data);
/* wait bus idle */
while(__PARALLEL_IS_BUS_BUSY(hparallel->PARALLELx));
}
/*********************************************************************
* @fn Parallel_write_data
*
* @brief Sending data or parameters
*
* @param fp32_WriteBuffer : Write data buffer
* fu32_WriteNum : transmit number.
* 1. select DATA_BUS_8_BIT, 1 count sent 1 byte
* 2. select DATA_BUS_16_BIT, 1 count sent 2 byte
* @return None.
*/
void Parallel_write_data(PARALLEL_HandTypeDef *hparallel, uint32_t *fp32_WriteBuffer, uint32_t fu32_WriteNum)
{
uint32_t i;
uint32_t lu32_Num;
hparallel->PARALLELx->DATA_WR_LEN = fu32_WriteNum;
/* 8 bit bus */
if (hparallel->PARALLELx->INTF_CFG.PARA_WIDTH == DATA_BUS_8_BIT)
{
lu32_Num = fu32_WriteNum / 4;
if (fu32_WriteNum % 4)
{
lu32_Num++;
}
}
/* 16 bit bus */
else
{
lu32_Num = fu32_WriteNum / 2;
if (fu32_WriteNum % 2)
{
lu32_Num++;
}
}
while(lu32_Num >= PARALLEL_FIFO_DEPTH)
{
uint32_t u32_l = PARALLEL_FIFO_DEPTH;
while(u32_l--)
{
hparallel->PARALLELx->TX_FIFO = *fp32_WriteBuffer++;
}
lu32_Num -= PARALLEL_FIFO_DEPTH;
while(!(__PARALLEL_INT_STATUS(hparallel->PARALLELx)&INT_TXFIFO_EMPTY));
}
while(lu32_Num--)
{
hparallel->PARALLELx->TX_FIFO = *fp32_WriteBuffer++;
}
/* wait bus idle */
while(__PARALLEL_IS_BUS_BUSY(hparallel->PARALLELx));
}
/*********************************************************************
* @fn Parallel_read_data_8bit
*
* @brief read data. select DATA_BUS_8_BIT, 1 count receive 1 byte.
*
* @param fu8_Param : read Param
* fp8_ReadBuffer : read data buffer.
* fu32_ReadNum : receive number.
*
* @return None.
*/
void Parallel_read_data_8bit(PARALLEL_HandTypeDef *hparallel, uint8_t fu8_Param, uint8_t *fp8_ReadBuffer, uint32_t fu32_ReadNum)
{
uint32_t i;
__PARALLEL_WR_PARAM(hparallel->PARALLELx, fu8_Param);
/* wait bus idle */
while(__PARALLEL_IS_BUS_BUSY(hparallel->PARALLELx));
for (i = 0; i < fu32_ReadNum; i++)
{
/* Read REQ*/
__PARALLEL_RD_REQ(hparallel->PARALLELx);
/* wait bus idle */
while(__PARALLEL_IS_BUS_BUSY(hparallel->PARALLELx));
fp8_ReadBuffer[i] = hparallel->PARALLELx->DAT_RD;
}
}
/*********************************************************************
* @fn Parallel_read_data_16bit
*
* @brief read data. select DATA_BUS_16_BIT, 1 count receive 2 byte.
*
* @param fu8_Param : read Param
fp16_ReadBuffer : read data buffer.
* fu32_ReadNum : receive number.
*
* @return None.
*/
void Parallel_read_data_16bit(PARALLEL_HandTypeDef *hparallel, uint8_t fu8_Param, uint16_t *fp16_ReadBuffer, uint32_t fu32_ReadNum)
{
uint32_t i;
__PARALLEL_WR_PARAM(hparallel->PARALLELx, fu8_Param);
/* wait bus idle */
while(__PARALLEL_IS_BUS_BUSY(hparallel->PARALLELx));
for (i = 0; i < fu32_ReadNum; i++)
{
/* Read REQ*/
__PARALLEL_RD_REQ(hparallel->PARALLELx);
/* wait bus idle */
while(__PARALLEL_IS_BUS_BUSY(hparallel->PARALLELx));
fp16_ReadBuffer[i] = hparallel->PARALLELx->DAT_RD;
}
}

View File

@ -0,0 +1,176 @@
/*
******************************************************************************
* @file driver_pdm.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2023
* @brief pdm module driver.
* This file provides firmware functions to manage the
* pulse-duration modulation (PDM) peripheral
******************************************************************************
* @attention
*
* Copyright (c) 2023 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
/************************************************************************************
* @fn pdm_IRQHandler
*
* @brief Handle PDM interrupt request.
*
* @param hpdm: PDM handle.
*/
__WEAK void pdm_IRQHandler(PDM_HandleTypeDef *hpdm)
{
if (__PDM_IS_FIFO_ALMOST_FULL(hpdm->PDMx))
{
if (hpdm->p_RxData) {
pdm_read_data(hpdm, hpdm->p_RxData);
}
if (hpdm->RxCallback) {
hpdm->RxCallback(hpdm);
}
}
}
/************************************************************************************
* @fn pdm_init
*
* @brief Initialize the PDM according to the specified parameters in the struct_PDMInit_t
*
* @param hpdm: PDM handle.
*/
void pdm_init(PDM_HandleTypeDef *hpdm)
{
/* Clock default use 24M */
hpdm->PDMx->Config.USB_MODE = 1;
/* Sample Rate */
hpdm->PDMx->Config.SAMPLE_RATE = hpdm->Init.SampleRate;
/* Over Samplek Mode */
hpdm->PDMx->Config.OSR_MODE = hpdm->Init.OverSampleMode;
/* channel config */
if (hpdm->Init.ChannelMode == PDM_STEREO) {
hpdm->PDMx->Config.MONO = 0;
hpdm->PDMx->Config.CH_SEL = 0;
}
else{
hpdm->PDMx->Config.MONO = 1;
hpdm->PDMx->Config.CH_SEL = hpdm->Init.ChannelMode;
}
/* fifo almost Full Threshold */
hpdm->PDMx->FF_AFLL_LVL = hpdm->Init.FIFO_FullThreshold;
pdm_vol_set(hpdm, hpdm->Init.Volume);
hpdm->PDMx->Config.RST = 1;
hpdm->PDMx->Config.RST = 0;
hpdm->PDMx->FF_RST.rst = 0x07;
hpdm->PDMx->FF_RST.rst = 0x00;
}
/************************************************************************************
* @fn pdm_start_IT
*
* @brief PDM read start in interrupt mode.
*
* @param hpdm: PDM handle.
* @param fp_Data: buffer used to store received data, If fp_Data is NULL, application layer
* should take charge of reading data from fifo.
*/
void pdm_start_IT(PDM_HandleTypeDef *hpdm, void *fp_Data)
{
if (hpdm->b_RxBusy)
return;
__PDM_CLK_ENABLE(hpdm->PDMx);
__PDM_ENABLE(hpdm->PDMx);
__PDM_FIFO_ALMOST_FULL_INT_ENABLE(hpdm->PDMx);
hpdm->b_RxBusy = true;
hpdm->p_RxData = fp_Data;
}
/************************************************************************************
* @fn pdm_init
*
* @brief Initialize the PDM according to the specified parameters in the struct_PDMInit_t
*
* @param hpdm: PDM handle.
* @param vol: target volume, unit is dB
*/
void pdm_vol_set(PDM_HandleTypeDef *hpdm, int8_t vol)
{
uint32_t vol_cfg;
if(vol <= 18) {
vol_cfg = PDM_VOL_dB(vol);
hpdm->Init.Volume = vol;
}
else {
return;
}
hpdm->PDMx->VOL_L = vol_cfg;
hpdm->PDMx->VOL_R = vol_cfg;
}
/************************************************************************************
* @fn pdm_read_data
*
* @brief read data from PDM fifo, read size is FIFO_FullThreshold
*
* @param hpdm: PDM handle.
* @param pcm: buffer used to store received data.
*/
void pdm_read_data(PDM_HandleTypeDef *hpdm, void *fp_Data)
{
uint8_t thd = hpdm->Init.FIFO_FullThreshold;
if (hpdm->Init.ChannelMode == PDM_STEREO)
{
uint32_t *p_u32 = (void *)fp_Data;
while (thd--) {
*p_u32++ = hpdm->PDMx->DATA;
}
}
else
{
uint16_t *p_u16 = (void *)fp_Data;
while (thd--) {
*p_u16++ = hpdm->PDMx->DATA;
}
}
}
/************************************************************************************
* @fn pdm_start
*
* @brief PDM sampling start.
*
* @param hpdm: PDM handle.
*/
void pdm_start(PDM_HandleTypeDef *hpdm)
{
__PDM_CLK_ENABLE(hpdm->PDMx);
__PDM_ENABLE(hpdm->PDMx);
}
/************************************************************************************
* @fn pdm_stop
*
* @brief PDM sampling stop.
*
* @param hpdm: PDM handle.
*/
void pdm_stop(PDM_HandleTypeDef *hpdm)
{
__PDM_DISABLE(hpdm->PDMx);
__PDM_CLK_DISABLE(hpdm->PDMx);
hpdm->b_RxBusy = false;
}

View File

@ -0,0 +1,591 @@
#include "fr30xx.h"
#define PMU_FSM_ON_DIV 0x04 //the follow tcnt based <((DIV+1))*40K_CLK(rc)>
#define PMU_PMU_ON_CNT (0x18<<0)
//the follow tcnt should <= PMU_PMU_ON_CNT
#define PMU_BBG_ON_CNT (0x01<<0)
#define PMU_SYSBUCK_ON_CNT (0x03<<0)
#define PMU_IOBUCK_ON_CNT (0x03<<0)
#define PMU_IOLDO1_ON_CNT (0x03<<0)
#define PMU_IOLDO2_ON_CNT (0x03<<0)
#define PMU_APPDLDO_ON_CNT (0x06<<0)
#define PMU_DSPDLDO_ON_CNT (0x06<<0)
#define PMU_PKSTPD_ON_CNT (0x0c<<0)
#define PMU_MEMPK_ON_CNT (0x10<<0)
#define PMU_MEMPD_ON_CNT (0x10<<0)
#define PMU_OSCLDO_ON_CNT (0x06<<0)
#define PMU_OSC_ON_CNT (0x08<<0)
#define PMU_RC24PD_ON_CNT (0x10<<0)
#define PMU_RAMPK_ON_CNT (0x18<<0)
#define PMU_PMUISO_ON_CNT (0x17<<0)
#define PMU_IOISO_ON_CNT (0x17<<0)
#define PMU_IORTON_ON_CNT (0x17<<0)
#define PMU_IOSNS_ON_CNT (0x17<<0)
#define PMU_RSTN_ON_CNT (0x18<<0)
#define PMU_FSM_OFF_DIV (0x00<<5) //the follow tcnt based <((DIV+1))*40K_CLK(rc)>
#define PMU_PMU_OFF_CNT (0x06<<5)
//the follow tcnt should <= PMU_PMU_OFF_CNT
#define PMU_BBG_OFF_CNT (0x05<<5)
#define PMU_SYSBUCK_OFF_CNT (0x04<<5)
#define PMU_IOBUCK_OFF_CNT (0x01<<5)
#define PMU_IOLDO1_OFF_CNT (0x01<<5)
#define PMU_IOLDO2_OFF_CNT (0x01<<5)
#define PMU_APPDLDO_OFF_CNT (0x03<<5)
#define PMU_DSPDLDO_OFF_CNT (0x03<<5)
#define PMU_PKSTPD_OFF_CNT (0x01<<5)
#define PMU_MEMPK_OFF_CNT (0x01<<5)
#define PMU_MEMPD_OFF_CNT (0x03<<5)
#define PMU_OSCLDO_OFF_CNT (0x03<<5)
#define PMU_OSC_OFF_CNT (0x01<<5)
#define PMU_RC24PD_OFF_CNT (0x03<<5)
#define PMU_RAMPK_OFF_CNT (0x01<<5)
#define PMU_PMUISO_OFF_CNT (0x01<<5)
#define PMU_IOISO_OFF_CNT (0x02<<5)
#define PMU_IORTON_OFF_CNT (0x02<<5)
#define PMU_IOSNS_OFF_CNT (0x02<<5)
#define PMU_RSTN_OFF_CNT (0x01<<5)
void pmu_init(void)
{
/* setup sleep and wakeup counters */
ool_write(PMU_REG_FSM_TIMER , PMU_FSM_ON_DIV | PMU_FSM_OFF_DIV );
ool_write(PMU_REG_PMU_ONOFF_CNT , PMU_PMU_ON_CNT | PMU_PMU_OFF_CNT );
ool_write(PMU_REG_BBG_ONOFF_CNT , PMU_BBG_ON_CNT | PMU_BBG_OFF_CNT );
ool_write(PMU_REG_SYSBUCK_ONOFF_CNT , PMU_SYSBUCK_ON_CNT | PMU_SYSBUCK_OFF_CNT);
ool_write(PMU_REG_IOBUCK_ONOFF_CNT , PMU_IOBUCK_ON_CNT | PMU_IOBUCK_OFF_CNT );
ool_write(PMU_REG_IOLDO1_ONOFF_CNT , PMU_IOLDO1_ON_CNT | PMU_IOLDO1_OFF_CNT );
ool_write(PMU_REG_IOLDO2_ONOFF_CNT , PMU_IOLDO2_ON_CNT | PMU_IOLDO2_OFF_CNT );
ool_write(PMU_REG_APPDLDO_ONOFF_CNT , PMU_APPDLDO_ON_CNT | PMU_APPDLDO_OFF_CNT);
ool_write(PMU_REG_DSPDLDO_ONOFF_CNT , PMU_DSPDLDO_ON_CNT | PMU_DSPDLDO_OFF_CNT);
ool_write(PMU_REG_PKSTPD_ONOFF_CNT , PMU_PKSTPD_ON_CNT | PMU_PKSTPD_OFF_CNT );
ool_write(PMU_REG_MEMPK_ONOFF_CNT , PMU_MEMPK_ON_CNT | PMU_MEMPK_OFF_CNT );
ool_write(PMU_REG_MEMPD_ONOFF_CNT , PMU_MEMPD_ON_CNT | PMU_MEMPD_OFF_CNT );
ool_write(PMU_REG_OSCLDO_ONOFF_CNT , PMU_OSCLDO_ON_CNT | PMU_OSCLDO_OFF_CNT );
ool_write(PMU_REG_OSC_ONOFF_CNT , PMU_OSC_ON_CNT | PMU_OSC_OFF_CNT );
ool_write(PMU_REG_RC24PD_ONOFF_CNT , PMU_RC24PD_ON_CNT | PMU_RC24PD_OFF_CNT );
ool_write(PMU_REG_RAMPK_ONOFF_CNT , PMU_RAMPK_ON_CNT | PMU_RAMPK_OFF_CNT );
ool_write(PMU_REG_PMUISO_ONOFF_CNT , PMU_PMUISO_ON_CNT | PMU_PMUISO_OFF_CNT );
ool_write(PMU_REG_IOISO_ONOFF_CNT , PMU_IOISO_ON_CNT | PMU_IOISO_OFF_CNT );
ool_write(PMU_REG_IORTON_ONOFF_CNT , PMU_IORTON_ON_CNT | PMU_IORTON_OFF_CNT );
ool_write(PMU_REG_IOSNS_ONOFF_CNT , PMU_IOSNS_ON_CNT | PMU_IOSNS_OFF_CNT );
ool_write(PMU_REG_RSTN_ONOFF_CNT , PMU_RSTN_ON_CNT | PMU_RSTN_OFF_CNT );
/* splite PKVDDH and PKVDD */
ool_write(PMU_REG_PKVDDH_CTRL_0, 0x60);
ool_write(PMU_REG_PKVDDH_CTRL_0, 0x70);
/* shut down OSC buffer */
ool_write(PMU_REG_OSC_CTRL_1, ool_read(PMU_REG_OSC_CTRL_1) & (~0x04));
/* PLL analog clock enable */
ool_write(PMU_REG_OSC_CTRL_1, ool_read(PMU_REG_OSC_CTRL_1)|0x0B);
/* set PKVDD to 0.85v */
ool_write(PMU_REG_PKVDD_CTRL, 0x7a);
/* set PKVDDH to 1.1v, set RAMPKVDD to 0.7v */
ool_write(PMU_REG_PKVDDH_CTRL_1, 0x34);
/* buck load inductor will not be shorted */
ool_write(PMU_REG_SYSBUCK_CTRL_1, 0x43);
/* disable internal load of sys-buck and io-buck */
ool_write(PMU_REG_IOBUCK_CTRL_4, 0x73);
ool_write(PMU_REG_SYSBUCK_CTRL_4, 0x73);
/*
* IOLDO dynamic bias, used to avoid unexpect leakage when IOLDO
* output configuration is large than VBAT input voltage
*/
ool_write(PMU_REG_IOLDO1_CTRL_1, ool_read(PMU_REG_IOLDO1_CTRL_1) | (1<<4));
ool_write(PMU_REG_IOLDO2_CTRL_1, ool_read(PMU_REG_IOLDO2_CTRL_1) | (1<<4));
/* enable BT sleep timer clock */
ool_write(PMU_REG_CLK_EN, PMU_LP_TICK_CLK_EN_BIT);
#if 0
/* sleep and wake up is controlled by TICK */
ool_write(PMU_REG_SLP_WK_SRC, PMU_SLP_TICK_EN_BIT | PMU_WK_TICK_EN_BIT);
/*
* BIT0: BB generate sleep signal en
* BIT1: external interrupt wakeup BT timer enable
*/
ool_write(PMU_REG_TICK_CTRL, PMU_TICK_SLP_PMU_EN_BIT | PMU_EXT_WK_TICK_EN_BIT | PMU_IRQ_WK_TICK_EN_BIT);
/* reset lp tick */
ool_write(PMU_REG_RST, PMU_LP_TICK_SFT_RST_BIT);
while (ool_read(PMU_REG_RST) & PMU_LP_TICK_SFT_RST_BIT);
#else
/* sleep and wake up is controlled by TICK */
ool_write(PMU_REG_SLP_WK_SRC, PMU_SLP_CPU_EN_BIT | PMU_WK_IRQ_EN_BIT);
/* release RTC clock */
ool_write(PMU_REG_CLK_EN, ool_read(PMU_REG_CLK_EN) | PMU_RTC_CLK_EN_BIT);
/* release interrupt mask of RTC alarm B */
ool_write16(PMU_REG_INT_MASK, ool_read16(PMU_REG_INT_MASK) | PMU_RTC_B_INT_MSK_BIT);
#endif
/* disable power fsm */
ool_write(0x85, 0xff);
/* IO33 and IO18 always on */
ool_write(0x63, 0x18);
/* set mask of GPIO SNS & ISO */
ool_write(0x64, ool_read(0x64) | 0x80 | 0x20); //bit7 : GPIO_SNS; bit5 : GPIO_ISO
// /* configure PMU_PIN_8 output BBG_EN signal */
// ool_write(PMU_REG_DIAG_CTRL, 0x82);
//// ool_write16(PMU_REG_PIN_IOMUX_L, 0xffff);
// ool_write(PMU_REG_PIN_IOMUX_H, 0x03);
// /* disable input as default setting */
// ool_write16(PMU_REG_PIN_INPUT_EN, 0x0000);
/* remove internal cap of osc */
ool_write(PMU_REG_OSC_CTRL_4, 0x20);
}
/******************************************************************************
* @fn pmu_adc_power_ctrl
*
* @brief ADC power control. true: enable.
* false: disable.
*/
void pmu_adc_power_ctrl(bool enable)
{
if (enable)
ool_write(PMU_REG_ADC_CTL, ool_read(PMU_REG_ADC_CTL) | PMU_ADC_CTL_POWER_BIT);
else
ool_write(PMU_REG_ADC_CTL, ool_read(PMU_REG_ADC_CTL) & ~PMU_ADC_CTL_POWER_BIT);
}
/******************************************************************************
* @fn pmu_vbe_power_ctrl
*
* @brief VBE(For temperature detection) power control. true: enable.
* false: disable.
*/
void pmu_vbe_power_ctrl(bool enable)
{
if (enable)
ool_write(PMU_REG_BBG_CTL, ool_read(PMU_REG_BBG_CTL) | PMU_BBG_CTL_VBE_EN_BIT);
else
ool_write(PMU_REG_BBG_CTL, ool_read(PMU_REG_BBG_CTL) & ~PMU_BBG_CTL_VBE_EN_BIT);
}
/******************************************************************************
* @fn pmu_auldo_power_ctrl
*
* @brief audio ldo power control. true: enable.
* false: disable.
*/
void pmu_auldo_power_ctrl(bool enable)
{
if (enable)
ool_write(PMU_REG_AULDO_CTL, ool_read(PMU_REG_AULDO_CTL) & ~PMU_AULDO_CTL_PD_BIT);
else
ool_write(PMU_REG_AULDO_CTL, ool_read(PMU_REG_AULDO_CTL) | PMU_AULDO_CTL_PD_BIT);
}
/*********************************************************************
* @fn pmu_enable_charge
*
* @brief enable charge function, and set charge current & voltage.
*
* @param cur - charge current, @ref enum_PMU_charge_current_t
* @param vol - charge terminal voltage, @ref enum_PMU_charge_end_vol_t
*
* @return None.
*/
void pmu_charge_enable(enum_PMU_charge_current_t cur, enum_PMU_charge_end_vol_t vol)
{
/* charge reference select BBG */
ool_write(PMU_REG_CHG_CFG_CD, ool_read(PMU_REG_CHG_CFG_CD) | PMU_CHG_CFG_REF_SEL_BIT);
/* config charge voltage */
ool_write(PMU_REG_CHG_CFG_CB, (ool_read(PMU_REG_CHG_CFG_CB)&0x8F) | (vol << PMU_CHG_CFG_END_VOL_POS));
/* config charge current */
ool_write(PMU_REG_CHG_CFG_C8, (ool_read(PMU_REG_CHG_CFG_C8)&0xC0) | (cur));
/* enable charge */
ool_write(PMU_REG_CHG_CFG_CD, ool_read(PMU_REG_CHG_CFG_CD) | PMU_CHG_CFG_ENABLE_BIT);
}
/*********************************************************************
* @fn pmu_charge_disable
*
* @brief disable charge function.
*/
void pmu_charge_disable(void)
{
/* disable charge */
ool_write(PMU_REG_CHG_CFG_CD, ool_read(PMU_REG_CHG_CFG_CD) & ~PMU_CHG_CFG_ENABLE_BIT);
}
/*********************************************************************
* @fn pmu_charge_monitor_en
*
* @brief Charging in/out monitor interrupt enable.
*/
void pmu_charge_monitor_en(enum_PMU_charge_type_t charge_type)
{
if (charge_type == PMU_CHARGING_IN)
ool_write(PMU_REG_ANA_LEVEL, ool_read(PMU_REG_ANA_LEVEL) & ~PMU_CHG_ACOK_LEVEL_BIT);
else
ool_write(PMU_REG_ANA_LEVEL, ool_read(PMU_REG_ANA_LEVEL) | PMU_CHG_ACOK_LEVEL_BIT);
ool_write(PMU_REG_CLK_EN, ool_read(PMU_REG_CLK_EN) | PMU_FILTER_CLK_EN_BIT);
ool_write(PMU_REG_CHG_ACOK_FILTER, 100);
ool_write(PMU_REG_ANA_INT_EN, ool_read(PMU_REG_ANA_INT_EN) | PMU_CHG_ACOK_INT_EN_BIT);
pmu_enable_isr(PMU_CHG_ACOK_INT_MASK_BIT);
}
/*********************************************************************
* @fn pmu_battery_full_monitor_en
*
* @brief battery_full monitor interrupt enable
*/
void pmu_battery_full_monitor_en(enum_PMU_battery_type_t battery_type)
{
if (battery_type == PMU_BATTERY_FULL)
ool_write(PMU_REG_ANA_LEVEL, ool_read(PMU_REG_ANA_LEVEL) & ~PMU_BATFULL_LEVEL_BIT);
else
ool_write(PMU_REG_ANA_LEVEL, ool_read(PMU_REG_ANA_LEVEL) | PMU_BATFULL_LEVEL_BIT);
ool_write(PMU_REG_CLK_EN, ool_read(PMU_REG_CLK_EN) | PMU_FILTER_CLK_EN_BIT);
ool_write(PMU_REG_BAT_FULL_FILTER, 200);
ool_write(PMU_REG_ANA_INT_EN, ool_read(PMU_REG_ANA_INT_EN) | PMU_BATFULL_INT_EN_BIT);
pmu_enable_isr(PMU_BATFULL_INT_MASK_BIT);
}
void pmu_set_pin_pull(enum_PMU_PINx_t bits, enum_PMU_GPIO_PULL_t type)
{
uint8_t en_reg = PMU_REG_PIN_PULL_EN;
uint8_t pull_reg = PMU_REG_PIN_PULL_SEL;
if(type == PMU_GPIO_NO_PULL) {
ool_write16(en_reg, (ool_read16(en_reg) & (~bits)));
}
else {
if(type == PMU_GPIO_PULL_UP) {
ool_write16(pull_reg, (ool_read16(pull_reg) | bits));
}
else if(type == PMU_GPIO_PULL_DOWN) {
ool_write16(pull_reg, (ool_read16(pull_reg) & (~bits)));
}
else {
return;
}
ool_write16(en_reg, (ool_read16(en_reg) | bits));
}
}
void pmu_set_pin_dir(enum_PMU_PINx_t bits, enum_PMU_GPIO_MODE_t dir)
{
uint8_t oe_reg = PMU_REG_PIN_OUTPUT_EN;
uint8_t ie_reg = PMU_REG_PIN_INPUT_EN;
if(dir == PMU_GPIO_MODE_INPUT) {
ool_write16(oe_reg, ool_read16(oe_reg) | bits);
ool_write16(ie_reg, ool_read16(ie_reg) | (bits << 2));
}
else {
ool_write16(oe_reg, ool_read16(oe_reg) & (~bits));
ool_write16(ie_reg, ool_read16(ie_reg) & (~bits << 2));
}
}
void pmu_set_pin_value(enum_PMU_PINx_t bits, uint8_t value)
{
uint8_t data_reg = PMU_REG_PIN_DATA;
if (value == 0)
ool_write16(data_reg, (ool_read16(data_reg) & (~bits)));
else
ool_write16(data_reg, (ool_read16(data_reg) | bits));
}
uint8_t pmu_get_pin_value(enum_PMU_PINx_t bit)
{
uint8_t data_reg = PMU_REG_PIN_DATA;
return ( (ool_read16(data_reg) & (1<<bit))>>bit );
}
void pmu_set_pin_xor_en(enum_PMU_PINx_t bits, bool en)
{
uint8_t xor_reg = PMU_REG_PIN_XOR_EN;
if(en) {
ool_write16(xor_reg, ool_read16(xor_reg) | (bits));
}
else {
ool_write16(xor_reg, ool_read16(xor_reg) & (~bits));
}
}
/*********************************************************************
* @fn pmu_port_wakeup_func_set
*
* @brief PortPin wakeup function congfig
*
* @param bits: Select Pin. 0x01--PIN0 0x80--PIN7
*/
void pmu_port_wakeup_func_set(enum_PMU_PINx_t bits)
{
uint8_t last_status_reg = PMU_REG_PIN_LAST_V;
uint8_t data_reg = PMU_REG_PIN_DATA;
/* Config input Pull up */
pmu_set_pin_pull(bits, PMU_GPIO_PULL_UP);
pmu_set_pin_dir(bits, PMU_GPIO_MODE_INPUT);
/* Read the current value and write */
ool_write16(last_status_reg, ool_read16(data_reg));
/* XOR Enable */
pmu_set_pin_xor_en(bits, true);
/* XOR interrupt enable */
ool_write(PMU_REG_PIN_INT_EN, 0x01);
}
/*********************************************************************
* @fn pmu_gpio_int_init
*
* @brief pmu pin wakeup function config. Compare with pmu_port_wakeup_func_set, this
* function provides two parameter to set pull mode and initial value
*
* @param bits: Select Pin. 0x01--PIN0 0x80--PIN7
* pull: pull mode selection, @ref enum_PMU_GPIO_PULL_t
* init_value: initial value. Once the level of corresponding pin changes to opposite
* level with initial value, PMU_GPIO_PMU_INT will be generated.
*/
void pmu_gpio_int_init(enum_PMU_PINx_t bits, enum_PMU_GPIO_PULL_t pull, uint8_t init_value)
{
uint8_t last_status_reg = PMU_REG_PIN_LAST_V;
uint8_t data_reg = PMU_REG_PIN_DATA;
/* Config input Pull up */
pmu_set_pin_pull(bits, pull);
pmu_set_pin_dir(bits, PMU_GPIO_MODE_INPUT);
/* Read the current value and write */
if (init_value) {
ool_write16(last_status_reg, ool_read16(last_status_reg) | bits);
}
else {
ool_write16(last_status_reg, ool_read16(last_status_reg) & (~bits));
}
/* XOR Enable */
pmu_set_pin_xor_en(bits, true);
/* XOR interrupt enable */
ool_write(PMU_REG_PIN_INT_EN, 0x01);
}
/*********************************************************************
* @fn pmu_port_wakeup_func_clear
*
* @brief Get rtc current counter value
*
* @param bits: Select Pin. 0x01--PIN0 0x80--PIN7
*/
void pmu_port_wakeup_func_clear(enum_PMU_PINx_t bits)
{
/* XOR Disable */
pmu_set_pin_xor_en(bits, false);
}
void pmu_enable_isr(uint16_t isr_map)
{
ool_write16(PMU_REG_INT_MASK, ool_read16(PMU_REG_INT_MASK) | isr_map);
}
void pmu_disable_isr(uint16_t isr_map)
{
ool_write16(PMU_REG_INT_MASK, ool_read16(PMU_REG_INT_MASK) & (~isr_map));
}
uint16_t pmu_get_isr_state(void)
{
return ool_read16(PMU_REG_INT_STATUS);
}
void pmu_clear_isr_state(uint16_t state_map)
{
if (state_map & PMU_BATFULL_INT_STATUS_BIT) {
ool_write(PMU_REG_ANA_INT_CLR, ool_read(PMU_REG_ANA_INT_CLR) | PMU_BATFULL_INT_CLR_BIT);
}
if (state_map & PMU_CHG_ACOK_INT_STATUS_BIT) {
ool_write(PMU_REG_ANA_INT_CLR, ool_read(PMU_REG_ANA_INT_CLR) | PMU_CHG_ACOK_INT_CLR_BIT);
}
if (state_map & PMU_LVD_INT_STATUS_BIT) {
ool_write(PMU_REG_ANA_INT_CLR, ool_read(PMU_REG_ANA_INT_CLR) | PMU_LVD_INT_CLR_BIT);
}
if (state_map & PMU_WDT_INT_STATUS_BIT) {
ool_write(PMU_REG_RTC_CTRL, ool_read(PMU_REG_RTC_CTRL) | PMU_WDT_CLR_BIT);
}
if (state_map & PMU_RTC_A_INT_STATUS_BIT) {
ool_write(PMU_REG_RTC_CTRL, ool_read(PMU_REG_RTC_CTRL) | PMU_RTC_ALARM_A_CLR_BIT);
}
if (state_map & PMU_GPIO_PMU_INT_STATUS_BIT) {
// ool_write16(PMU_REG_PIN_XOR_CLR, ool_read16(PMU_REG_PIN_XOR_RESULT));
}
if (state_map & PMU_GPIO_GROUPH_INT_STATUS_BIT) {
ool_write(PMU_REG_WKUP_INT_CLR, ool_read(PMU_REG_WKUP_INT_CLR) | 0x01);
}
if (state_map & PMU_GPIO_GROUPL_INT_STATUS_BIT) {
ool_write(PMU_REG_WKUP_INT_CLR, ool_read(PMU_REG_WKUP_INT_CLR) | 0x02);
}
}
#if 0
void pmu_lvd_enable(enum_PMU_LVD_THD_t thd)
{
uint8_t value;
value = ool_read(0xa3);
value &= 0x1f;
value |= (thd << 5);
ool_write(0xa3, value);
ool_write(PMU_REG_ANA_LAST_V, ool_read(PMU_REG_ANA_LAST_V) & (~PMU_ANA_LAST_LVD_V_BIT));
ool_write(PMU_REG_ANA_XOR_EN, ool_read(PMU_REG_ANA_XOR_EN) | PMU_ANA_XOR_LVD_EN_BIT);
ool_write(PMU_REG_ANA_INT_EN, ool_read(PMU_REG_ANA_INT_EN) | PMU_LVD_INT_EN_BIT);
pmu_enable_isr(PMU_LVD_INT_MSK_BIT);
}
void pmu_lvd_disable(void)
{
pmu_disable_isr(PMU_LVD_INT_MSK_BIT);
}
void pmu_adkey0_start(void)
{
/*adkey0 interrupt enable*/
ool_write(PMU_REG_ANA_INT_EN, PMU_KEY0_INT_EN_BIT);
/*adkey0 xor enable*/
ool_write16(PMU_REG_ANA_XOR_EN, ool_read(PMU_REG_ANA_XOR_EN) | 0x04);
/*enable adkey0*/
pmu_enable_isr(PMU_ADKEY0_INT_MSK_BIT);
ool_write(PMU_REG_ADKEY_CFG, 0xdb);
NVIC_EnableIRQ(PMU_IRQn);
}
void pmu_adkey1_start(void)
{
/*adkey1 interrupt enable*/
ool_write(PMU_REG_ANA_INT_EN, PMU_KEY1_INT_EN_BIT);
/*adkey1 xor enable*/
ool_write16(PMU_REG_ANA_XOR_EN, ool_read(PMU_REG_ANA_XOR_EN) | 0x08);
/*enable adkey1*/
pmu_enable_isr(PMU_ADKEY1_INT_MSK_BIT);
ool_write(PMU_REG_ADKEY_CFG, 0xdb);
NVIC_EnableIRQ(PMU_IRQn);
}
#endif
__WEAK void PMU_Battery_Full_IRQHandler(void)
{
}
__WEAK void PMU_Charge_Monitor_IRQHandler(void)
{
}
__WEAK void RTC_ALARMA_IRQHandler(void)
{
}
__WEAK void RTC_ALARMB_IRQHandler(void)
{
}
__WEAK void PMU_GPIO_PMU_IRQHandler(void)
{
}
__WEAK void PMU_GPIO_GROUPH_IRQHandler(void)
{
}
__WEAK void PMU_GPIO_GROUPL_IRQHandler(void)
{
}
__WEAK void PMU_LVD_IRQHandler(void)
{
}
__WEAK void PMU_ADKEY0_IRQHandler(void)
{
}
__WEAK void PMU_ADKEY1_IRQHandler(void)
{
}
__WEAK void PMU_IWDT_IRQhandler(void)
{
}
void pmu_irq(void)
{
uint16_t state_map = pmu_get_isr_state();
// printf("%s state%d \r\n",__func__,state_map);
// pmu_clear_isr_state(state_map);
if (state_map & PMU_BATFULL_INT_STATUS_BIT) {
PMU_Battery_Full_IRQHandler();
}
if (state_map & PMU_CHG_ACOK_INT_STATUS_BIT) {
PMU_Charge_Monitor_IRQHandler();
}
if (state_map & PMU_LVD_INT_STATUS_BIT) {
PMU_LVD_IRQHandler();
}
if (state_map & PMU_RTC_A_INT_STATUS_BIT) {
RTC_ALARMA_IRQHandler();
}
if (state_map & PMU_RTC_B_INT_STATUS_BIT) {
RTC_ALARMB_IRQHandler();
}
if (state_map & PMU_GPIO_PMU_INT_STATUS_BIT) {
PMU_GPIO_PMU_IRQHandler();
}
if (state_map & PMU_GPIO_GROUPH_INT_STATUS_BIT) {
PMU_GPIO_GROUPH_IRQHandler();
}
if (state_map & PMU_GPIO_GROUPL_INT_STATUS_BIT) {
PMU_GPIO_GROUPL_IRQHandler();
}
if (state_map & PMU_ADKEY0_INT_STATUS_BIT) {
PMU_ADKEY0_IRQHandler();
}
if (state_map & PMU_ADKEY1_INT_STATUS_BIT) {
PMU_ADKEY1_IRQHandler();
}
if (state_map & PMU_WDT_INT_STATUS_BIT) {
PMU_IWDT_IRQhandler();
}
pmu_clear_isr_state(state_map);
}

View File

@ -0,0 +1,127 @@
/*
******************************************************************************
* @file driver_pmu_iwdt.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2023
* @brief pmu iwdt module driver.
* This file provides firmware functions to manage the
* PMU Independent watchdog (IWDT) peripheral
******************************************************************************
* @attention
*
* Copyright (c) 2023 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
/*********************************************************************
* @fn iwdt_init
*
* @brief init the Watchdog.
*/
void iwdt_init(iwdt_Init_t Init)
{
/* enable pmu wdt clock */
ool_write(PMU_REG_CLK_EN, ool_read(PMU_REG_CLK_EN) | PMU_WDT_CLK_EN_BIT);
/* Set iwdt_Count and iwdt_Timeout */
iwdt_Set_Count(Init.iwdt_Count);
iwdt_Set_Timeout(Init.iwdt_Timeout);
/* Set iwdt control */
ool_write(PMU_REG_WDT_CTRL, Init.iwdt_int_Enable | PMU_WDT_RST_CHIP_BIT);
/* iwdt interrupt enable */
if (Init.iwdt_int_Enable)
{
pmu_enable_isr(PMU_WDT_INT_MSK_BIT);
}
else
{
pmu_disable_isr(PMU_WDT_INT_MSK_BIT);
}
}
/*********************************************************************
* @fn iwdt_Enable
*
* @brief Watchdog count Enable.
*/
void iwdt_Enable(void)
{
/* enable iwdt count */
ool_write(PMU_REG_WDT_CTRL, ool_read(PMU_REG_WDT_CTRL) | PMU_WDT_EN_BIT);
}
/*********************************************************************
* @fn iwdt_Disable
*
* @brief Watchdog count Disable.
*/
void iwdt_Disable(void)
{
/* disable iwdt count */
ool_write(PMU_REG_WDT_CTRL, ool_read(PMU_REG_WDT_CTRL) & ~PMU_WDT_EN_BIT);
}
/*********************************************************************
* @fn iwdt_Refresh
*
* @brief Refresh the Watchdog.
*/
void iwdt_Refresh(void)
{
ool_write(PMU_REG_WDT_CTRL, ool_read(PMU_REG_WDT_CTRL) | PMU_WDT_CLR_BIT);
}
/*********************************************************************
* @fn iwdt_Interrupt_Enable
*
* @brief Watchdog Interrupt Enable.
*/
void iwdt_Interrupt_Enable(void)
{
/* enable iwdt interrupt */
ool_write(PMU_REG_WDT_CTRL, ool_read(PMU_REG_WDT_CTRL) | PMU_WDT_IRQ_EN_BIT);
}
/*********************************************************************
* @fn iwdt_Interrupt_Disable
*
* @brief Watchdog Interrupt Disable.
*/
void iwdt_Interrupt_Disable(void)
{
/* enable iwdt interrupt */
ool_write(PMU_REG_WDT_CTRL, ool_read(PMU_REG_WDT_CTRL) & ~PMU_WDT_IRQ_EN_BIT);
}
/*********************************************************************
* @fn iwdt_Set_Count
*
* @brief Set watchdog count.
*
* @param iwdtCount: watchdog count (0x00000000 ~ 0xFFFFFFFF).
*/
void iwdt_Set_Count(uint32_t iwdtCount)
{
/* set iwdt Count value */
ool_write32(PMU_REG_WDT_LEN_0, iwdtCount);
}
/*********************************************************************
* @fn iwdt_Set_Timeout
*
* @brief Set watchdog Timeout. Timeout trigger the system reset.
* Attention: Timeout Set to 0 the system will not reset.
*
* @param WdtCount: watchdog Timeout value (0x0000 ~ 0xFFFF).
*/
void iwdt_Set_Timeout(uint16_t iwdtTimeout)
{
/* set iwdt timeout value */
ool_write16(PMU_REG_WDT_TOUT_COUNTER_0, iwdtTimeout);
}

View File

@ -0,0 +1,272 @@
/*
******************************************************************************
* @file driver_pmu_rtc.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2023
* @brief rtc module driver.
* This file provides firmware functions to manage the
* Real Time Clock (RTC) peripheral
******************************************************************************
* @attention
*
* Copyright (c) 2023 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
static str_Time_t AlarmTime_A;
static str_Time_t AlarmTime_B;
/*********************************************************************
* @fn rtc_AlarmA_Handler
*
* @brief Alarm interrupt handler
*/
__WEAK void rtc_AlarmA_Handler(void)
{
/* Update according to the periodic period in the rtc_AlarmConfig function. */
rtc_AlarmUpdate(AlARM_A);
}
/*********************************************************************
* @fn rtc_AlarmB_Handler
*
* @brief Alarm interrupt handler
*/
__WEAK void rtc_AlarmB_Handler(void)
{
/* Update according to the periodic period in the rtc_AlarmConfig function. */
rtc_AlarmUpdate(AlARM_B);
}
/*********************************************************************
* @fn rtc_init
*
* @brief rtc init
*
* @param InitValue: RTC init value.
*/
void rtc_init(uint32_t InitValue)
{
/* RTC clock enable */
ool_write(PMU_REG_CLK_EN, ool_read(PMU_REG_CLK_EN) | PMU_RTC_CLK_EN_BIT);
/* config init value */
ool_write32(PMU_REG_RTC_COUNTER_0, InitValue);
/* load init into cnt register */
ool_write(PMU_REG_RTC_CTRL, ool_read(PMU_REG_RTC_CTRL) | PMU_RTC_UPD_EN_BIT);
AlarmTime_A.UnitBackup = 0;
AlarmTime_B.UnitBackup = 0;
}
/*********************************************************************
* @fn rtc_CountEnable
*
* @brief RTC count enable
*/
void rtc_CountEnable(void)
{
ool_write(PMU_REG_CLK_EN, ool_read(PMU_REG_CLK_EN) | PMU_RTC_CLK_EN_BIT);
}
/*********************************************************************
* @fn rtc_CountDisable
*
* @brief RTC count disable
*/
void rtc_CountDisable(void)
{
ool_write(PMU_REG_CLK_EN, ool_read(PMU_REG_CLK_EN) & ~PMU_RTC_CLK_EN_BIT);
}
/*********************************************************************
* @fn rtc_AlarmConfig
*
* @brief rtc alarm config
*
* @param fe_Alarm: alarm select.
* @param lu8_hour: hour
* @param lu8_Minute: minute
* @param lu8_Second: second
*/
void rtc_AlarmConfig(enum_Alarm_t fe_Alarm, uint32_t fu32_hour, uint32_t fu32_Minute, uint32_t fu32_Second)
{
uint32_t lu32_Second;
lu32_Second = fu32_hour * 3600;
lu32_Second += fu32_Minute * 60;
lu32_Second += fu32_Second;
switch (fe_Alarm)
{
case AlARM_A:
{
/* Timing unit backup */
AlarmTime_A.UnitBackup = lu32_Second;
/* Convert to count value */
lu32_Second *= pmu_lp_rc_get();
lu32_Second += rtc_GetCount();
rtc_AlarmSet(AlARM_A, lu32_Second);
rtc_AlarmEnable(AlARM_A);
pmu_enable_isr(PMU_RTC_A_INT_MSK_BIT);
}break;
case AlARM_B:
{
/* Timing backup */
AlarmTime_B.UnitBackup = lu32_Second;
/* Convert to count value */
lu32_Second *= pmu_lp_rc_get();
lu32_Second += rtc_GetCount();
rtc_AlarmSet(AlARM_B, lu32_Second);
rtc_AlarmEnable(AlARM_B);
pmu_enable_isr(PMU_RTC_B_INT_MSK_BIT);
}break;
default: break;
}
}
/*********************************************************************
* @fn rtc_GetCount
*
* @brief Get rtc current counter value
*
* @param None.
* @return lu32_CountValue: rtc current counter value.
*/
uint32_t rtc_GetCount(void)
{
uint32_t lu32_CountValue;
/* get current RTC counter */
ool_write(PMU_REG_RTC_CTRL, ool_read(PMU_REG_RTC_CTRL) | PMU_RTC_SAMPLE_BIT);
while ( ool_read(PMU_REG_RTC_CTRL) & PMU_RTC_SAMPLE_BIT);
lu32_CountValue = ool_read32(PMU_REG_RTC_COUNTER_0);
return lu32_CountValue;
}
/*********************************************************************
* @fn rtc_CountUpdate
*
* @brief Update RTC counter
*
* @param fu32_CountValue: update value.
* @return None.
*/
void rtc_CountUpdate(uint32_t fu32_CountValue)
{
/* config init value */
ool_write32(PMU_REG_RTC_COUNTER_0, fu32_CountValue);
/* load init into cnt register */
ool_write(PMU_REG_RTC_CTRL, ool_read(PMU_REG_RTC_CTRL) | PMU_RTC_UPD_EN_BIT);
}
/*********************************************************************
* @fn rtc_AlarmUpdate
*
* @brief rtc alarm Update.
* Update according to the periodic period in the rtc_AlarmConfig function.
*
* @param fe_Alarm: alarm select.
*/
void rtc_AlarmUpdate(enum_Alarm_t fe_Alarm)
{
uint32_t lu32_AddValue;
uint32_t lu32_AlarmValue;
/* Convert to count value */
if (fe_Alarm == AlARM_A)
lu32_AddValue = AlarmTime_A.UnitBackup * pmu_lp_rc_get();
else
lu32_AddValue = AlarmTime_B.UnitBackup * pmu_lp_rc_get();
lu32_AlarmValue = rtc_AlarmRead(fe_Alarm);
lu32_AlarmValue += lu32_AddValue;
rtc_AlarmSet(fe_Alarm, lu32_AlarmValue);
}
/*********************************************************************
* @fn rtc_AlarmEnable
*
* @brief Alarm Enable
*/
void rtc_AlarmEnable(enum_Alarm_t fe_Alarm)
{
ool_write(PMU_REG_RTC_CTRL, ool_read(PMU_REG_RTC_CTRL) | fe_Alarm);
}
/*********************************************************************
* @fn rtc_ALarmDisable
*
* @brief Alarm Disable
*/
void rtc_AlarmDisable(enum_Alarm_t fe_Alarm)
{
ool_write(PMU_REG_RTC_CTRL, ool_read(PMU_REG_RTC_CTRL) & ~fe_Alarm);
}
/*********************************************************************
* @fn rtc_AlarmRead
*
* @brief read rtc alarm config value
*
* @return lu32_ConfigValue: alarm config value.
*/
uint32_t rtc_AlarmRead(enum_Alarm_t fe_Alarm)
{
uint32_t fu32_AlarmValue;
switch (fe_Alarm)
{
case AlARM_A:
{
fu32_AlarmValue = ool_read32(PMU_REG_ALARM_A_COUNTER_0);
}break;
case AlARM_B:
{
fu32_AlarmValue = ool_read32(PMU_REG_ALARM_B_COUNTER_0);
}break;
default: break;
}
return fu32_AlarmValue;
}
/*********************************************************************
* @fn rtc_AlarmSet
*
* @brief Set rtc alarm config value
*
* @param fu32_AlarmValue: alarm config value.
*/
void rtc_AlarmSet(enum_Alarm_t fe_Alarm, uint32_t fu32_AlarmValue)
{
switch (fe_Alarm)
{
case AlARM_A:
{
ool_write32(PMU_REG_ALARM_A_COUNTER_0, fu32_AlarmValue);
}break;
case AlARM_B:
{
ool_write32(PMU_REG_ALARM_B_COUNTER_0, fu32_AlarmValue);
}break;
}
}

View File

@ -0,0 +1,306 @@
/*
******************************************************************************
* @file driver_pwm.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief SPI module driver.
* This file provides firmware functions to manage the
* Pulse-Width Modulatio (PWM) peripheral
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
/************************************************************************************
* @fn pwm_config
*
* @brief PWM mode. Config channel paramter.
*
* @param PWMx: PWM0<4D><30>PWM1.
* fu16_channel: Select output channel.(1bit ~ 1channel)
* fstr_Config: Config paramter.
*/
void pwm_config(struct_PWM_t *PWMx, uint16_t fu16_channel, struct_PWM_Config_t fstr_Config)
{
uint32_t lu32_Position = 0;
uint32_t lu32_Current_Channel;
PWMx->OutputSelect &= ~fu16_channel;
/* Configure Select channel */
while (fu16_channel >> lu32_Position != 0)
{
/* Get current pin position */
lu32_Current_Channel = fu16_channel & (1uL << lu32_Position);
if (lu32_Current_Channel)
{
/* stop sync update */
PWMx->Update.PWM_Update &= ~lu32_Current_Channel;
PWMx->Edge[lu32_Position].Posedge = fstr_Config.Posedge;
PWMx->Edge[lu32_Position].Negedeg = fstr_Config.Negedge;
PWMx->Frequency[lu32_Position].Prescale = fstr_Config.Prescale - 1;
PWMx->Frequency[lu32_Position].Period = fstr_Config.Period - 1;
}
lu32_Position++;
}
}
/************************************************************************************
* @fn pwm_complementary_config
*
* @brief Complementary outputs with dead-time insertion
*
* @param PWMx: PWM0<4D><30>PWM1.
* fu16_MainChannel: Select main output channel.(1bit ~ 1channel)
* @param ComplementaryChannel: Select complementary output channel.(1bit ~ 1channel)
* fstr_Config: Config paramter.
*/
bool pwm_complementary_config(struct_PWM_t *PWMx, uint16_t fu16_MainChannel, uint16_t ComplementaryChannel, struct_PWM_Complementary_Config_t fstr_Config)
{
struct_PWM_Config_t PWM_Config;
PWM_Config.Prescale = fstr_Config.Prescale;
PWM_Config.Period = fstr_Config.Period;
if (fstr_Config.MianDeadTime != 0)
{
if (fstr_Config.MianDeadTime - 1 >= PWM_Config.Period - 1 - fstr_Config.DutyCycle - fstr_Config.MianDeadTime)
return false;
PWM_Config.Posedge = fstr_Config.MianDeadTime - 1;
PWM_Config.Negedge = PWM_Config.Period - 1 - fstr_Config.DutyCycle - fstr_Config.MianDeadTime;
}
else
{
/* Error check */
if (fstr_Config.DutyCycle >= PWM_Config.Period)
return false;
if (fstr_Config.DutyCycle == 0)
return false;
PWM_Config.Posedge = PWM_Config.Period - 1;
PWM_Config.Negedge = PWM_Config.Period - 1 - fstr_Config.DutyCycle;
}
pwm_config(PWMx, fu16_MainChannel, PWM_Config);
if (fstr_Config.CompDeadTime != 0)
{
if (PWM_Config.Period - 1 - fstr_Config.DutyCycle + fstr_Config.MianDeadTime >= PWM_Config.Period - 1 - fstr_Config.CompDeadTime)
return false;
PWM_Config.Posedge = PWM_Config.Period - 1 - fstr_Config.DutyCycle + fstr_Config.MianDeadTime;
PWM_Config.Negedge = PWM_Config.Period - 1 - fstr_Config.CompDeadTime;
}
else
{
/* Error check */
if (fstr_Config.DutyCycle >= PWM_Config.Period)
return false;
if (fstr_Config.DutyCycle == 0)
return false;
PWM_Config.Posedge = PWM_Config.Period - 1 - fstr_Config.DutyCycle;
PWM_Config.Negedge = PWM_Config.Period - 1;
}
pwm_config(PWMx, ComplementaryChannel, PWM_Config);
return true;
}
/************************************************************************************
* @fn pwm_output_enable
*
* @brief PWM_DAC mode. output enable.
*
* @param PWMx: PWM0<4D><30>PWM1.
* fu16_channel: Select output channel.(1bit ~ 1channel)
*/
void pwm_output_enable(struct_PWM_t *PWMx, uint16_t fu16_channel)
{
PWMx->Update.PWM_Update |= fu16_channel;
PWMx->CNT_EN |= fu16_channel;
PWMx->ChannelEN |= fu16_channel;
}
/************************************************************************************
* @fn pwm_output_disable
*
* @brief PWM_DAC mode. output disable.
*
* @param PWMx: PWM0<4D><30>PWM1.
* fu8_channel: Select output channel.(1bit ~ 1channel)
*/
void pwm_output_disable(struct_PWM_t *PWMx, uint16_t fu16_channel)
{
/* stop sync update */
PWMx->Update.PWM_Update &= ~fu16_channel;
PWMx->ChannelEN &= ~fu16_channel;
PWMx->CNT_EN &= ~fu16_channel;
}
/************************************************************************************
* @fn pwm_output_status
*
* @brief PWM_DAC mode. output inverter disable.
*
* @param PWMx: PWM0<4D><30>PWM1.
* fe_channel: Select output channel.(1bit ~ 1channel)
*
* @return true : PWM runing.
* false: PWM stop.
*/
bool pwm_output_status(struct_PWM_t *PWMx, enum_PWMChannel_t fe_channel)
{
if (PWMx->Update.PWM_Status & fe_channel)
{
return true;
}
else
{
return false;
}
}
/************************************************************************************
* @fn pwm_output_updata
*
* @brief channel Posedge/Negedeg/Prescale/Period updata
*
* @param PWMx: PWM0<4D><30>PWM1.
* fu16_channel: Select output channel.(1bit ~ 1channel)
*/
void pwm_output_updata(struct_PWM_t *PWMx, uint16_t fu16_channel)
{
/* start sync update */
PWMx->Update.PWM_Update |= fu16_channel;
}
/************************************************************************************
* @fn pwm_capture_config
*
* @brief Capture mode. Config channel paramter.
*
* @param PWMx: PWM0<4D><30>PWM1.
* fu16_channel: Select capture channel(1bit ~ 1channel).
* fstr_Config: Config paramter.
*/
void pwm_capture_config(struct_PWM_t *PWMx, uint16_t fu16_channel, struct_Capture_Config_t fstr_Config)
{
uint32_t lu32_Position = 0;
uint32_t lu32_Current_Channel;
/* Set Capture Prescale */
PWMx->CapturePrescale = 0x10 | fstr_Config.CapturePrescale;
/* Configure Select channel */
while (fu16_channel >> lu32_Position != 0)
{
/* Get current pin position */
lu32_Current_Channel = fu16_channel & (1uL << lu32_Position);
if (lu32_Current_Channel)
{
/* Set Capture mode */
if (fstr_Config.CaptureMode == MODE_LOOP)
{
PWMx->CaptureCtrl.Capture_Mode &= ~lu32_Current_Channel;
}
else
{
PWMx->CaptureCtrl.Capture_Mode |= lu32_Current_Channel;
}
}
lu32_Position++;
}
}
/************************************************************************************
* @fn pwm_capture_enable
*
* @brief capture enable.
*
* @param PWMx: PWM0<4D><30>PWM1.
* fu16_channel: Select capture channel.(1bit ~ 1channel)
*/
void pwm_capture_enable(struct_PWM_t *PWMx, uint16_t fu16_channel)
{
PWMx->CaptureCtrl.Capture_EN |= fu16_channel;
}
/************************************************************************************
* @fn pwm_capture_disable
*
* @brief pwm_capture_disable.
*
* @param PWMx: PWM0<4D><30>PWM1.
* fu16_channel: Select capture channel.(1bit ~ 1channel)
*/
void pwm_capture_disable(struct_PWM_t *PWMx, uint16_t fu16_channel)
{
PWMx->CaptureCtrl.Capture_EN &= ~fu16_channel;
}
/************************************************************************************
* @fn pwm_capture_status
*
* @brief get pwm_capture_status.
*
* @param PWMx: PWM0<4D><30>PWM1.
* fe_channel: Select capture channel.(1bit ~ 1channel)
* @return true : capture result value ready.
* false: capture result value not ready.
*/
bool pwm_capture_status(struct_PWM_t *PWMx, enum_PWMChannel_t fe_channel)
{
return (PWMx->CaptureStatus & fe_channel) ? true : false;
}
/************************************************************************************
* @fn pwm_capture_status_clear
*
* @brief capture status claear.
*
* @param PWMx: PWM0<4D><30>PWM1.
* fe_channel: Select capture channel.(1bit ~ 1channel)
*/
void pwm_capture_status_clear(struct_PWM_t *PWMx,enum_PWMChannel_t fe_channel)
{
PWMx->CaptureStatus |= fe_channel;
}
/************************************************************************************
* @fn pwm_capture_value
*
* @brief get pwm_capture_value.
*
* @param PWMx: PWM0<4D><30>PWM1.
* fe_channel: Select capture channel.(1bit ~ 1channel)
*/
uint32_t pwm_capture_value(struct_PWM_t *PWMx, enum_PWMChannel_t fe_channel)
{
uint8_t i;
for (i = 0; i < 16; i++)
{
if (fe_channel & 1 << i)
break;
}
return PWMx->CaptureValue[i];
}

View File

@ -0,0 +1,80 @@
/*
******************************************************************************
* @file driver_qspi.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief QSPI module driver.
* This file provides firmware functions to manage the
* Quad Serial Peripheral Interface (QSPI) peripheral
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
#define QSPI_STIG_MAX_SINGLE_LEN 8
#define QSPI_STIG_BANK_DEPTH 128
__RAM_CODE int qspi_stig_cmd(struct qspi_regs_t *QSPI, struct qspi_stig_reg_t cmd, enum qspi_stig_cmd_type_t type, int len, uint8_t *buffer)
{
uint32_t tmp_u32[2];
uint8_t *tmp_u8 = (uint8_t *)tmp_u32;
if(type == QSPI_STIG_CMD_BANK_READ) {
if(QSPI_STIG_BANK_DEPTH < len) {
return -1;
}
}
else {
if(QSPI_STIG_MAX_SINGLE_LEN < len) {
return -1;
}
}
while(__QSPI_IS_BUSY(QSPI));
if(type == QSPI_STIG_CMD_EXE) {
__QSPI_STIG_CMD_SET(QSPI, cmd);
__QSPI_STIG_EXECUTE(QSPI);
while(__QSPI_STIG_ON_GOING(QSPI));
}
else {
if(type == QSPI_STIG_CMD_WRITE) {
for (volatile int32_t i=0; i<len; i++) {
*tmp_u8++ = *buffer++;
}
__QSPI_STIG_DATA_L_SET(QSPI, tmp_u32[0]);
__QSPI_STIG_DATA_H_SET(QSPI, tmp_u32[1]);
__QSPI_STIG_CMD_SET(QSPI, cmd);
__QSPI_STIG_WRITE_BYTES_SET(QSPI, len);
__QSPI_STIG_EXECUTE(QSPI);
while(__QSPI_STIG_ON_GOING(QSPI));
}
else {
__QSPI_STIG_CMD_SET(QSPI, cmd);
__QSPI_STIG_READ_BYTES_SET(QSPI, len);
__QSPI_STIG_EXECUTE(QSPI);
while(__QSPI_STIG_ON_GOING(QSPI));
if(type == QSPI_STIG_CMD_READ) {
tmp_u32[0] = __QSPI_STIG_DATA_L_GET(QSPI);
tmp_u32[1] = __QSPI_STIG_DATA_H_GET(QSPI);
for (volatile int32_t i=0; i<len; i++) {
*buffer++ = *tmp_u8++;
}
}
else {
//TBD, BANK READ
}
}
}
return 0;
}

View File

@ -0,0 +1,196 @@
/*
******************************************************************************
* @file driver_sbc_codec.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief IIR module driver.
* This file provides firmware functions to manage the
* SBC CODEC peripheral
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
#define SBC_SYNCWORD 0x9c
/******************************************************************************
* @fn sbc_dec_get_packed_frame_info
*
* @brief sbc decoder get sbc packed frame info
*
* @param data : sbc packed frame
* frame_info : struct_frame_info_t structure contains
*/
int sbc_dec_get_packed_frame_info(uint8_t *data, struct_frame_info_t frame_info)
{
if (data[0] != SBC_SYNCWORD)
{
return -2;
}
frame_info.frequency = (data[1] >> 6) & 0x03;
frame_info.block_mode = (data[1] >> 4) & 0x03;
switch (frame_info.block_mode) {
case 0:
frame_info.block_len = 4;
break;
case 1:
frame_info.block_len = 8;
break;
case 2:
frame_info.block_len = 12;
break;
case 3:
frame_info.block_len = 16;
break;
default:
frame_info.block_len = 4;
break;
}
frame_info.mode = (data[1] >> 2) & 0x03;
switch(frame_info.mode)
{
case 0:
frame_info.channels = 1;
break;
case 3:
frame_info.channels = 2;
break;
default:
break;
}
frame_info.allocation = (data[1] >> 1) & 0x01;
frame_info.subband_mode = (data[1] & 0x01);
frame_info.subbands = frame_info.subband_mode ? 8 : 4;
frame_info.bit_pool = data[2];
if((frame_info.mode == 0 || frame_info.mode == 1) &&
frame_info.bit_pool > 16 * frame_info.subbands)
return -4;
if((frame_info.mode == 3 || frame_info.mode == 2) &&
frame_info.bit_pool > 32 * frame_info.subbands)
return -4;
return 0;
}
/******************************************************************************
* @fn sbc_dec_init
*
* @brief sbc decoder initialize
*
* @param hSbcDec : sbc decoder handler
*/
void sbc_dec_init(SBC_DEC_HandleTypeDef *hSbcDec)
{
/*sbc decoder fifo init*/
SBC_DEC->SBCD_CTRL.Bits.DEC_IN_FIFO_RESET = 1;
SBC_DEC->SBCD_CTRL.Bits.DEC_OUTL_FIFO_RESET = 1;
SBC_DEC->SBCD_CTRL.Bits.DEC_OUTR_FIFO_RESET = 1;
SBC_DEC->SBCD_CTRL.Bits.DEC_RESET = 1;
/* sbc dma config initialize*/
SBC_DEC->SBCD_CTRL.Bits.IN_DMA_EN = hSbcDec->sbc_init.Bits.input_dma_en;
SBC_DEC->SBCD_CTRL.Bits.OUT_DMA_EN = hSbcDec->sbc_init.Bits.output_dma_en;
if(SBC_DEC->SBCD_CTRL.Bits.OUT_DMA_EN == 1)
{
if(hSbcDec->sbc_init.Bits.ch_mode == 1)
{
SBC_DEC->SBCD_CTRL.Bits.OUTR_FIFO_EN = 1;
}
else
{
SBC_DEC->SBCD_CTRL.Bits.OUTL_FIFO_EN = 1;
}
}
/*sbc fifo level intialize*/
SBC_DEC->SBCD_FIFO_LEVEL.Bits.INFIFO_ALEMPTY_LEVEL = hSbcDec->sbc_init.Bits.infifo_alempty_lvl;
SBC_DEC->SBCD_FIFO_LEVEL.Bits.OUTLFIFO_ALFULL_LEVEL = hSbcDec->sbc_init.Bits.outlfifo_alfull_lvl;
SBC_DEC->SBCD_FIFO_LEVEL.Bits.OUTRFIFO_ALFULL_LEVEL = hSbcDec->sbc_init.Bits.outrlfifo_alfull_lvl;
SBC_DEC->SBCD_CTRL.Bits.DEC_EN = 1;
}
/******************************************************************************
* @fn sbc_dec_playdata_IT
*
* @brief sbc decoder play data with isr
*
* @param hSbcDec : sbc decoder handler
* fp_Data : sbc packed frame data
* fu32_Size : sbc packed frame data size
* fp_Data_Out : after sbc decoder pcm data
*/
void sbc_dec_playdata_IT(SBC_DEC_HandleTypeDef *hSbcDec, uint8_t *fp_Data, uint32_t fu32_Size, uint16_t *fp_Data_Out)
{
hSbcDec->OrignData = fp_Data_Out;
hSbcDec->EncodeData = fp_Data;
hSbcDec->DataSize = fu32_Size;
hSbcDec->InputIndex = 0;
hSbcDec->OutIndex = 0;
if(hSbcDec->sbc_init.Bits.ch_mode == SBCD_MONO)
{
SBC_DEC->SBCD_INTEN.Bits.CRC_ERR_INT_EN = 1;
SBC_DEC->SBCD_INTEN.Bits.OUTLFF_ALFULL_INT_EN = 1;
SBC_DEC->SBCD_INTEN.Bits.INFF_EMPTY_INT_EN = 1;
}
else
{
SBC_DEC->SBCD_INTEN.Bits.CRC_ERR_INT_EN = 1;
SBC_DEC->SBCD_INTEN.Bits.OUTRFF_ALFULL_INT_EN = 1;
SBC_DEC->SBCD_INTEN.Bits.INFF_EMPTY_INT_EN = 1;
}
}
/******************************************************************************
* @fn sbcdec_IRQHandler
*
* @brief sbc decoder handle function in sbc decoder isr
*
* @param hSbcDec : sbc decoder handler
*/
void sbcdec_IRQHandler(SBC_DEC_HandleTypeDef *hSbcDec)
{
uint32_t status = __SBCD_GET_ISR_STS();
if(status & OUTLF_ALFULL_INT)
{
while(!__SBCD_OUTLFIFO_IS_EMPTY())
{
hSbcDec->OrignData[hSbcDec->OutIndex++] = SBC_DEC->SBCD_OUTFIFO.Bits.PCM_LEFT_DATA;
}
}
if(status & OUTRF_ALFULL_INT)
{
/*outfifo almost full need to do*/
while(!__SBCD_OUTRFIFO_IS_EMPTY())
{
hSbcDec->OrignData[hSbcDec->OutIndex++] = SBC_DEC->SBCD_OUTFIFO.Bits.PCM_LEFT_DATA;
hSbcDec->OrignData[hSbcDec->OutIndex++] = SBC_DEC->SBCD_OUTFIFO.Bits.PCM_RIGHT_DATA;
}
}
if(status & INFF_EMPTY_INT)
{
while(!__SBCD_INFIFO_IS_FULL())
{
SBC_DEC->SBCD_INFIFO.Bits.SBC_IN = hSbcDec->EncodeData[hSbcDec->InputIndex++];
if(hSbcDec->InputIndex >= hSbcDec->DataSize)
{
__SBCD_INFIFO_EMPTY_DISABLE();
if(hSbcDec->Callback)
{
hSbcDec->Callback(hSbcDec);
}
break;
}
}
}
}

View File

@ -0,0 +1,150 @@
/*
******************************************************************************
* @file driver_sbc_enc.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief SBC ENCODER module driver.
* This file provides firmware functions to manage the
* SBC ENCODER peripheral
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
/******************************************************************************
* @fn sbc_enc_init
*
* @brief Initialize the SBC encoder according to the specified parameters
* in the SBC_ENC_HandleTypeDef
*
* @param hSbcEnc : SBC_ENC_HandleTypeDef structure that contains the
* configuration information for SBC encoder module.
*/
void sbc_enc_init(SBC_ENC_HandleTypeDef *hSbcEnc)
{
/*sbc encoder init*/
SBC_ENC->SBCE_CTRL.Bits.ENC_INL_FIFO_RESET = 1;
SBC_ENC->SBCE_CTRL.Bits.ENC_INR_FIFO_RESET = 1;
SBC_ENC->SBCE_CTRL.Bits.ENC_OUT_FIFO_RESET = 1;
SBC_ENC->SBCE_CTRL.Bits.ENC_RESET = 1;
/*encode config*/
SBC_ENC->SBCE_CFG.Bits.CH_MODE = hSbcEnc->SbcEncInit.Bits.ch_mode;
if(hSbcEnc->SbcEncInit.Bits.ch_mode == SBCE_MONO)
{
SBC_ENC->SBCE_CTRL.Bits.ENC_INR_FLOW_CTRL = 1;
}
SBC_ENC->SBCE_CFG.Bits.BLK_LEN = hSbcEnc->SbcEncInit.Bits.blk_len;
SBC_ENC->SBCE_CFG.Bits.SMP_FRQ = hSbcEnc->SbcEncInit.Bits.sample_freq;
/*encode fifo level config*/
SBC_ENC->SBCE_INFIFO_LVL.Bits.INLFIFO_ALEMPTY_LEVEL = hSbcEnc->SbcEncInit.Bits.inlfifo_alempty_lvl;
SBC_ENC->SBCE_INFIFO_LVL.Bits.INRFIFO_ALEMPTY_LEVEL = hSbcEnc->SbcEncInit.Bits.inrfifo_alempty_lvl;
SBC_ENC->SBCE_OUTFF_LVL.Bits.OUTFIFO_ALFULL_LEVEL = hSbcEnc->SbcEncInit.Bits.outlfifo_alfull_lvl;
/*dma config*/
if(hSbcEnc->SbcEncInit.Bits.input_dma_en == 1)
{
SBC_ENC->SBCE_CTRL.Bits.IN_DMA_EN = 1;
SBC_ENC->SBCE_CTRL.Bits.INL_FIFO_EN = 1;
SBC_ENC->SBCE_CTRL.Bits.INR_FIFO_EN = 1;
}
if(hSbcEnc->SbcEncInit.Bits.output_dma_en == 1)
{
SBC_ENC->SBCE_CTRL.Bits.OUT_DMA_EN = 1;
}
/*sbc encoder start*/
SBC_ENC->SBCE_CTRL.Bits.ENC_EN = 1;
}
/******************************************************************************
* @fn sbc_encoder_enc_IT
*
* @brief start sbc encoder with isr
*
* @param hSbcEnc : sbc encoder handle.
* fp_Data_In : pcm data in
* fu32_size : pcm data size
* fp_Data_Out : sbc encoder packed frame out
*/
void sbc_encoder_enc_IT(SBC_ENC_HandleTypeDef *hSbcEnc, uint16_t *fp_Data_In, uint32_t fu32_size, uint8_t *fp_Data_Out)
{
hSbcEnc->OrignlData = fp_Data_In;
hSbcEnc->EncodedData = fp_Data_Out;
hSbcEnc->OrignlDataSize = fu32_size;
hSbcEnc->gDataInIndex = 0;
hSbcEnc->gDataOutIndex = 0;
SBC_ENC->SBCE_INTEN.Word |= 0x24;
return;
}
/******************************************************************************
* @fn sbcenc_IRQHandler
*
* @brief sbc encoder handle function in sbc encoder isr
*
* @param hSbcEnc : sbc encoder handle.
*
*/
void sbcenc_IRQHandler(SBC_ENC_HandleTypeDef *hSbcEnc)
{
uint32_t isr = __SBCE_GET_ISR_STS();
if(isr & OUTFF_ALFULL_INT)
{
while(!__SBCE_OUTFIFO_IS_EMPTY())
{
hSbcEnc->EncodedData[hSbcEnc->gDataOutIndex++] = (uint8_t)__SBCE_GET_OUT_RESULT_WORD();
}
}
if(isr & INLF_EMPTY_INT)
{
uint32_t read_size = 0;
if(SBC_ENC->SBCE_CFG.Bits.CH_MODE == SBCE_STEREO)/*2 channels*/
{
read_size = (hSbcEnc->OrignlDataSize - hSbcEnc->gDataInIndex) >= 256 ? 256 : (hSbcEnc->OrignlDataSize - hSbcEnc->gDataInIndex);
for(uint32_t i = 0; i< read_size/2; i++)
{
SBC_ENC->SBCE_INFIFO.Word = *((int32_t *)&hSbcEnc->OrignlData[hSbcEnc->gDataInIndex]);
hSbcEnc->gDataInIndex += 2;
}
}
else/*1 channel*/
{
read_size = (hSbcEnc->OrignlDataSize - hSbcEnc->gDataInIndex) >= 128 ? 128 : (hSbcEnc->OrignlDataSize - hSbcEnc->gDataInIndex);
for(uint32_t i = 0; i< read_size; i++)
{
SBC_ENC->SBCE_INFIFO.Bits.ENC_FFL = hSbcEnc->OrignlData[hSbcEnc->gDataInIndex++];
}
}
if(hSbcEnc->gDataInIndex >= hSbcEnc->OrignlDataSize)
{
__SBCE_INLFF_EMPTY_INT_DISABLE();
}
// while(!__SBCE_INLFIFO_IS_FULL())
// {
// if(SBC_ENC->SBCE_CFG.Bits.CH_MODE == SBCE_STEREO)/*2 channels*/
// {
// SBC_ENC->SBCE_INFIFO.Word = *((int32_t *)&hSbcEnc->OrignlData[hSbcEnc->gDataInIndex]);
// hSbcEnc->gDataInIndex += 2;
// }
// else/*1 channel*/
// {
// SBC_ENC->SBCE_INFIFO.Bits.ENC_FFL = hSbcEnc->OrignlData[hSbcEnc->gDataInIndex++];
// }
// if(hSbcEnc->gDataInIndex >= hSbcEnc->OrignlDataSize)
// {
// __SBCE_INLFF_EMPTY_INT_DISABLE();
// break;
// }
// }
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,888 @@
/*
******************************************************************************
* @file driver_sd_card.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2022
* @brief SD card application HAL module driver.
******************************************************************************
* @attention
*
* Copyright (c) 2022 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
/* Private function prototypes -----------------------------------------------*/
static uint32_t __SDCard_PowerON(SD_HandleTypeDef *hsd);
static uint32_t __SDCard_InitCard(SD_HandleTypeDef *hsd);
static void __SDCard_GetCardCSD(SD_HandleTypeDef *hsd);
static void __SDCard_GetCardCID(SD_HandleTypeDef *hsd);
/************************************************************************************
* @fn SDCard_IRQHandler
*
* @brief SDCard interrupt handler.
*
* @param hsd: Pointer to SD handle
*/
void SDCard_IRQHandler(SD_HandleTypeDef *hsd)
{
switch (hsd->CardStatus)
{
/* card read, write */
case CARD_STATUS_READ_BUSY:
case CARD_STATUS_WIRTE_BUSY:
{
/* DMA interrupt */
if (__SD_GET_INT_STATUS(hsd->SDx) & INT_DMA_INT)
{
__SD_CLR_INT_STATUS(hsd->SDx, INT_DMA_INT);
/* SDMA system Address alignment increases */
hsd->AddrAlign += SDMA_ADDR_UNIT;
/* Update SDMA system Address */
__SD_SET_SDMA_SYSTEM_ADDR(hsd->SDx, (uint32_t)hsd->AddrAlign);
}
/* error */
if (__SD_GET_INT_STATUS(hsd->SDx) & INT_ERR_MASK)
{
/* clear interrupt status */
__SD_CLR_ALL_INT_STATUS(hsd->SDx);
hsd->CardStatus = CARD_STATUS_ERR;
}
/* transfer complete */
if (__SD_GET_INT_STATUS(hsd->SDx) & INT_TRANSFER_COMPLETE)
{
/* clear transfer complete statsu */
__SD_CLR_INT_STATUS(hsd->SDx, INT_TRANSFER_COMPLETE);
hsd->CardStatus = CARD_STATUS_IDLE;
}
}break;
default: break;
}
}
/************************************************************************************
* @fn SDCard_Init
*
* @brief Initializes the SD Card.
*
* @param hsd: Pointer to SD handle
*/
uint32_t SDCard_Init(SD_HandleTypeDef *hsd)
{
uint32_t lu32_ErrState = INT_NO_ERR;
/* SD Crad class initialization */
SD_SDCardClass_Init(hsd->SDx);
for(volatile uint32_t i=0; i<10000; i++);
/* Identify card operating voltage */
lu32_ErrState = __SDCard_PowerON(hsd);
if (lu32_ErrState)
{
return lu32_ErrState;
}
/* Card initialization */
lu32_ErrState = __SDCard_InitCard(hsd);
if (lu32_ErrState)
{
return lu32_ErrState;
}
/* Get the card information from the CID register */
__SDCard_GetCardCID(hsd);
/* Get the card information from the CSD register */
__SDCard_GetCardCSD(hsd);
return lu32_ErrState;
}
/************************************************************************************
* @fn SDCard_BusWidth_Select
*
* @brief SDCard 1bit/4bit bus width select.
*
* @param hsd: Pointer to SD handle.
* fu32_BusWidth: bus width. can select SDIO_BUS_WIDTH_1BIT.
* SDIO_BUS_WIDTH_4BIT.
*/
uint32_t SDCard_BusWidth_Select(SD_HandleTypeDef *hsd, uint32_t fu32_BusWidth)
{
uint32_t lu32_ErrState = INT_NO_ERR;
/* SEND CMD55 APP_CMD with RCA as 0 */
lu32_ErrState = SD_CMD_AppCommand(hsd->SDx, hsd->RCA);
if (lu32_ErrState)
{
return lu32_ErrState;
}
/* Send ACMD6 SET_BUS_WIDTH */
lu32_ErrState = SD_ACMD_SetBusWidth(hsd->SDx, fu32_BusWidth);
if (lu32_ErrState)
{
return lu32_ErrState;
}
else
{
if (fu32_BusWidth)
__SD_DATA_WIDTH_4BIT(hsd->SDx);
else
__SD_DATA_WIDTH_1BIT(hsd->SDx);
}
return lu32_ErrState;
}
/************************************************************************************
* @fn SDCard_ReadBolcks
*
* @brief Reads block(s) from a specified address in a card.
* The Data transfer by polling mode.
*
* @param hsd: Pointer to SD handle.
* fp_Data: pointer to the received dat buffer.
* fu32_BlockAddr: Block Start Address.
* fu16_BlockNum: Number of SD blocks to read.
*/
uint32_t SDCard_ReadBolcks(SD_HandleTypeDef *hsd, uint32_t *fp_Data, uint32_t fu32_BlockAddr, uint16_t fu16_BlockNum)
{
int i;
uint32_t lu32_ErrState = INT_NO_ERR;
if (fu16_BlockNum == 0)
return E1_NUM_ERR;
if (fu16_BlockNum == 1)
{
/* SEND CMD17 READ_SINGLI_BLOCK */
lu32_ErrState = SD_CMD_ReadSingleBlock(hsd->SDx, fu32_BlockAddr);
if (lu32_ErrState)
return lu32_ErrState;
/* Wait for Buffer Read Ready Int */
while(!(__SD_GET_INT_STATUS(hsd->SDx) & INT_BUFFER_READ_READY));
/* Clear Buffer_Read_Ready */
__SD_CLR_INT_STATUS(hsd->SDx, INT_BUFFER_READ_READY);
/* Read one block */
for (i = 0; i < BLOCKSIZE / 4; i++)
{
*fp_Data++ = __SD_GET_BUFFERDATA(hsd->SDx);
}
}
else
{
/* SEND CMD23 SET_BLOCK_COUNT */
lu32_ErrState = SD_CMD_SetBlockCount(hsd->SDx, fu16_BlockNum);
if (lu32_ErrState)
return lu32_ErrState;
/* Set block count */
__SD_SET_BLOCK_COUNT(hsd->SDx, fu16_BlockNum);
/* SEND CMD18 READ_MULTIPLE_BLOCK */
lu32_ErrState = SD_CMD_ReadMultiBlock(hsd->SDx, fu32_BlockAddr);
if (lu32_ErrState)
return lu32_ErrState;
while (fu16_BlockNum--)
{
/* Wait for Buffer_Read_Ready */
while(!(__SD_GET_INT_STATUS(hsd->SDx) & INT_BUFFER_READ_READY));
/* Clear Buffer_Read_Ready */
__SD_CLR_INT_STATUS(hsd->SDx, INT_BUFFER_READ_READY);
/* Read one block */
for (i = 0; i < BLOCKSIZE / 4; i++)
{
*fp_Data++ = __SD_GET_BUFFERDATA(hsd->SDx);
}
}
}
/* wait for transfer complete or any errors occur */
while(!(__SD_GET_INT_STATUS(hsd->SDx) & (INT_TRANSFER_COMPLETE | INT_ERR_MASK)));
/* Any errors occur */
if (__SD_GET_INT_STATUS(hsd->SDx) & INT_ERR_MASK)
{
lu32_ErrState = __SD_GET_INT_STATUS(hsd->SDx) & INT_ERR_MASK;
}
/* clear interrupt status */
__SD_CLR_ALL_INT_STATUS(hsd->SDx);
return lu32_ErrState;
}
/************************************************************************************
* @fn SDCard_WriteBolcks
*
* @brief Write block(s) from a specified address in a card.
* The Data transfer by polling mode.
*
* @param hsd: Pointer to SD handle.
* fp_Data: pointer to the received dat buffer.
* fu32_BlockAddr: Block Address.
* fu16_BlockNum: Number of SD blocks to write.
*/
uint32_t SDCard_WriteBolcks(SD_HandleTypeDef *hsd, uint32_t *fp_Data, uint32_t fu32_BlockAddr, uint16_t fu16_BlockNum)
{
int i;
uint32_t lu32_ErrState = INT_NO_ERR;
if (fu16_BlockNum == 0)
return E1_NUM_ERR;
if (fu16_BlockNum == 1)
{
/* SEND CMD24 WRITE_BLOCK */
lu32_ErrState = SD_CMD_WriteSingleBlock(hsd->SDx, fu32_BlockAddr);
if (lu32_ErrState)
return lu32_ErrState;
/* Wait for buffer write enable Int */
while(!(__SD_GET_PRESENT_STATE(hsd->SDx) & PreState_BUFFER_WRITE_EN_MASK));
/* write one block */
for (i = 0; i < BLOCKSIZE / 4; i++)
{
__SD_SET_BUFFERDATA(hsd->SDx, *fp_Data++);
}
}
else
{
/* SEND CMD23 SET_BLOCK_COUNT */
lu32_ErrState = SD_CMD_SetBlockCount(hsd->SDx, fu16_BlockNum);
if (lu32_ErrState)
return lu32_ErrState;
/* Set block count */
__SD_SET_BLOCK_COUNT(hsd->SDx, fu16_BlockNum);
/* SEND CMD25 WRITE_MULTIPLE_BLOCK */
lu32_ErrState = SD_CMD_WriteMultiBlock(hsd->SDx, fu32_BlockAddr);
if (lu32_ErrState)
return lu32_ErrState;
/* First block transfer check the PresentState register */
/* Wait for Buffer_Write_Enable */
while(!(__SD_GET_PRESENT_STATE(hsd->SDx) & PreState_BUFFER_WRITE_EN_MASK));
/* write one block */
for (i = 0; i < BLOCKSIZE / 4; i++)
{
__SD_SET_BUFFERDATA(hsd->SDx, *fp_Data++);
}
fu16_BlockNum--;
/* Other block transfer check the StatusInt register */
while(fu16_BlockNum--)
{
/* Wait for Buffer_Write_Ready */
while(!(__SD_GET_INT_STATUS(hsd->SDx) & INT_BUFFER_WRITE_READY));
/* Clear Buffer_Write_Ready */
__SD_CLR_INT_STATUS(hsd->SDx, INT_BUFFER_WRITE_READY);
/* write one block */
for (i = 0; i < BLOCKSIZE / 4; i++)
{
__SD_SET_BUFFERDATA(hsd->SDx, *fp_Data++);
}
}
}
/* wait for transfer complete or any errors occur */
while(!(__SD_GET_INT_STATUS(hsd->SDx) & (INT_TRANSFER_COMPLETE | INT_ERR_MASK)));
/* Any errors occur */
if (__SD_GET_INT_STATUS(hsd->SDx) & INT_ERR_MASK)
{
lu32_ErrState = __SD_GET_INT_STATUS(hsd->SDx) & INT_ERR_MASK;
}
/* clear interrupt status */
__SD_CLR_ALL_INT_STATUS(hsd->SDx);
return lu32_ErrState;
}
/************************************************************************************
* @fn SDCard_ReadBolcks_SDMA
*
* @brief Reads block(s) from a specified address in a card.
* The Data transfer by SDMA(Simple DMA) mode.
*
* @param hsd: Pointer to SD handle.
* fp_Data: pointer to the received dat buffer.
* fu32_BlockAddr: Block Start Address.
* fu16_BlockNum: Number of SD blocks to read.
*/
uint32_t SDCard_ReadBolcks_SDMA(SD_HandleTypeDef *hsd, uint32_t *fp_Data, uint32_t fu32_BlockAddr, uint16_t fu16_BlockNum)
{
int i;
uint32_t lu32_ErrState = INT_NO_ERR;
bool lb_TrfComplete = true;
uint32_t lu32_Addr = (uint32_t)fp_Data;
if (fu16_BlockNum == 0)
return E1_NUM_ERR;
/* SEND CMD23 SET_BLOCK_COUNT */
lu32_ErrState = SD_CMD_SetBlockCount(hsd->SDx, fu16_BlockNum);
if (lu32_ErrState)
return lu32_ErrState;
/* set SDMA system Address */
__SD_SET_SDMA_SYSTEM_ADDR(hsd->SDx, (uint32_t)fp_Data);
/* Set block count */
__SD_SET_BLOCK_COUNT(hsd->SDx, fu16_BlockNum);
/* SEND CMD18 READ_MULTIPLE_BLOCK */
lu32_ErrState = SD_CMD_ReadBlock_SDMA(hsd->SDx, fu32_BlockAddr);
if (lu32_ErrState)
return lu32_ErrState;
/* Address alignment */
lu32_Addr &= SDMA_ADDR_ALIGN_MASK;
/* wait for transfer complete or any errors occur */
while (lb_TrfComplete)
{
if (__SD_GET_INT_STATUS(hsd->SDx) & (INT_TRANSFER_COMPLETE | INT_ERR_MASK))
{
lb_TrfComplete = false;
}
if (__SD_GET_INT_STATUS(hsd->SDx) & INT_DMA_INT)
{
__SD_CLR_INT_STATUS(hsd->SDx, INT_DMA_INT);
/* SDMA system Address alignment increases */
lu32_Addr += SDMA_ADDR_UNIT;
/* Update SDMA system Address */
__SD_SET_SDMA_SYSTEM_ADDR(hsd->SDx, (uint32_t)lu32_Addr);
}
}
/* Any errors occur */
if (__SD_GET_INT_STATUS(hsd->SDx) & INT_ERR_MASK)
{
lu32_ErrState = __SD_GET_INT_STATUS(hsd->SDx) & INT_ERR_MASK;
}
/* clear interrupt status */
__SD_CLR_ALL_INT_STATUS(hsd->SDx);
return lu32_ErrState;
}
/************************************************************************************
* @fn SDCard_WriteBolcks_SDMA
*
* @brief Write block(s) from a specified address in a card.
* The Data transfer by SDMA(Simple DMA) mode.
*
* @param hsd: Pointer to SD handle.
* fp_Data: pointer to the received dat buffer.
* fu32_BlockAddr: Block Address.
* fu16_BlockNum: Number of SD blocks to write.
*/
uint32_t SDCard_WriteBolcks_SDMA(SD_HandleTypeDef *hsd, uint32_t *fp_Data, uint32_t fu32_BlockAddr, uint16_t fu16_BlockNum)
{
int i;
uint32_t lu32_ErrState = INT_NO_ERR;
bool lb_TrfComplete = true;
uint32_t lu32_Addr = (uint32_t)fp_Data;
if (fu16_BlockNum == 0)
return E1_NUM_ERR;
/* SEND CMD23 SET_BLOCK_COUNT */
lu32_ErrState = SD_CMD_SetBlockCount(hsd->SDx, fu16_BlockNum);
if (lu32_ErrState)
return lu32_ErrState;
/* set SDMA system Address */
__SD_SET_SDMA_SYSTEM_ADDR(hsd->SDx, (uint32_t)fp_Data);
/* Set block count */
__SD_SET_BLOCK_COUNT(hsd->SDx, fu16_BlockNum);
/* SEND CMD25 WRITE_MULTIPLE_BLOCK */
lu32_ErrState = SD_CMD_WriteBlock_SDMA(hsd->SDx, fu32_BlockAddr);
if (lu32_ErrState)
return lu32_ErrState;
/* Address alignment */
lu32_Addr &= SDMA_ADDR_ALIGN_MASK;
/* wait for transfer complete or any errors occur */
while (lb_TrfComplete)
{
if (__SD_GET_INT_STATUS(hsd->SDx) & (INT_TRANSFER_COMPLETE | INT_ERR_MASK))
{
lb_TrfComplete = false;
}
if (__SD_GET_INT_STATUS(hsd->SDx) & INT_DMA_INT)
{
__SD_CLR_INT_STATUS(hsd->SDx, INT_DMA_INT);
/* SDMA system Address alignment increases */
lu32_Addr += SDMA_ADDR_UNIT;
/* Update SDMA system Address */
__SD_SET_SDMA_SYSTEM_ADDR(hsd->SDx, (uint32_t)lu32_Addr);
}
}
/* Any errors occur */
if (__SD_GET_INT_STATUS(hsd->SDx) & INT_ERR_MASK)
{
lu32_ErrState = __SD_GET_INT_STATUS(hsd->SDx) & INT_ERR_MASK;
}
/* clear interrupt status */
__SD_CLR_ALL_INT_STATUS(hsd->SDx);
return lu32_ErrState;
}
/************************************************************************************
* @fn SDCard_ReadBolcks_SDMA_IT
*
* @brief Reads block(s) from a specified address in a card.
* The Data transfer by SDMA(Simple DMA) mode with interrupt.
*
* @param hsd: Pointer to SD handle.
* fp_Data: pointer to the received dat buffer.
* fu32_BlockAddr: Block Start Address.
* fu16_BlockNum: Number of SD blocks to read.
*/
uint32_t SDCard_ReadBolcks_SDMA_IT(SD_HandleTypeDef *hsd, uint32_t *fp_Data, uint32_t fu32_BlockAddr, uint16_t fu16_BlockNum)
{
int i;
uint32_t lu32_ErrState = INT_NO_ERR;
if (hsd->CardStatus != CARD_STATUS_IDLE)
return E4_CARD_BUSY;
if (fu16_BlockNum == 0)
return E1_NUM_ERR;
/* SEND CMD23 SET_BLOCK_COUNT */
lu32_ErrState = SD_CMD_SetBlockCount(hsd->SDx, fu16_BlockNum);
if (lu32_ErrState)
return lu32_ErrState;
/* set SDMA system Address */
__SD_SET_SDMA_SYSTEM_ADDR(hsd->SDx, (uint32_t)fp_Data);
/* Set block count */
__SD_SET_BLOCK_COUNT(hsd->SDx, fu16_BlockNum);
/* Address alignment */
hsd->AddrAlign = (uint32_t)fp_Data & SDMA_ADDR_ALIGN_MASK;
/* Enable error/transfer complete/dma */
__SD_INT_ENABLE(hsd->SDx, INT_DMA_INT | INT_TRANSFER_COMPLETE | INT_ERR_MASK);
/* SEND CMD18 READ_MULTIPLE_BLOCK */
lu32_ErrState = SD_CMD_ReadBlock_SDMA(hsd->SDx, fu32_BlockAddr);
if (lu32_ErrState)
return lu32_ErrState;
else
hsd->CardStatus = CARD_STATUS_READ_BUSY;
return lu32_ErrState;
}
/************************************************************************************
* @fn SDCard_WriteBolcks_SDMA_IT
*
* @brief Write block(s) from a specified address in a card.
* The Data transfer by SDMA(Simple DMA) mode with interrupt.
*
* @param hsd: Pointer to SD handle.
* fp_Data: pointer to the received dat buffer.
* fu32_BlockAddr: Block Address.
* fu16_BlockNum: Number of SD blocks to write.
*/
uint32_t SDCard_WriteBolcks_SDMA_IT(SD_HandleTypeDef *hsd, uint32_t *fp_Data, uint32_t fu32_BlockAddr, uint16_t fu16_BlockNum)
{
int i;
uint32_t lu32_ErrState = INT_NO_ERR;
if (hsd->CardStatus != CARD_STATUS_IDLE)
return E4_CARD_BUSY;
if (fu16_BlockNum == 0)
return E1_NUM_ERR;
/* SEND CMD23 SET_BLOCK_COUNT */
lu32_ErrState = SD_CMD_SetBlockCount(hsd->SDx, fu16_BlockNum);
if (lu32_ErrState)
return lu32_ErrState;
/* set SDMA system Address */
__SD_SET_SDMA_SYSTEM_ADDR(hsd->SDx, (uint32_t)fp_Data);
/* Set block count */
__SD_SET_BLOCK_COUNT(hsd->SDx, fu16_BlockNum);
/* Address alignment */
hsd->AddrAlign = (uint32_t)fp_Data & SDMA_ADDR_ALIGN_MASK;
/* Enable error/transfer complete/dma */
__SD_INT_ENABLE(hsd->SDx, INT_DMA_INT | INT_TRANSFER_COMPLETE | INT_ERR_MASK);
/* SEND CMD25 WRITE_MULTIPLE_BLOCK */
lu32_ErrState = SD_CMD_WriteBlock_SDMA(hsd->SDx, fu32_BlockAddr);
if (lu32_ErrState)
return lu32_ErrState;
else
hsd->CardStatus = CARD_STATUS_WIRTE_BUSY;
return lu32_ErrState;
}
/************************************************************************************
* @fn SDCard_Erase
*
* @brief Write block(s) from a specified address in a card.
* The Data transfer by polling mode.
*
* @param hsd: Pointer to SD handle.
* BlockStartAdd: Start Block address
* BlockEndAdd: End Block address
*/
uint32_t SDCard_Erase(SD_HandleTypeDef *hsd, uint32_t BlockStartAddr, uint32_t BlockEndAddr)
{
uint32_t lu32_ErrState = INT_NO_ERR;
/* CMD32: ERASE_WR_BLK_START */
lu32_ErrState = SD_CMD_EraseStartAddr(hsd->SDx, BlockStartAddr);
if (lu32_ErrState)
{
return lu32_ErrState;
}
/* CMD33: ERASE_WR_BLK_END */
lu32_ErrState = SD_CMD_EraseEndAddr(hsd->SDx, BlockEndAddr);
if (lu32_ErrState)
{
return lu32_ErrState;
}
/* CMD38: ERASE */
lu32_ErrState = SD_CMD_Erase(hsd->SDx);
if (lu32_ErrState)
{
return lu32_ErrState;
}
return lu32_ErrState;
}
/************************************************************************************
* @fn SDCard_Get_Block_count
*
* @brief Get block counter of mounted SD Card.
*
* @param hsd: Pointer to SD handle.
*
* @return Block count.
*/
uint32_t SDCard_Get_Block_count(SD_HandleTypeDef *hsd)
{
if (hsd) {
return hsd->CardInfo.MemoryCapacity / 512;
}
else {
return 0;
}
}
/************************************************************************************
* @fn SDCard_GetCardCSD
*
* @brief Get the card information from the CSD register.
*/
static void __SDCard_GetCardCSD(SD_HandleTypeDef *hsd)
{
hsd->CSDInfo = (SD_CardCSDTypeDef *)hsd->CSD;
/* Card memory capacity, unit KByte */
hsd->CardInfo.MemoryCapacity = (hsd->CSDInfo->C_SIZE + 1) * 512;
/* Card command class */
hsd->CardInfo.Class = hsd->CSDInfo->CCC;
}
/************************************************************************************
* @fn SDCard_GetCardCID
*
* @brief Get the card information from the CID register.
*/
static void __SDCard_GetCardCID(SD_HandleTypeDef *hsd)
{
hsd->CIDInfo = (SD_CardCIDTypeDef *)hsd->CID;
}
/************************************************************************************
* @fn SD_PowerON
*
* @brief Enquires cards about their operating voltage and configures clock ontrols.
*/
static uint32_t __SDCard_PowerON(SD_HandleTypeDef *hsd)
{
uint32_t lu32_ErrState = INT_NO_ERR;
uint32_t lu32_Response;
bool lb_BusyStatus = false;
/* CMD0: GO_IDLE_STATE */
lu32_ErrState = SD_CMD_GoIdleState(hsd->SDx);
if (lu32_ErrState)
{
return lu32_ErrState;
}
/* CMD8: SEND_IF_COND: Command available only on V2.0 cards */
lu32_ErrState = SD_CMD_SendInterfaceCondition(hsd->SDx);
if (lu32_ErrState)
{
hsd->CardInfo.CardVersion = CARD_VER_1_X;
return lu32_ErrState;
}
else
{
hsd->CardInfo.CardVersion = CARD_VER_2_X;
/* signaling 3.3V */
if (hsd->Init.SpeedMode & SIGNALING_3_3V_MASK)
{
while (lb_BusyStatus == false)
{
/* Send CMD55 APP_CMD with RCA as 0 */
lu32_ErrState = SD_CMD_AppCommand(hsd->SDx, 0);
if (lu32_ErrState)
{
return lu32_ErrState;
}
/* Send ACMD41 SD_SEND_OP_COND */
lu32_ErrState = SD_ACMD_SendOperCondition(hsd->SDx, ACMD41_ARG_HCS|ACMD41_ARG_VOLTAGE_WINDOW_32_33, &hsd->OCR);
if (lu32_ErrState)
{
return lu32_ErrState;
}
lb_BusyStatus = hsd->OCR & OCR_BUSY ? true : false;
}
if (hsd->OCR & OCR_CCS)
{
hsd->CardInfo.CardType = CARD_TYPE_SDHC_SDXC;
}
else
{
hsd->CardInfo.CardType = CARD_TYPE_SDSC;
}
}
/* signaling 1.8V */
else
{
while (lb_BusyStatus == false)
{
/* SEND CMD55 APP_CMD with RCA as 0 */
lu32_ErrState = SD_CMD_AppCommand(hsd->SDx, 0);
if (lu32_ErrState)
{
return lu32_ErrState;
}
/* Send ACMD41 SD_SEND_OP_COND */
lu32_ErrState = SD_ACMD_SendOperCondition(hsd->SDx, ACMD41_ARG_HCS|ACMD41_ARG_S18R|ACMD41_ARG_VOLTAGE_WINDOW_32_33, &hsd->OCR);
if (lu32_ErrState)
{
return lu32_ErrState;
}
lb_BusyStatus = hsd->OCR & OCR_BUSY ? true : false;
}
/* Card Capacity Status */
if (hsd->OCR & OCR_CCS)
{
hsd->CardInfo.CardType = CARD_TYPE_SDHC_SDXC;
}
else
{
hsd->CardInfo.CardType = CARD_TYPE_SDSC;
}
/* switching to 1.8V Accepted */
if (hsd->OCR & OCR_S18A)
{
/* SEND CMD11 VOLTAGE_SWITCH */
lu32_ErrState = SD_CMD_VoltageSwitch(hsd->SDx);
if (lu32_ErrState == INT_NO_ERR)
{
/* Data line is in use */
while(!(__SD_GET_PRESENT_STATE(hsd->SDx) & PreState_DAT0_SIGNAL_MASK));
/* Host switch 1.8V */
__SD_1_8V_ENABLE(hsd->SDx, 1);
/* Host default select SDR12 */
__SD_SDCLK_DISABLE(hsd->SDx);
__SD_UHS_MODE(hsd->SDx, 0);
__SD_SDCLK_ENABLE(hsd->SDx);
/* Wait to Card ready */
uint32_t lu32_Timeout = 100;
while (lu32_Timeout--)
{
if (!SD_CMD_SendStatus(hsd->SDx, hsd->RCA, &lu32_Response))
{
break;
}
}
}
}
else
{
lu32_ErrState = E2_1_8V_ERR;
}
}
}
return lu32_ErrState;
}
/************************************************************************************
* @fn __SDCard_InitCard
*
* @brief Initializes the sd card.
*/
static uint32_t __SDCard_InitCard(SD_HandleTypeDef *hsd)
{
uint32_t lu32_ErrState = INT_NO_ERR;
uint32_t lu32_Response;
uint32_t CMD6_Data[16];
/* CMD2: ALL_SEND_CID */
lu32_ErrState = SD_CMD_AllSendCID(hsd->SDx, hsd->CID);
if (lu32_ErrState)
{
return lu32_ErrState;
}
/* CMD3: SEND_RELATIVE_ADDR */
lu32_ErrState = SD_CMD_SendRelAddr(hsd->SDx, &hsd->RCA);
if (lu32_ErrState)
{
return lu32_ErrState;
}
/* CMD9: SEND_CSD */
lu32_ErrState = SD_CMD_SendCSD(hsd->SDx, hsd->RCA, hsd->CSD);
if (lu32_ErrState)
{
return lu32_ErrState;
}
/* CMD7: SEL_DESEL_CARD */
lu32_ErrState = SD_CMD_SelectCard(hsd->SDx, hsd->RCA);
if (lu32_ErrState)
{
return lu32_ErrState;
}
/* Wait to enter transfer state */
uint32_t lu32_Timeout = 100;
while (lu32_Timeout--)
{
/* CMD13: SEND_STATUS */
lu32_ErrState = SD_CMD_SendStatus(hsd->SDx, hsd->RCA, &lu32_Response);
if (lu32_ErrState)
{
return lu32_ErrState;
}
if (lu32_Response & CARD_CURRENT_STATE_TRAN)
break;
}
/* Switch card function */
if (hsd->Init.SpeedMode != SPEED_DS)
{
/* CMD6: SWITCH_FUNC */
lu32_ErrState = SD_CMD_SwitchFunc(hsd->SDx, 0x80FFFFF0 | hsd->Init.SpeedMode);
if (lu32_ErrState)
{
return lu32_ErrState;
}
if (lu32_ErrState == INT_NO_ERR)
{
/* Wait for Buffer Read Ready Int */
while(!(__SD_GET_INT_STATUS(hsd->SDx) & INT_BUFFER_READ_READY));
/* Clear Buffer_Read_Ready */
__SD_CLR_INT_STATUS(hsd->SDx, INT_BUFFER_READ_READY);
/* Read one block */
for (int i = 0; i < 16; i++)
{
CMD6_Data[i] = __SD_GET_BUFFERDATA(hsd->SDx);
}
/* wait for transfer complete or any errors occur */
while(!(__SD_GET_INT_STATUS(hsd->SDx) & (INT_TRANSFER_COMPLETE | INT_ERR_MASK)));
/* Any errors occur */
if (__SD_GET_INT_STATUS(hsd->SDx) & INT_ERR_MASK)
{
return (__SD_GET_INT_STATUS(hsd->SDx) & INT_ERR_MASK);
}
/* clear interrupt status */
__SD_CLR_ALL_INT_STATUS(hsd->SDx);
/* Check Card */
/* Card Not support selected Speed */
if ((CMD6_Data[4] & 0xF) == 0xF)
{
lu32_ErrState = E3_SPEED_ERR;
return lu32_ErrState;
}
/* Update Speed mode */
else
{
if (hsd->Init.SpeedMode == SPEED_HS)
{
/* HIGH Speed mode */
__SD_SPEED_MODE(hsd->SDx, 1);
}
else
{
/* SDR25/SDR50/SDR104/DDR50 */
__SD_SDCLK_DISABLE(hsd->SDx);
__SD_UHS_MODE(hsd->SDx, (hsd->Init.SpeedMode & 0xF));
__SD_SDCLK_ENABLE(hsd->SDx);
}
}
}
}
/* Update bus clock speed */
__SD_CLOCK_DIV_LOW_8BIT(hsd->SDx, (hsd->Init.ClockDiv / 2));
/* Fixed Block Size 512 Byte */
__SD_SET_BLOCK_SIZE(hsd->SDx, 512);
return lu32_ErrState;
}

View File

@ -0,0 +1,613 @@
/*
******************************************************************************
* @file driver_sd_mmc.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2022
* @brief Multi-Media card application HAL module driver.
******************************************************************************
* @attention
*
* Copyright (c) 2022 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
/* Private function prototypes -----------------------------------------------*/
static uint32_t __eMMC_PowerON(MMC_HandleTypeDef *hmmc);
static uint32_t __eMMC_InitCard(MMC_HandleTypeDef *hmmc);
static void __MMCCard_GetCardCSD(MMC_HandleTypeDef *hmmc);
static void __MMCCard_GetCardCID(MMC_HandleTypeDef *hmmc);
/************************************************************************************
* @fn eMMC_Init
*
* @brief Initializes the Embedded Multi Media Card.
*
* @param hmmc: Pointer to MMC handle
*/
uint32_t eMMC_Init(MMC_HandleTypeDef *hmmc)
{
uint32_t lu32_ErrState = INT_NO_ERR;
/* eMMC class initialization */
SD_SDMMCClass_Init(hmmc->SDx);
/* Identify card operating voltage */
lu32_ErrState = __eMMC_PowerON(hmmc);
if (lu32_ErrState)
{
return lu32_ErrState;
}
/* Card initialization */
lu32_ErrState = __eMMC_InitCard(hmmc);
if (lu32_ErrState)
{
return lu32_ErrState;
}
/* Get the card information from the CID register */
__MMCCard_GetCardCID(hmmc);
/* Get the card information from the CSD register */
__MMCCard_GetCardCSD(hmmc);
return lu32_ErrState;
}
/************************************************************************************
* @fn eMMC_BusWidth_Select
*
* @brief SDCard 1bit/4bit/8bit bus width select.
*
* @param hmmc: Pointer to MMC handle.
* fu32_BusWidth: bus width. can select MMC_BUS_WIDTH_1BIT.
* MMC_BUS_WIDTH_4BIT.
* MMC_BUS_WIDTH_8BIT.
*/
uint32_t eMMC_BusWidth_Select(MMC_HandleTypeDef *hmmc, uint32_t fu32_BusWidth)
{
uint32_t lu32_ErrState = INT_NO_ERR;
uint32_t fu32_Argument;
/* Access */
fu32_Argument = MMC_CMD6_ACCESS_WRITE_BYTE;
/* Index */
fu32_Argument |= MMC_EX_CSD_INDEX_BUS_WIDTH << 16;
/* Value */
fu32_Argument |= fu32_BusWidth << 8;
/* Send CMD6 SWITCH */
lu32_ErrState = MMC_CMD_Switch(hmmc->SDx, fu32_Argument);
if (lu32_ErrState)
{
return lu32_ErrState;
}
else
{
/* Data line is in use */
while(__SD_GET_PRESENT_STATE(hmmc->SDx) & PreState_DAT_LINE_MASK);
/* Host set bus width */
if (fu32_BusWidth == MMC_BUS_WIDTH_8BIT)
{
/* Enable Bus width 8bit */
__SD_8BIT_WIDTH_ENABLE(hmmc->SDx);
}
else
{
/* Disable Bus width 8bit */
__SD_8BIT_WIDTH_DISABLE(hmmc->SDx);
if (fu32_BusWidth == MMC_BUS_WIDTH_4BIT)
__SD_DATA_WIDTH_4BIT(hmmc->SDx);
else
__SD_DATA_WIDTH_1BIT(hmmc->SDx);
}
}
return lu32_ErrState;
}
/************************************************************************************
* @fn eMMC_ReadBolcks
*
* @brief Reads block(s) from a specified address in a eMMC.
* The Data transfer by polling mode.
*
* @param hsd: Pointer to SD handle.
* fp_Data: pointer to the received dat buffer.
* fu32_BlockAddr: Block Start Address.
* fu16_BlockNum: Number of SD blocks to read.
*/
uint32_t eMMC_ReadBolcks(MMC_HandleTypeDef *hmmc, uint32_t *fp_Data, uint32_t fu32_BlockAddr, uint16_t fu16_BlockNum)
{
int i;
uint32_t lu32_ErrState = INT_NO_ERR;
if (fu16_BlockNum == 0)
return E1_NUM_ERR;
if (fu16_BlockNum == 1)
{
/* SEND CMD17 READ_SINGLI_BLOCK */
lu32_ErrState = MMC_CMD_ReadSingleBlock(hmmc->SDx, fu32_BlockAddr);
if (lu32_ErrState)
return lu32_ErrState;
/* Wait for Buffer Read Ready Int */
while(!(__SD_GET_INT_STATUS(hmmc->SDx) & INT_BUFFER_READ_READY));
/* Clear Buffer_Read_Ready */
__SD_CLR_INT_STATUS(hmmc->SDx, INT_BUFFER_READ_READY);
/* Read one block */
for (i = 0; i < BLOCKSIZE / 4; i++)
{
*fp_Data++ = __SD_GET_BUFFERDATA(hmmc->SDx);
}
}
else
{
/* SEND CMD23 SET_BLOCK_COUNT */
lu32_ErrState = MMC_CMD_SetBlockCount(hmmc->SDx, fu16_BlockNum);
if (lu32_ErrState)
return lu32_ErrState;
/* Set block count */
__SD_SET_BLOCK_COUNT(hmmc->SDx, fu16_BlockNum);
/* SEND CMD18 READ_MULTIPLE_BLOCK */
lu32_ErrState = MMC_CMD_ReadMultiBlock(hmmc->SDx, fu32_BlockAddr);
if (lu32_ErrState)
return lu32_ErrState;
while (fu16_BlockNum--)
{
/* Wait for Buffer_Read_Ready */
while(!(__SD_GET_INT_STATUS(hmmc->SDx) & INT_BUFFER_READ_READY));
/* Clear Buffer_Read_Ready */
__SD_CLR_INT_STATUS(hmmc->SDx, INT_BUFFER_READ_READY);
/* Read one block */
for (i = 0; i < BLOCKSIZE / 4; i++)
{
*fp_Data++ = __SD_GET_BUFFERDATA(hmmc->SDx);
}
}
}
/* wait for transfer complete or any errors occur */
while(!(__SD_GET_INT_STATUS(hmmc->SDx) & (INT_TRANSFER_COMPLETE | INT_ERR_MASK)));
/* Any errors occur */
if (__SD_GET_INT_STATUS(hmmc->SDx) & INT_ERR_MASK)
{
lu32_ErrState = __SD_GET_INT_STATUS(hmmc->SDx) & INT_ERR_MASK;
}
/* clear interrupt status */
__SD_CLR_ALL_INT_STATUS(hmmc->SDx);
return lu32_ErrState;
}
/************************************************************************************
* @fn eMMC_WriteBolcks
*
* @brief Write block(s) from a specified address in a eMMC.
* The Data transfer by polling mode.
*
* @param hsd: Pointer to SD handle.
* fp_Data: pointer to the received dat buffer.
* fu32_BlockAddr: Block Start Address.
* fu16_BlockNum: Number of SD blocks to write.
*/
uint32_t eMMC_WriteBolcks(MMC_HandleTypeDef *hmmc, uint32_t *fp_Data, uint32_t fu32_BlockAddr, uint16_t fu16_BlockNum)
{
int i;
uint32_t lu32_ErrState = INT_NO_ERR;
if (fu16_BlockNum == 0)
return E1_NUM_ERR;
if (fu16_BlockNum == 1)
{
/* SEND CMD24 WRITE_BLOCK */
lu32_ErrState = MMC_CMD_WriteSingleBlock(hmmc->SDx, fu32_BlockAddr);
if (lu32_ErrState)
return lu32_ErrState;
/* Wait for buffer write enable Int */
while(!(__SD_GET_PRESENT_STATE(hmmc->SDx) & PreState_BUFFER_WRITE_EN_MASK));
/* write one block */
for (i = 0; i < BLOCKSIZE / 4; i++)
{
__SD_SET_BUFFERDATA(hmmc->SDx, *fp_Data++);
}
}
else
{
/* SEND CMD23 SET_BLOCK_COUNT */
lu32_ErrState = MMC_CMD_SetBlockCount(hmmc->SDx, fu16_BlockNum);
if (lu32_ErrState)
return lu32_ErrState;
/* Set block count */
__SD_SET_BLOCK_COUNT(hmmc->SDx, fu16_BlockNum);
/* SEND CMD25 WRITE_MULTIPLE_BLOCK */
lu32_ErrState = MMC_CMD_WriteMultiBlock(hmmc->SDx, fu32_BlockAddr);
if (lu32_ErrState)
return lu32_ErrState;
/* First block transfer check the PresentState register */
/* Wait for Buffer_Write_Enable */
while(!(__SD_GET_PRESENT_STATE(hmmc->SDx) & PreState_BUFFER_WRITE_EN_MASK));
/* write one block */
for (i = 0; i < BLOCKSIZE / 4; i++)
{
__SD_SET_BUFFERDATA(hmmc->SDx, *fp_Data++);
}
fu16_BlockNum--;
/* Other block transfer check the StatusInt register */
while(fu16_BlockNum--)
{
/* Wait for Buffer_Write_Ready */
while(!(__SD_GET_INT_STATUS(hmmc->SDx) & INT_BUFFER_WRITE_READY));
/* Clear Buffer_Write_Ready */
__SD_CLR_INT_STATUS(hmmc->SDx, INT_BUFFER_WRITE_READY);
/* write one block */
for (i = 0; i < BLOCKSIZE / 4; i++)
{
__SD_SET_BUFFERDATA(hmmc->SDx, *fp_Data++);
}
}
}
/* wait for transfer complete or any errors occur */
while(!(__SD_GET_INT_STATUS(hmmc->SDx) & (INT_TRANSFER_COMPLETE | INT_ERR_MASK)));
/* Any errors occur */
if (__SD_GET_INT_STATUS(hmmc->SDx) & INT_ERR_MASK)
{
lu32_ErrState = __SD_GET_INT_STATUS(hmmc->SDx) & INT_ERR_MASK;
}
/* clear interrupt status */
__SD_CLR_ALL_INT_STATUS(hmmc->SDx);
return lu32_ErrState;
}
/************************************************************************************
* @fn eMMC_ReadBolcks_SDMA
*
* @brief Reads block(s) from a specified address in a eMMC.
* The Data transfer by SDMA(Simple DMA) mode.
*
* @param hsd: Pointer to SD handle.
* fp_Data: pointer to the received dat buffer.
* fu32_BlockAddr: Block Start Address.
* fu16_BlockNum: Number of SD blocks to read.
*/
uint32_t eMMC_ReadBolcks_SDMA(MMC_HandleTypeDef *hmmc, uint32_t *fp_Data, uint32_t fu32_BlockAddr, uint16_t fu16_BlockNum)
{
int i;
uint32_t lu32_ErrState = INT_NO_ERR;
bool lb_TrfComplete = true;
uint32_t lu32_Addr = (uint32_t)fp_Data;
if (fu16_BlockNum == 0)
return E1_NUM_ERR;
/* SEND CMD23 SET_BLOCK_COUNT */
lu32_ErrState = MMC_CMD_SetBlockCount(hmmc->SDx, fu16_BlockNum);
if (lu32_ErrState)
return lu32_ErrState;
/* set SDMA system Address */
__SD_SET_SDMA_SYSTEM_ADDR(hmmc->SDx, (uint32_t)fp_Data);
/* Set block count */
__SD_SET_BLOCK_COUNT(hmmc->SDx, fu16_BlockNum);
/* SEND CMD18 READ_MULTIPLE_BLOCK */
lu32_ErrState = MMC_CMD_ReadBlock_SDMA(hmmc->SDx, fu32_BlockAddr);
if (lu32_ErrState)
return lu32_ErrState;
/* Address alignment */
lu32_Addr &= SDMA_ADDR_ALIGN_MASK;
/* wait for transfer complete or any errors occur */
while (lb_TrfComplete)
{
if (__SD_GET_INT_STATUS(hmmc->SDx) & (INT_TRANSFER_COMPLETE | INT_ERR_MASK))
{
lb_TrfComplete = false;
}
if (__SD_GET_INT_STATUS(hmmc->SDx) & INT_DMA_INT)
{
__SD_CLR_INT_STATUS(hmmc->SDx, INT_DMA_INT);
/* SDMA system Address alignment increases */
lu32_Addr += SDMA_ADDR_UNIT;
/* Update SDMA system Address */
__SD_SET_SDMA_SYSTEM_ADDR(hmmc->SDx, (uint32_t)lu32_Addr);
}
}
/* Any errors occur */
if (__SD_GET_INT_STATUS(hmmc->SDx) & INT_ERR_MASK)
{
lu32_ErrState = __SD_GET_INT_STATUS(hmmc->SDx) & INT_ERR_MASK;
}
/* clear interrupt status */
__SD_CLR_ALL_INT_STATUS(hmmc->SDx);
return lu32_ErrState;
}
/************************************************************************************
* @fn eMMC_WriteBolcks_SDMA
*
* @brief Write block(s) from a specified address in a eMMC.
* The Data transfer by SDMA(Simple DMA) mode.
*
* @param hsd: Pointer to SD handle.
* fp_Data: pointer to the received dat buffer.
* fu32_BlockAddr: Block Start Address.
* fu16_BlockNum: Number of SD blocks to write.
*/
uint32_t eMMC_WriteBolcks_SDMA(MMC_HandleTypeDef *hmmc, uint32_t *fp_Data, uint32_t fu32_BlockAddr, uint16_t fu16_BlockNum)
{
int i;
uint32_t lu32_ErrState = INT_NO_ERR;
bool lb_TrfComplete = true;
uint32_t lu32_Addr = (uint32_t)fp_Data;
if (fu16_BlockNum == 0)
return E1_NUM_ERR;
/* SEND CMD23 SET_BLOCK_COUNT */
lu32_ErrState = MMC_CMD_SetBlockCount(hmmc->SDx, fu16_BlockNum);
if (lu32_ErrState)
return lu32_ErrState;
/* set SDMA system Address */
__SD_SET_SDMA_SYSTEM_ADDR(hmmc->SDx, (uint32_t)fp_Data);
/* Set block count */
__SD_SET_BLOCK_COUNT(hmmc->SDx, fu16_BlockNum);
/* SEND CMD25 WRITE_MULTIPLE_BLOCK */
lu32_ErrState = MMC_CMD_WriteBlock_SDMA(hmmc->SDx, fu32_BlockAddr);
if (lu32_ErrState)
return lu32_ErrState;
/* Address alignment */
lu32_Addr &= SDMA_ADDR_ALIGN_MASK;
/* wait for transfer complete or any errors occur */
while (lb_TrfComplete)
{
if (__SD_GET_INT_STATUS(hmmc->SDx) & (INT_TRANSFER_COMPLETE | INT_ERR_MASK))
{
lb_TrfComplete = false;
}
if (__SD_GET_INT_STATUS(hmmc->SDx) & INT_DMA_INT)
{
__SD_CLR_INT_STATUS(hmmc->SDx, INT_DMA_INT);
/* SDMA system Address alignment increases */
lu32_Addr += SDMA_ADDR_UNIT;
/* Update SDMA system Address */
__SD_SET_SDMA_SYSTEM_ADDR(hmmc->SDx, (uint32_t)lu32_Addr);
}
}
/* Any errors occur */
if (__SD_GET_INT_STATUS(hmmc->SDx) & INT_ERR_MASK)
{
lu32_ErrState = __SD_GET_INT_STATUS(hmmc->SDx) & INT_ERR_MASK;
}
/* clear interrupt status */
__SD_CLR_ALL_INT_STATUS(hmmc->SDx);
return lu32_ErrState;
}
/************************************************************************************
* @fn MMCCard_GetCardCSD
*
* @brief Get the card information from the CSD register.
*/
static void __MMCCard_GetCardCSD(MMC_HandleTypeDef *hmmc)
{
hmmc->CSDInfo = (MMC_CardCSDTypeDef *)hmmc->CSD;
/* Card memory capacity, unit KByte */
hmmc->CardInfo.MemoryCapacity = hmmc->ExCSDInfo.SEC_COUNT / 2;
/* Card command class */
hmmc->CardInfo.Class = hmmc->CSDInfo->CCC;
}
/************************************************************************************
* @fn __MMCCard_GetCardCID
*
* @brief Get the card information from the CID register.
*/
static void __MMCCard_GetCardCID(MMC_HandleTypeDef *hmmc)
{
hmmc->CIDInfo = (MMC_CardCIDTypeDef *)hmmc->CID;
}
/************************************************************************************
* @fn __eMMC_PowerON
*
* @brief Enquires cards about their operating voltage and configures clock ontrols.
*/
static uint32_t __eMMC_PowerON(MMC_HandleTypeDef *hmmc)
{
uint32_t lu32_ErrState = INT_NO_ERR;
bool lb_BusyStatus = false;
/* CMD0: GO_IDLE_STATE */
lu32_ErrState = MMC_CMD_GoIdleState(hmmc->SDx);
if(lu32_ErrState)
{
return lu32_ErrState;
}
while (lb_BusyStatus == false)
{
/* SEND CMD1 SEND_OP_COND with eMMC_DUAL_VOLTAGE_RANGE(0xC0FF8080U) as argument */
lu32_ErrState = MMC_CMD_SendOperCondition(hmmc->SDx, eMMC_DUAL_VOLTAGE_RANGE, &hmmc->OCR);
if(lu32_ErrState)
{
return lu32_ErrState;
}
lb_BusyStatus = hmmc->OCR & OCR_BUSY ? true : false;
}
hmmc->CardInfo.CardType = 0;
/* After power routine and command returns valid voltage */
if (hmmc->OCR & eMMC_DUAL_VOLTAGE_CARD)
{
/* Voltage range of the card is within 1.70V ~ 1.95V or 2.7V ~ 3.6V */
hmmc->CardInfo.CardType = eMMC_DUAL_VOLTAGE_CARD;
}
if (hmmc->OCR & eMMC_CAPACITY_HIGHER_2G)
{
/* Capacity > 2G, sector mode */
hmmc->CardInfo.CardType |= eMMC_CAPACITY_HIGHER_2G;
}
return lu32_ErrState;
}
/************************************************************************************
* @fn __eMMC_InitCard
*
* @brief Initializes the sd card.
*/
static uint32_t __eMMC_InitCard(MMC_HandleTypeDef *hmmc)
{
uint32_t lu32_ErrState = INT_NO_ERR;
uint32_t lu32_Response, lu32_TempValue;
/* CMD2: ALL_SEND_CID */
lu32_ErrState = MMC_CMD_AllSendCID(hmmc->SDx, hmmc->CID);
if (lu32_ErrState)
{
return lu32_ErrState;
}
/* CMD3: SET_RELATIVE_ADDR */
hmmc->RCA = 0xF1170000;
lu32_ErrState = MMC_CMD_SetRelAddr(hmmc->SDx, hmmc->RCA);
if (lu32_ErrState)
{
return lu32_ErrState;
}
/* After CMD3, Bus select push-pull mode */
__SD_MMC_OD_PP(hmmc->SDx, 1);
/* CMD9: SEND_CSD */
lu32_ErrState = MMC_CMD_SendCSD(hmmc->SDx, hmmc->RCA, hmmc->CSD);
if (lu32_ErrState)
{
return lu32_ErrState;
}
/* CMD7: SEL_DESEL_CARD */
lu32_ErrState = MMC_CMD_SelectCard(hmmc->SDx, hmmc->RCA);
if (lu32_ErrState)
{
return lu32_ErrState;
}
/* Wait to enter transfer state */
uint32_t lu32_Timeout = 100;
while (lu32_Timeout--)
{
/* CMD13: SEND_STATUS */
lu32_ErrState = SD_CMD_SendStatus(hmmc->SDx, hmmc->RCA, &lu32_Response);
if (lu32_ErrState)
{
return lu32_ErrState;
}
if (lu32_Response & CARD_CURRENT_STATE_TRAN)
break;
}
/* CMD8: SEND_EXT_CSD */
lu32_ErrState = MMC_CMD_SendExtendedCSD(hmmc->SDx);
if (lu32_ErrState)
{
return lu32_ErrState;
}
/* Wait for Buffer Read Ready Int */
while(!(__SD_GET_INT_STATUS(hmmc->SDx) & INT_BUFFER_READ_READY));
/* Clear Buffer_Read_Ready */
__SD_CLR_INT_STATUS(hmmc->SDx, INT_BUFFER_READ_READY);
/* Read one block */
for (int i = 0; i < BLOCKSIZE / 4; i++)
{
lu32_TempValue = __SD_GET_BUFFERDATA(hmmc->SDx);
/* Extract Parameter */
switch (i)
{
case MMC_EX_CSD_INDEX_SEC_COUNT0 / 4:
{ /* Byte 212,213,214,215 */
hmmc->ExCSDInfo.SEC_COUNT = lu32_TempValue;
}break;
case MMC_EX_CSD_INDEX_BUS_WIDTH / 4:
{ /* Byte 183 */
hmmc->ExCSDInfo.BUS_WIDTH = lu32_TempValue >> 24 & 0xFF;
}break;
case MMC_EX_CSD_INDEX_HS_TIMING / 4:
{ /* Byte 185 */
hmmc->ExCSDInfo.HS_TIMING = lu32_TempValue >> 8 & 0xFF;
}break;
case MMC_EX_CSD_INDEX_EXT_CSD_REV / 4:
{ /* Byte 192 */
hmmc->ExCSDInfo.EXT_CSD_REV = lu32_TempValue & 0xFF;
}break;
case MMC_EX_CSD_INDEX_DEVICE_TYPE / 4:
{ /* Byte 196 */
hmmc->ExCSDInfo.DEVICE_TYPE = lu32_TempValue & 0xFF;
}break;
default: break;
}
}
/* wait for transfer complete or any errors occur */
while(!(__SD_GET_INT_STATUS(hmmc->SDx) & (INT_TRANSFER_COMPLETE | INT_ERR_MASK)));
/* Any errors occur */
if (__SD_GET_INT_STATUS(hmmc->SDx) & INT_ERR_MASK)
{
lu32_ErrState = __SD_GET_INT_STATUS(hmmc->SDx) & INT_ERR_MASK;
}
/* clear interrupt status */
__SD_CLR_ALL_INT_STATUS(hmmc->SDx);
/* Update bus clock speed */
__SD_CLOCK_DIV_LOW_8BIT(hmmc->SDx, (hmmc->Init.ClockDiv / 2));
return lu32_ErrState;
}

View File

@ -0,0 +1,323 @@
/*
******************************************************************************
* @file driver_sha.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2022
* @brief IIR module driver.
* This file provides firmware functions to manage the
* SEC SHA peripheral
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
static uint8_t Context[128]; /* orignal data save buffer */
static uint16_t ContextIndex = 0;
static uint64_t TotalBits512[2];
static uint64_t TotalBits256;
/*********************************************************************
* @fn sha_init
*
* @brief SHA256 initialization procedure
*
* @param mode : SHA mode select
*/
void sha_init(enum_sha_mode_t fe_Mode)
{
SEC_SHA->SHA_CTRL.Bits.MODE = fe_Mode;
SEC_SHA->SHA_CTRL.Bits.ENDIAN_MODE = SHA_BIG_ENDIAN;
SEC_SHA->SHA_CTRL.Bits.ISR_EN = 1;
SEC_SHA->SHA_CTRL.Bits.INIT_EN = 1;
/*verity initialize*/
TotalBits256 = 0;
TotalBits512[0] = 0;
TotalBits512[1] = 0;
ContextIndex = 0;
}
static void __sha_updata_256(uint8_t *fp8_Data, uint32_t fu32_Size);
static void __sha_updata_512(uint8_t *fp8_Data, uint32_t fu32_Size);
/*********************************************************************
* @fn sha_update
*
* @brief SHA update procedure.
*
* @param fp8_Data : message to hash.
* @param fu32_Size: length of message to hash.
*/
void sha_update(uint8_t *fp8_Data, uint32_t fu32_Size)
{
if(SEC_SHA->SHA_CTRL.Bits.MODE >= SHA_512)
{
__sha_updata_512(fp8_Data, fu32_Size);
}
else
{
__sha_updata_256(fp8_Data, fu32_Size);
}
}
/*********************************************************************
* @fn sha_final
*
* @brief SHA Final calculation result
*
* @param DataOut : SHA calculation result buffer.
*/
void sha_final(uint8_t *DataOut)
{
uint32_t *DataIn = NULL;
/*sha512 or sha384 or sha512/256 or sha512/224*/
if(SEC_SHA->SHA_CTRL.Bits.MODE >= SHA_512)
{
if((TotalBits512[0] == 0) && (TotalBits512[1] == 0)) return;
uint32_t LeftBits = (ContextIndex << 3);
if(LeftBits == 0)
{
Context[0] = 0x80;
memset(&Context[1], 0, (SHA_512_BLOCK_SIZE - 1 - 16));
Context[SHA_512_BLOCK_SIZE - 1] = (uint8_t) TotalBits512[0];
Context[SHA_512_BLOCK_SIZE - 2] = (uint8_t) (TotalBits512[0] >> 8);
Context[SHA_512_BLOCK_SIZE - 3] = (uint8_t) (TotalBits512[0] >> 16);
Context[SHA_512_BLOCK_SIZE - 4] = (uint8_t) (TotalBits512[0] >> 24);
Context[SHA_512_BLOCK_SIZE - 5] = (uint8_t) (TotalBits512[0] >> 32);
Context[SHA_512_BLOCK_SIZE - 6] = (uint8_t) (TotalBits512[0] >> 40);
Context[SHA_512_BLOCK_SIZE - 7] = (uint8_t) (TotalBits512[0] >> 48);
Context[SHA_512_BLOCK_SIZE - 8] = (uint8_t) (TotalBits512[0] >> 56);
Context[SHA_512_BLOCK_SIZE - 9] = (uint8_t) TotalBits512[1];
Context[SHA_512_BLOCK_SIZE - 10] = (uint8_t) (TotalBits512[1] >> 8);
Context[SHA_512_BLOCK_SIZE - 11] = (uint8_t) (TotalBits512[1] >> 16);
Context[SHA_512_BLOCK_SIZE - 12] = (uint8_t) (TotalBits512[1] >> 24);
Context[SHA_512_BLOCK_SIZE - 13] = (uint8_t) (TotalBits512[1] >> 32);
Context[SHA_512_BLOCK_SIZE - 14] = (uint8_t) (TotalBits512[1] >> 40);
Context[SHA_512_BLOCK_SIZE - 15] = (uint8_t) (TotalBits512[1] >> 48);
Context[SHA_512_BLOCK_SIZE - 16] = (uint8_t) (TotalBits512[1] >> 56);
}
else if(LeftBits >= 896)
{
Context[ContextIndex++] = 0x80;
memset(&Context[ContextIndex], 0, (SHA_512_BLOCK_SIZE - ContextIndex));
DataIn = (uint32_t *)Context;
for(uint32_t i=0; i<16;i++)
{
SEC_SHA->DATA_1[i] = DataIn[i];
SEC_SHA->DATA_2[i] = DataIn[i + 16];
}
SEC_SHA->SHA_CTRL.Bits.CALCULATE = 1;
while(SEC_SHA->SHA_INT_STATE.Bits.INT_DONE == 0);
SEC_SHA->SHA_INT_STATE.Bits.INT_DONE = 0;
/*one more need to process*/
memset(&Context[0], 0, (SHA_512_BLOCK_SIZE - 16));
Context[SHA_512_BLOCK_SIZE - 1] = (uint8_t) TotalBits512[0];
Context[SHA_512_BLOCK_SIZE - 2] = (uint8_t) (TotalBits512[0] >> 8);
Context[SHA_512_BLOCK_SIZE - 3] = (uint8_t) (TotalBits512[0] >> 16);
Context[SHA_512_BLOCK_SIZE - 4] = (uint8_t) (TotalBits512[0] >> 24);
Context[SHA_512_BLOCK_SIZE - 5] = (uint8_t) (TotalBits512[0] >> 32);
Context[SHA_512_BLOCK_SIZE - 6] = (uint8_t) (TotalBits512[0] >> 40);
Context[SHA_512_BLOCK_SIZE - 7] = (uint8_t) (TotalBits512[0] >> 48);
Context[SHA_512_BLOCK_SIZE - 8] = (uint8_t) (TotalBits512[0] >> 56);
Context[SHA_512_BLOCK_SIZE - 9] = (uint8_t) TotalBits512[1];
Context[SHA_512_BLOCK_SIZE - 10] = (uint8_t) (TotalBits512[1] >> 8);
Context[SHA_512_BLOCK_SIZE - 11] = (uint8_t) (TotalBits512[1] >> 16);
Context[SHA_512_BLOCK_SIZE - 12] = (uint8_t) (TotalBits512[1] >> 24);
Context[SHA_512_BLOCK_SIZE - 13] = (uint8_t) (TotalBits512[1] >> 32);
Context[SHA_512_BLOCK_SIZE - 14] = (uint8_t) (TotalBits512[1] >> 40);
Context[SHA_512_BLOCK_SIZE - 15] = (uint8_t) (TotalBits512[1] >> 48);
Context[SHA_512_BLOCK_SIZE - 16] = (uint8_t) (TotalBits512[1] >> 56);
}
else
{
Context[ContextIndex++] = 0x80;
memset(&Context[ContextIndex], 0, (SHA_512_BLOCK_SIZE - ContextIndex - 16));
Context[SHA_512_BLOCK_SIZE - 1] = (uint8_t) TotalBits512[0];
Context[SHA_512_BLOCK_SIZE - 2] = (uint8_t) (TotalBits512[0] >> 8);
Context[SHA_512_BLOCK_SIZE - 3] = (uint8_t) (TotalBits512[0] >> 16);
Context[SHA_512_BLOCK_SIZE - 4] = (uint8_t) (TotalBits512[0] >> 24);
Context[SHA_512_BLOCK_SIZE - 5] = (uint8_t) (TotalBits512[0] >> 32);
Context[SHA_512_BLOCK_SIZE - 6] = (uint8_t) (TotalBits512[0] >> 40);
Context[SHA_512_BLOCK_SIZE - 7] = (uint8_t) (TotalBits512[0] >> 48);
Context[SHA_512_BLOCK_SIZE - 8] = (uint8_t) (TotalBits512[0] >> 56);
Context[SHA_512_BLOCK_SIZE - 9] = (uint8_t) TotalBits512[1];
Context[SHA_512_BLOCK_SIZE - 10] = (uint8_t) (TotalBits512[1] >> 8);
Context[SHA_512_BLOCK_SIZE - 11] = (uint8_t) (TotalBits512[1] >> 16);
Context[SHA_512_BLOCK_SIZE - 12] = (uint8_t) (TotalBits512[1] >> 24);
Context[SHA_512_BLOCK_SIZE - 13] = (uint8_t) (TotalBits512[1] >> 32);
Context[SHA_512_BLOCK_SIZE - 14] = (uint8_t) (TotalBits512[1] >> 40);
Context[SHA_512_BLOCK_SIZE - 15] = (uint8_t) (TotalBits512[1] >> 48);
Context[SHA_512_BLOCK_SIZE - 16] = (uint8_t) (TotalBits512[1] >> 56);
}
DataIn = (uint32_t *)Context;
for(uint32_t i=0; i<16;i++)
{
SEC_SHA->DATA_1[i] = DataIn[i];
SEC_SHA->DATA_2[i] = DataIn[i + 16];
}
/*start to calculate the last package data*/
SEC_SHA->SHA_CTRL.Bits.CALCULATE = 1;
while(SEC_SHA->SHA_INT_STATE.Bits.INT_DONE == 0);
SEC_SHA->SHA_INT_STATE.Bits.INT_DONE = 0;
}
else /*sha256 or sha1 or sha224*/
{
if(TotalBits256 == 0) return;
uint32_t LeftBits = (ContextIndex << 3);
if(LeftBits == 0)
{
Context[0] = 0x80;
memset(&Context[1], 0, (SHA_256_BLOCK_SIZE - 1 - 8));
Context[SHA_256_BLOCK_SIZE - 1] = (uint8_t) TotalBits256;
Context[SHA_256_BLOCK_SIZE - 2] = (uint8_t) (TotalBits256 >> 8);
Context[SHA_256_BLOCK_SIZE - 3] = (uint8_t) (TotalBits256 >> 16);
Context[SHA_256_BLOCK_SIZE - 4] = (uint8_t) (TotalBits256 >> 24);
Context[SHA_256_BLOCK_SIZE - 5] = (uint8_t) (TotalBits256 >> 32);
Context[SHA_256_BLOCK_SIZE - 6] = (uint8_t) (TotalBits256 >> 40);
Context[SHA_256_BLOCK_SIZE - 7] = (uint8_t) (TotalBits256 >> 48);
Context[SHA_256_BLOCK_SIZE - 8] = (uint8_t) (TotalBits256 >> 56);
}
else if(LeftBits >= 448)
{
Context[ContextIndex++] = 0x80;
memset(&Context[ContextIndex], 0, (SHA_256_BLOCK_SIZE - ContextIndex));
DataIn = (uint32_t *)Context;
for(uint32_t i=0; i<16;i++)
{
SEC_SHA->DATA_1[i] = DataIn[i];
}
SEC_SHA->SHA_CTRL.Bits.CALCULATE = 1;
while(SEC_SHA->SHA_INT_STATE.Bits.INT_DONE == 0);
SEC_SHA->SHA_INT_STATE.Bits.INT_DONE = 0;
/*one more need to process*/
memset(&Context[0], 0, (SHA_256_BLOCK_SIZE - 8));
Context[SHA_256_BLOCK_SIZE - 1] = (uint8_t) TotalBits256;
Context[SHA_256_BLOCK_SIZE - 2] = (uint8_t) (TotalBits256 >> 8);
Context[SHA_256_BLOCK_SIZE - 3] = (uint8_t) (TotalBits256 >> 16);
Context[SHA_256_BLOCK_SIZE - 4] = (uint8_t) (TotalBits256 >> 24);
Context[SHA_256_BLOCK_SIZE - 5] = (uint8_t) (TotalBits256 >> 32);
Context[SHA_256_BLOCK_SIZE - 6] = (uint8_t) (TotalBits256 >> 40);
Context[SHA_256_BLOCK_SIZE - 7] = (uint8_t) (TotalBits256 >> 48);
Context[SHA_256_BLOCK_SIZE - 8] = (uint8_t) (TotalBits256 >> 56);
}
else
{
Context[ContextIndex++] = 0x80;
memset(&Context[ContextIndex], 0, (SHA_256_BLOCK_SIZE - ContextIndex - 8));
Context[SHA_256_BLOCK_SIZE - 1] = (uint8_t) TotalBits256;
Context[SHA_256_BLOCK_SIZE - 2] = (uint8_t) (TotalBits256 >> 8);
Context[SHA_256_BLOCK_SIZE - 3] = (uint8_t) (TotalBits256 >> 16);
Context[SHA_256_BLOCK_SIZE - 4] = (uint8_t) (TotalBits256 >> 24);
Context[SHA_256_BLOCK_SIZE - 5] = (uint8_t) (TotalBits256 >> 32);
Context[SHA_256_BLOCK_SIZE - 6] = (uint8_t) (TotalBits256 >> 40);
Context[SHA_256_BLOCK_SIZE - 7] = (uint8_t) (TotalBits256 >> 48);
Context[SHA_256_BLOCK_SIZE - 8] = (uint8_t) (TotalBits256 >> 56);
}
DataIn = (uint32_t *)Context;
for(uint32_t i=0; i<16;i++)
{
SEC_SHA->DATA_1[i] = DataIn[i];
}
/*start to calculate the last package data*/
SEC_SHA->SHA_CTRL.Bits.CALCULATE = 1;
while(SEC_SHA->SHA_INT_STATE.Bits.INT_DONE == 0);
SEC_SHA->SHA_INT_STATE.Bits.INT_DONE = 0;
}
uint32_t LastDigest[16];
memset(&LastDigest, 0, 64);
/*data out*/
if(SEC_SHA->SHA_CTRL.Bits.MODE >= SHA_512)
{
for(uint32_t i=0;i<8;i++)
{
LastDigest[2*i] = SEC_SHA->HASH_VAL_H[i];
LastDigest[2*i + 1] = SEC_SHA->HASH_VAL_L[i];
*(DataOut++) = (uint8_t)(LastDigest[2*i] >> 24);
*(DataOut++) = (uint8_t)(LastDigest[2*i] >> 16);
*(DataOut++) = (uint8_t)(LastDigest[2*i] >> 8);
*(DataOut++) = (uint8_t)(LastDigest[2*i]);
*(DataOut++) = (uint8_t)(LastDigest[2*i + 1] >> 24);
*(DataOut++) = (uint8_t)(LastDigest[2*i + 1] >> 16);
*(DataOut++) = (uint8_t)(LastDigest[2*i + 1] >> 8);
*(DataOut++) = (uint8_t)(LastDigest[2*i + 1]);
}
}
else
{
for(uint32_t i=0;i<8;i++)
{
LastDigest[i] = SEC_SHA->HASH_VAL_L[i];
*(DataOut++) = (uint8_t)(LastDigest[i] >> 24);
*(DataOut++) = (uint8_t)(LastDigest[i] >> 16);
*(DataOut++) = (uint8_t)(LastDigest[i] >> 8);
*(DataOut++) = (uint8_t)(LastDigest[i]);
}
}
}
static void __sha_updata_256(uint8_t *fp8_Data, uint32_t fu32_Size)
{
/*total bits add*/
TotalBits256 += (fu32_Size << 3);
while(fu32_Size-- > 0)
{
Context[ContextIndex++] = *(fp8_Data++);
if(ContextIndex >= SHA_256_BLOCK_SIZE)
{
ContextIndex = 0;
uint32_t *DataIn = (uint32_t *)Context;
for(uint32_t i=0; i<16;i++)
{
SEC_SHA->DATA_1[i] = DataIn[i];
}
SEC_SHA->SHA_CTRL.Bits.CALCULATE = 1;
while(SEC_SHA->SHA_INT_STATE.Bits.INT_DONE == 0);
SEC_SHA->SHA_INT_STATE.Bits.INT_DONE = 0;
}
}
}
static void __sha_updata_512(uint8_t *fp8_Data, uint32_t fu32_Size)
{
TotalBits512[0] += (fu32_Size << 3);
if(TotalBits512[0] < (uint64_t)(fu32_Size << 3) ) {
TotalBits512[1]++;
}
while(fu32_Size-- > 0)
{
Context[ContextIndex++] = *(fp8_Data++);
if(ContextIndex >= SHA_512_BLOCK_SIZE)
{
ContextIndex = 0;
uint32_t *DataIn = (uint32_t *)Context;
for(uint32_t i=0; i<16;i++)
{
SEC_SHA->DATA_1[i] = DataIn[i];
SEC_SHA->DATA_2[i] = DataIn[i + 16];
}
SEC_SHA->SHA_CTRL.Bits.CALCULATE = 1;
while(SEC_SHA->SHA_INT_STATE.Bits.INT_DONE == 0);
SEC_SHA->SHA_INT_STATE.Bits.INT_DONE = 0;
}
}
}

View File

@ -0,0 +1,240 @@
/*
******************************************************************************
* @file driver_spdif.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2023
* @brief SPDIF module driver.
* This file provides firmware functions to manage the
* SPDIF peripheral
******************************************************************************
* @attention
*
* Copyright (c) 2023 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
/******************************************************************************
* @fn SPDIF_IRQHandler
*
* @brief spdif handle function in spdif isr
*
* @param hspdif : spdif handle
*/
void SPDIF_IRQHandler(SPDIF_HandleTypeDef *hspdif)
{
if(__SPDIF_IS_INT_ALEMPTY())
{
if((__SPDIF_GET_INT_STATUS() & ALEMPTY_FLAG))
{
while(__SPDIF_GET_INT_STATUS() & FULL_FLAG)
{
SPDIF->SPDIF_FIFO_DATA = hspdif->p_TxData[ hspdif->u32_TxCount++];
if(hspdif->u32_TxCount >= hspdif->u32_TxSize)
{
__SPDIF_DISABLE_ALEMPTY_INT();
hspdif->b_TxBusy = false;
if(hspdif->TxCallback)
{
hspdif->TxCallback(hspdif);
}
break;
}
}
}
}
if(__SPDIF_IS_INT_ALFULL())
{
if(__SPDIF_GET_INT_STATUS() & ALFULL_FLAG)
{
while(!(__SPDIF_GET_INT_STATUS() & EMPTY_FLAG))
{
hspdif->p_RxData[hspdif->u32_RxCount++] = SPDIF->SPDIF_FIFO_DATA;
}
}
}
if(__SPDIF_IS_INT_SYNCERR())
{
if(__SPDIF_GET_INT_STATUS() & SYNCERR_FLAG)
{
while(!(__SPDIF_GET_INT_STATUS() & EMPTY_FLAG))
{
hspdif->p_RxData[hspdif->u32_RxCount++] = SPDIF->SPDIF_FIFO_DATA;
}
hspdif->b_RxBusy = false;
__SPDIF_DISABLE_ALFULL_INT();
if(hspdif->RxCallback)
{
hspdif->RxCallback(hspdif);
}
}
}
}
/******************************************************************************
* @fn spdif_init
*
* @brief Initialize the SPDIF according to the specified parameters
* in the SPDIF_HandleTypeDef
*
* @param hspdif : spdif handle
*/
void spdif_init(SPDIF_HandleTypeDef *hspdif)
{
SPDIF->SPDIF_CTRL.TSAMPLERATE = hspdif->Init.TxSampleRate;
SPDIF->SPDIF_CTRL.CHANNEL_MODE = hspdif->Init.CH_Mode;
SPDIF->SPDIF_CTRL.CLK_ENABLE = 0;
SPDIF->SPDIF_CTRL.FIFO_ENABLE = 1;
SPDIF->SPDIF_CTRL.SFR_ENABLE = 1;
SPDIF->SPDIF_CTRL.PARITYGEN = 1;
SPDIF->SPDIF_CTRL.DUPLICATE = 1;
SPDIF->SPDIF_CTRL.SETPREAMBB = 1;
SPDIF->SPDIF_CTRL.INTREQ_MASK = 1;
__SPDIF_FIFO_HALF_FULL_LEVEL(hspdif->Init.HALFIFOFull_Threshold);
__SPDIF_FIFO_ALMOST_EMPTY_LEVEL(hspdif->Init.ALFIFOEmpty_Threshold);
}
/******************************************************************************
* @fn spdif_msg_send
*
* @brief spdif send message
*
* @param hspdif : spdif handle
* fp_Data : send data pointer
* fu32_Size : send data size
*/
bool spdif_msg_send(SPDIF_HandleTypeDef *hspdif, uint32_t *fp_Data, uint32_t fu32_Size)
{
if (fu32_Size == 0) return false;
if (hspdif->b_TxBusy) return false;
if (hspdif->b_RxBusy) return false;
__SPDIF_DISABLE();
hspdif->b_TxBusy = 1;
__SPDIF_Tx_MODE();
__SPDIF_ENABLE();
while(fu32_Size)
{
while(__SPDIF_GET_INT_STATUS() & FULL_FLAG);
SPDIF->SPDIF_FIFO_DATA = *fp_Data++;
fu32_Size--;
}
while(!(__SPDIF_GET_INT_STATUS() & UNDERR_FLAG));
hspdif->b_TxBusy = 0;
return true;
}
/******************************************************************************
* @fn spdif_msg_receive
*
* @brief spdif receive message
*
* @param hspdif : spdif handle
* fp_Data : the receive data buffer
*/
bool spdif_msg_receive(SPDIF_HandleTypeDef *hspdif, uint32_t *fp_Data)
{
if (hspdif->b_TxBusy) return false;
if (hspdif->b_RxBusy) return false;
__SPDIF_DISABLE();
hspdif->b_RxBusy = 1;
__SPDIF_Rx_MODE();
__SPDIF_ENABLE();
while(1)
{
if(!(__SPDIF_GET_INT_STATUS() & EMPTY_FLAG))
{
*fp_Data++ = SPDIF->SPDIF_FIFO_DATA;
}
if(__SPDIF_GET_INT_STATUS() & SYNCERR_FLAG)
{
break;
}
}
hspdif->b_RxBusy = 0;
return true;
}
/******************************************************************************
* @fn spdif_msg_send_IT
*
* @brief spdif send message with isr
*
* @param hspdif : spdif handle
* fp_Data : send data pointer
* fu32_Size : send data size
*/
bool spdif_msg_send_IT(SPDIF_HandleTypeDef *hspdif, uint32_t *fp_Data, uint32_t fu32_Size)
{
if (fu32_Size == 0) return false;
if (hspdif->b_TxBusy) return false;
if (hspdif->b_RxBusy) return false;
hspdif->u32_TxSize = fu32_Size;
hspdif->u32_TxCount = 0;
hspdif->p_TxData = fp_Data;
hspdif->b_TxBusy = 1;
__SPDIF_Tx_MODE();
__SPDIF_ENABLE();
__SPDIF_ENABLE_ALEMPTY_INT();
return true;
}
/******************************************************************************
* @fn spdif_msg_receive_IT
*
* @brief spdif receive message with isr
*
* @param hspdif : spdif handle
* fp_Data : the receive data buffer
*/
bool spdif_msg_receive_IT(SPDIF_HandleTypeDef *hspdif, uint32_t *fp_Data)
{
if (hspdif->b_TxBusy) return false;
if (hspdif->b_RxBusy) return false;
hspdif->p_RxData = fp_Data;
hspdif->b_RxBusy = 1;
hspdif->u32_RxCount = 0;
__SPDIF_Tx_MODE();
__SPDIF_ENABLE();
__SPDIF_ENABLE_ALFULL_INT();
return true;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,513 @@
/*
******************************************************************************
* @file driver_spi_slave.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief SPI module driver.
* This file provides firmware functions to manage the
* Serial Peripheral Interface (SPI) peripheral
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "driver_spi.h"
static void spi_slave_tx_u8(SPI_HandleTypeDef *hspi)
{
while(!__SPI_IS_TxFIFO_FULL(hspi->SPIx))
{
hspi->SPIx->DR = hspi->u_TxData.p_u8[hspi->u32_TxCount++];
if (hspi->u32_TxCount >= hspi->u32_TxSize)
{
break;
}
}
}
static void spi_slave_tx_u16(SPI_HandleTypeDef *hspi)
{
while(!__SPI_IS_TxFIFO_FULL(hspi->SPIx))
{
hspi->SPIx->DR = hspi->u_TxData.p_u16[hspi->u32_TxCount++];
if (hspi->u32_TxCount >= hspi->u32_TxSize)
{
break;
}
}
}
static void spi_slave_tx_u32(SPI_HandleTypeDef *hspi)
{
while(!__SPI_IS_TxFIFO_FULL(hspi->SPIx))
{
hspi->SPIx->DR = hspi->u_TxData.p_u32[hspi->u32_TxCount++];
if (hspi->u32_TxCount >= hspi->u32_TxSize)
{
break;
}
}
}
static void spi_slave_rx_u8(SPI_HandleTypeDef *hspi)
{
while (!__SPI_IS_RxFIFO_EMPTY(hspi->SPIx))
{
hspi->u_RxData.p_u8[hspi->u32_RxCount++] = hspi->SPIx->DR;
if (hspi->u32_RxCount >= hspi->u32_RxSize)
{
break;
}
}
}
static void spi_slave_rx_u16(SPI_HandleTypeDef *hspi)
{
while (!__SPI_IS_RxFIFO_EMPTY(hspi->SPIx))
{
hspi->u_RxData.p_u16[hspi->u32_RxCount++] = hspi->SPIx->DR;
if (hspi->u32_RxCount >= hspi->u32_RxSize)
{
break;
}
}
}
static void spi_slave_rx_u32(SPI_HandleTypeDef *hspi)
{
while (!__SPI_IS_RxFIFO_EMPTY(hspi->SPIx))
{
hspi->u_RxData.p_u32[hspi->u32_RxCount++] = hspi->SPIx->DR;
if (hspi->u32_RxCount >= hspi->u32_RxSize)
{
break;
}
}
}
/************************************************************************************
* @fn spi_slave_IRQHandler
*
* @brief Handle SPI interrupt request.
*
* @param hspi: SPI handle.
*/
void spi_slave_IRQHandler(SPI_HandleTypeDef *hspi)
{
uint8_t frame_size;
/* Tx FIFO Threshold EMPTY */
if (__SPI_TxFIFO_EMPTY_INT_STATUS(hspi->SPIx))
{
frame_size = hspi->Init.Frame_Size;
if(frame_size <= SPI_FRAME_SIZE_8BIT)
{
spi_slave_tx_u8(hspi);
}
else if(frame_size <= SPI_FRAME_SIZE_16BIT)
{
spi_slave_tx_u16(hspi);
}
else
{
spi_slave_tx_u32(hspi);
}
if (hspi->u32_TxCount >= hspi->u32_TxSize)
{
__SPI_TxFIFO_EMPTY_INT_DISABLE(hspi->SPIx);
hspi->b_TxBusy = false;
if (hspi->TxCpltCallback != NULL)
{
hspi->TxCpltCallback(hspi);
}
}
}
/* Rx FIFO Threshold FULL */
else if (__SPI_RxFIFO_FULL_INT_STATUS(hspi->SPIx))
{
frame_size = hspi->Init.Frame_Size;
if(frame_size <= SPI_FRAME_SIZE_8BIT)
{
spi_slave_rx_u8(hspi);
}
else if(frame_size <= SPI_FRAME_SIZE_16BIT)
{
spi_slave_rx_u16(hspi);
}
else
{
spi_slave_rx_u32(hspi);
}
if (hspi->u32_RxCount >= hspi->u32_RxSize)
{
__SPI_RxFIFO_FULL_INT_DISABLE(hspi->SPIx);
hspi->b_RxBusy = false;
if (hspi->RxCpltCallback != NULL)
{
hspi->RxCpltCallback(hspi);
}
}
}
}
/************************************************************************************
* @fn spi_slave_init
*
* @brief Initialize the SPI according to the specified parameters in the struct_SPIInit_t
*
* @param hspi: SPI handle.
*/
void spi_slave_init(SPI_HandleTypeDef *hspi)
{
/* Disable SPI, reset FIFO */
__SPI_DISABLE(hspi->SPIx);
/* Work mode */
hspi->SPIx->CTRL0.SCPOL = hspi->Init.Work_Mode & 0x2 ? 1 : 0;
hspi->SPIx->CTRL0.SCPH = hspi->Init.Work_Mode & 0x1 ? 1 : 0;
/* FIFO Threshold */
hspi->SPIx->TXFTLR = hspi->Init.TxFIFOEmpty_Threshold;
hspi->SPIx->RXFTLR = hspi->Init.RxFIFOFull_Threshold;
/* Disable all interrupt */
hspi->SPIx->IMR.MSTIM = 0;
hspi->SPIx->IMR.TXEIM = 0;
hspi->SPIx->IMR.TXOIM = 0;
hspi->SPIx->IMR.RXUIM = 0;
hspi->SPIx->IMR.RXOIM = 0;
hspi->SPIx->IMR.RXFIM = 0;
__SPI_CS_TOGGLE_DISABLE(hspi->SPIx);
/* CS Set */
hspi->SPIx->SER = 0;
}
/************************************************************************************
* @fn spi_slave_transmit
*
* @brief Send an amount of data in blocking mode.(Standard<72><64>Dual and Quad mode)
*
* @param hspi: SPI handle.
* fp_Data: pointer to data buffer
* fu32_Size: amount of data to be sent
*/
void spi_slave_transmit(SPI_HandleTypeDef *hspi, void *fp_Data, uint32_t fu32_Size)
{
uint8_t frame_size;
union {
void *data;
uint8_t *p_u8;
uint16_t *p_u16;
uint32_t *p_u32;
} p_data;
p_data.data = fp_Data;
/* config Mult Write Transfer parameters */
spi_slave_MultWireConfig(hspi,Wire_Write);
/* Get current frame size */
frame_size = hspi->Init.Frame_Size;
/* Frame Size <= 8 */
if (frame_size <= SPI_FRAME_SIZE_8BIT)
{
while (fu32_Size--)
{
while(__SPI_IS_TxFIFO_FULL(hspi->SPIx));
/* write data to tx FIFO */
hspi->SPIx->DR = *p_data.p_u8++;
}
}
else if(frame_size <= SPI_FRAME_SIZE_16BIT)
{
while (fu32_Size--)
{
while(__SPI_IS_TxFIFO_FULL(hspi->SPIx));
/* write data to tx FIFO */
hspi->SPIx->DR = *p_data.p_u16++;
}
}
else
{
while(fu32_Size--)
{
while(__SPI_IS_TxFIFO_FULL(hspi->SPIx));
/* write data to tx FIFO */
hspi->SPIx->DR = *p_data.p_u32++;
}
}
while(__SPI_IS_BUSY(hspi->SPIx));
}
/************************************************************************************
* @fn spi_slave_transmit_IT
*
* @brief Send an amount of data in interrupt mode.(Standard<72><64>Dual and Quad mode)
*
* @param hspi: SPI handle.
* fp_Data: pointer to data buffer
* fu32_Size: amount of data to be sent
*/
void spi_slave_transmit_IT(SPI_HandleTypeDef *hspi, void*fp_Data, uint32_t fu32_Size)
{
if (hspi->b_TxBusy)
return;
uint8_t frame_size;
/* config Mult Write Transfer parameters */
spi_slave_MultWireConfig(hspi,Wire_Write);
hspi->u32_TxSize = fu32_Size;
hspi->u32_TxCount = 0;
hspi->b_TxBusy = true;
hspi->u_TxData.p_data = fp_Data;
/* Get current frame size */
frame_size = hspi->Init.Frame_Size;
if (frame_size <= SPI_FRAME_SIZE_8BIT)
{
while(!__SPI_IS_TxFIFO_FULL(hspi->SPIx))
{
hspi->SPIx->DR = hspi->u_TxData.p_u8[hspi->u32_TxCount++];
if (hspi->u32_TxCount >= fu32_Size)
{
hspi->b_TxBusy = false;
return;
}
}
}
else if (frame_size <= SPI_FRAME_SIZE_16BIT)
{
while(!__SPI_IS_TxFIFO_FULL(hspi->SPIx))
{
hspi->SPIx->DR = hspi->u_TxData.p_u16[hspi->u32_TxCount++];
if (hspi->u32_TxCount >= fu32_Size)
{
hspi->b_TxBusy = false;
return;
}
}
}
else
{
while(!__SPI_IS_TxFIFO_FULL(hspi->SPIx))
{
hspi->SPIx->DR = hspi->u_TxData.p_u32[hspi->u32_TxCount++];
if (hspi->u32_TxCount >= fu32_Size)
{
hspi->b_TxBusy = false;
return;
}
}
}
/* TxFIFO empty interrupt enable */
__SPI_TxFIFO_EMPTY_INT_ENABLE(hspi->SPIx);
}
/************************************************************************************
* @fn spi_slave_transmit_DMA
*
* @brief Send an amount of data in DMA mode.(Standard<72><64>Dual and Quad mode)
*
* @param hspi: SPI handle.
*/
void spi_slave_transmit_DMA(SPI_HandleTypeDef *hspi)
{
/* config Mult Write Transfer parameters */
spi_slave_MultWireConfig(hspi,Wire_Write);
/* DMA Config */
__SPI_DMA_TX_ENABLE(hspi->SPIx);
__SPI_DMA_TX_LEVEL(hspi->SPIx, hspi->Init.TxFIFOEmpty_Threshold);
}
/************************************************************************************
* @fn spi_slave_receive
*
* @brief Receive an amount of data in blocking mode.(Standard<72><64>Dual and Quad mode)
*
* @param hspi: SPI handle.
* fp_Data: pointer to data buffer
* fu32_Size: amount of data to be Receive
*/
void spi_slave_receive(SPI_HandleTypeDef *hspi, void *fp_Data, uint32_t fu32_Size)
{
uint8_t frame_size;
union {
void *data;
uint8_t *p_u8;
uint16_t *p_u16;
uint32_t *p_u32;
} p_data;
p_data.data = fp_Data;
/* config Mult Read Transfer parameters */
spi_slave_MultWireConfig(hspi,Wire_Read);
/* Get current frame size */
frame_size = hspi->Init.Frame_Size;
/* Frame Size <= 8 */
if (frame_size <= SPI_FRAME_SIZE_8BIT)
{
while (fu32_Size)
{
while(!__SPI_IS_RxFIFO_EMPTY(hspi->SPIx))
{
*p_data.p_u8++ = hspi->SPIx->DR;
fu32_Size--;
}
}
}
else if (frame_size <= SPI_FRAME_SIZE_16BIT)
{
while (fu32_Size)
{
while(!__SPI_IS_RxFIFO_EMPTY(hspi->SPIx))
{
*p_data.p_u16++ = hspi->SPIx->DR;
fu32_Size--;
}
}
}
else
{
while (fu32_Size)
{
while(!__SPI_IS_RxFIFO_EMPTY(hspi->SPIx))
{
*p_data.p_u32++ = hspi->SPIx->DR;
fu32_Size--;
}
}
}
while(__SPI_IS_BUSY(hspi->SPIx));
}
/************************************************************************************
* @fn spi_slave_receive_IT
*
* @brief Receive an amount of data in interrupt mode.(Standard<72><64>Dual and Quad mode)
*
* @param hspi: SPI handle.
* fp_Data: pointer to data buffer
* fu32_Size: amount of data to be Receive
*/
void spi_slave_receive_IT(SPI_HandleTypeDef *hspi, void *fp_Data, uint32_t fu32_Size)
{
if (hspi->b_RxBusy)
return;
/* config Mult Read Transfer parameters */
spi_slave_MultWireConfig(hspi,Wire_Read);
hspi->u32_RxSize = fu32_Size;
hspi->u32_RxCount = 0;
hspi->b_RxBusy = true;
hspi->u_RxData.p_data = fp_Data;
/* RxFIFO full interrupt enable */
__SPI_RxFIFO_FULL_INT_ENABLE(hspi->SPIx);
}
/************************************************************************************
* @fn spi_slave_receive_DMA
*
* @brief Receive an amount of data in interrupt mode.(Standard<72><64>Dual and Quad mode)
*
* @param hspi: SPI handle.
* fp_Data: pointer to data buffer
* fu32_Size: amount of data to be Receive
*/
void spi_slave_receive_DMA(SPI_HandleTypeDef *hspi)
{
/* config Mult Read Transfer parameters */
spi_slave_MultWireConfig(hspi,Wire_Read);
/* DMA Config */
__SPI_DMA_RX_ENABLE(hspi->SPIx);
__SPI_DMA_RX_LEVEL(hspi->SPIx, hspi->Init.RxFIFOFull_Threshold);
}
/************************************************************************************
* @fn spi_slave_MultWireConfig
*
* @brief config Mult Wire Transfer parameters.(DualbQuad mode)
*
* @param hspi: SPI handle.
*/
void spi_slave_MultWireConfig(SPI_HandleTypeDef *hspi, enum_Wire_Type_t fe_type)
{
/* Disable SPI, reset FIFO */
__SPI_DISABLE(hspi->SPIx);
/* slave mode and Frame Size*/
if (hspi->MultWireParam.Wire_X2X4X8 == Wire_X2)
{
__SPI_SLAVE_SET_MODE_X2(hspi->SPIx);
hspi->SPIx->CTRL0.DFS_32 = (hspi->Init.Frame_Size + 1) / 2 - 1;
}
else if (hspi->MultWireParam.Wire_X2X4X8 == Wire_X4)
{
__SPI_SLAVE_SET_MODE_X4(hspi->SPIx);
hspi->SPIx->CTRL0.DFS_32 = (hspi->Init.Frame_Size + 1) / 4 - 1;
}
else
{
__SPI_SLAVE_SET_MODE_X1(hspi->SPIx);
hspi->SPIx->CTRL0.DFS_32 = hspi->Init.Frame_Size;
}
if (fe_type == Wire_Write)
{
/* slave output enable */
hspi->SPIx->CTRL0.SLV_OE = 0;
/* Select Only Tx mode */
__SPI_TMODE_Tx_ONLY(hspi->SPIx);
}
else
{
/* slave output disable */
hspi->SPIx->CTRL0.SLV_OE = 1;
/* Select Only Rx mode */
__SPI_TMODE_Rx_ONLY(hspi->SPIx);
}
/* Enable SPI */
__SPI_ENABLE(hspi->SPIx);
}

View File

@ -0,0 +1,127 @@
/*
******************************************************************************
* @file driver_tick.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief Tick module driver.
* This file provides firmware functions to manage the System Tick peripheral
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
/************************************************************************************
* @fn tick_IRQHandler
*
* @brief Handle Tick interrupt request.
*
* @param htick: Tick handle.
*/
void tick_IRQHandler(TICK_HandleTypeDef *htick)
{
uint32_t status = Tick->INT_STA.Word;
/* system wake up from sleep */
if (status & TICK_INT_TYPE_SLP) {
if ((htick) && (htick->TickSleepCallback)) {
htick->TickSleepCallback();
}
Tick->INT_STA.Bits.SLP = 1;
}
/* tick reach target value */
if (status & TICK_INT_TYPE_TGT) {
if ((htick) && (htick->TickTargetCallback)) {
htick->TickTargetCallback();
}
Tick->INT_STA.Bits.TGT = 1;
Tick->INT_CTL.Bits.TGT = 0;
}
}
/************************************************************************************
* @fn tick_init
*
* @brief Init System Tick.
*
* @param htick: Tick handle.
*/
void tick_init(TICK_HandleTypeDef *handle)
{
/* enable Timerstamp compare default */
Tick->CTL.CMP_EN = 1;
/* enable sleep interrupt as default */
Tick->INT_CTL.Bits.SLP = 1;
}
/************************************************************************************
* @fn tick_get
*
* @brief Get current System Tick.
*
* @param clk: pointer used to store clock counter.
* fine: pointer used to store fine counter.
*/
void tick_get(uint32_t *clk, uint32_t *fine)
{
Tick->CTL.SMP = 1;
while(Tick->CTL.SMP == 1);
*clk = Tick->CLK_SMP;
*fine = Tick->FINE_SMP;
}
/************************************************************************************
* @fn tick_set_target
*
* @brief Set system tick target time and wait for the target time in block mode.
*
* @param clk: target clock counter.
* fine: target fine counter.
*/
void tick_set_target(uint32_t clk, uint32_t fine)
{
Tick->CLK_TGT = clk;
Tick->FINE_TGT = fine;
while (Tick->INT_RAW.Bits.TGT == 0);
Tick->INT_STA.Bits.TGT = 1;
}
/************************************************************************************
* @fn tick_set_target_IT
*
* @brief Set system tick target time in interrupt mode.
*
* @param clk: target clock counter.
* fine: target fine counter.
*/
void tick_set_target_IT(uint32_t clk, uint32_t fine)
{
Tick->CLK_TGT = clk;
Tick->FINE_TGT = fine;
Tick->INT_CTL.Bits.TGT = 1;
}
/************************************************************************************
* @fn tick_start_corr
*
* @brief Used to correction system tick after wake from sleep mode.
*
* @param clk: clock counter corrcetion value.
* fine: fine counter corrcetion value.
*/
void tick_start_corr(uint32_t clk, uint32_t fine)
{
Tick->CLK_CORR = clk;
Tick->FINE_CORR = fine;
Tick->SLP_CTL.SLP_CORR_EN = 1;
while(Tick->SLP_CTL.SLP_CORR_EN == 1);
}

View File

@ -0,0 +1,117 @@
/*
******************************************************************************
* @file driver_timer.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief Timer module driver.
* This file provides firmware functions to manage the Timer peripheral
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
/************************************************************************************
* @fn timer_init
*
* @brief timer initialize.
*
* @param TIMERx: Timer handle.
* fu32_LoadCount: Timer Load Count.
*/
void timer_init(struct_Timer_t *TIMERx, uint32_t fu32_LoadCount)
{
TIMERx->LoadCount = fu32_LoadCount;
TIMERx->Control.MODE = 1;
}
/************************************************************************************
* @fn timer_int_enable
*
* @brief timer interrupt enable.
*
* @param TIMERx: Timer handle.
*/
void timer_int_enable(struct_Timer_t *TIMERx)
{
TIMERx->Control.INT_MASK = 0;
}
/************************************************************************************
* @fn timer_int_disable
*
* @brief timer interrupt disable.
*
* @param TIMERx: Timer handle.
*/
void timer_int_disable(struct_Timer_t *TIMERx)
{
TIMERx->Control.INT_MASK = 1;
}
/************************************************************************************
* @fn timer_int_clear
*
* @brief timer interrupt status clear.
*
* @param TIMERx: Timer handle.
*/
void timer_int_clear(struct_Timer_t *TIMERx)
{
uint32_t lu32_TempValue;
lu32_TempValue = TIMERx->IntClear;
}
/************************************************************************************
* @fn timer_int_status
*
* @brief get timer interrupt status.
*
* @param TIMERx: Timer handle.
*/
bool timer_int_status(struct_Timer_t *TIMERx)
{
return TIMERx->IntStatus;
}
/************************************************************************************
* @fn timer_start
*
* @brief Timer start count.
*
* @param TIMERx: Timer handle.
*/
void timer_start(struct_Timer_t *TIMERx)
{
TIMERx->Control.ENABLE = 1;
}
/************************************************************************************
* @fn timer_stop
*
* @brief Timer stop count.
*
* @param TIMERx: Timer handle.
*/
void timer_stop(struct_Timer_t *TIMERx)
{
TIMERx->Control.ENABLE = 0;
}
/************************************************************************************
* @fn timer_get_CurrentCount
*
* @brief get Timer current count.
*
* @param TIMERx: Timer handle.
*/
uint32_t timer_get_CurrentCount(struct_Timer_t *TIMERx)
{
return TIMERx->CurrentValue;
}

View File

@ -0,0 +1,105 @@
/*
******************************************************************************
* @file driver_trigfunc.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2023
* @brief trigfunc module driver.
* This file provides firmware functions to manage the
* trigfunc(trigonometric function) peripheral
******************************************************************************
* @attention
*
* Copyright (c) 2023 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
double trigfunc_sin(double fe_argin)
{
double f_value = 0;
uint32_t int_value = 0;
fe_argin = QUANTIZATION_PARAMETER * fe_argin;
int_value = (int)fe_argin;
f_value = fe_argin - int_value;
if((f_value) >= 0.5)
{
int_value++;
}
TRIGFUNC->TRIGFUNC_INTR &= ~TRIGFUNC_INTRCR;
TRIGFUNC->TRIGFUNC_CTRL = TRIG_CAL_SIN_AND_COS | BYTE_2;
TRIGFUNC->TRIGFUNC_ARG1_IN = int_value;
while(!__TRIGFUNC_CAL_IS_DONE_STATUS());
return (int16_t)(TRIGFUNC->TRIGFUNC_RESULT2_OUT) / QUANTIZATION_PARAMETER;
}
double trigfunc_cos(double fe_argin)
{
double f_value = 0;
uint32_t int_value = 0;
fe_argin = QUANTIZATION_PARAMETER * fe_argin;
int_value = (int)fe_argin;
f_value = fe_argin - int_value;
if((f_value) >= 0.5)
{
int_value++;
}
TRIGFUNC->TRIGFUNC_INTR &= ~TRIGFUNC_INTRCR;
TRIGFUNC->TRIGFUNC_CTRL = TRIG_CAL_SIN_AND_COS | BYTE_2;
TRIGFUNC->TRIGFUNC_ARG1_IN = int_value;
while(!__TRIGFUNC_CAL_IS_DONE_STATUS());
return (int16_t)(TRIGFUNC->TRIGFUNC_RESULT1_OUT) / QUANTIZATION_PARAMETER;
}
double trigfunc_tan(double fe_argin)
{
double f_value;
uint32_t int_value = 0;
fe_argin = QUANTIZATION_PARAMETER * fe_argin;
int_value = (int)fe_argin;
f_value = fe_argin - int_value;
if((f_value) >= 0.5)
{
int_value++;
}
TRIGFUNC->TRIGFUNC_INTR &= ~TRIGFUNC_INTRCR;
TRIGFUNC->TRIGFUNC_CTRL = TRIG_CAL_TAN | BYTE_2;
TRIGFUNC->TRIGFUNC_ARG1_IN = int_value;
while(!__TRIGFUNC_CAL_IS_DONE_STATUS());
return (int16_t)(TRIGFUNC->TRIGFUNC_RESULT1_OUT) / (double)0x100 ;
}
double trigfunc_atan(double fe_argin)
{
int16_t f_value;
TRIGFUNC->TRIGFUNC_INTR &= ~TRIGFUNC_INTRCR;
TRIGFUNC->TRIGFUNC_CTRL = TRIG_CAL_ARCTAN_X | BYTE_2;
f_value = fe_argin * 0x100;
TRIGFUNC->TRIGFUNC_ARG1_IN = f_value;
while(!__TRIGFUNC_CAL_IS_DONE_STATUS());
return (int16_t)(TRIGFUNC->TRIGFUNC_RESULT1_OUT) * 180 / QUANTIZATION_PARAMETER;
}

View File

@ -0,0 +1,120 @@
/*
******************************************************************************
* @file driver_trng.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2023
* @brief TRNG module driver.
* This file provides firmware functions to manage the
* True Random Number Generator (TRNG) peripheral.
******************************************************************************
* @attention
*
* Copyright (c) 2023 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
static int trng_sel_smp_verify(int Rand_sel_index, int Sample_cnt_index)
{
int Error;
TRNG->TRNG_IMR = 0XFFFFFF00;
TRNG->TRNG_SrcEN = 0;
TRNG->TRNG_DebugControl = 0;
/* Selects the number of inverters in the ring oscillator */
TRNG->TRNG_Config = Rand_sel_index;
while((TRNG->TRNG_Config & Rand_sel_index) != Rand_sel_index);
TRNG->TRNG_SAMPLE_CNT1 = Sample_cnt_index;
while((TRNG->TRNG_SAMPLE_CNT1 & Sample_cnt_index) != Sample_cnt_index);
TRNG->TRNG_AUTOCORR = 0;
TRNG->TRNG_SrcEN = 1;
while(!(TRNG->TRNG_ISR));
if (TRNG->TRNG_ISR & TRNG_STATUS_EHR_VALID)
Error = 0;
else
Error = 1;
if (Error)
{
TRNG->TRNG_Reset = 1;
}
TRNG->TRNG_ICR = 0XFFFFFFFF;
return !Error;
}
/************************************************************************************
* @fn trng_init
*
* @brief trng init.
*/
void trng_init(void)
{
#define MAX_SAMPLE_CNT_INDX (0xFFFFFF00)
uint32_t Rand_sel_index;
uint32_t Sample_cnt_index;
uint32_t Rand_Sample_Passed;
for (Rand_sel_index = 1; Rand_sel_index < 4; Rand_sel_index++)
{
Rand_Sample_Passed = 0;
Sample_cnt_index = 33333;
do{
Rand_Sample_Passed = trng_sel_smp_verify(Rand_sel_index, Sample_cnt_index);
Sample_cnt_index += 111;
} while ((Sample_cnt_index <= (MAX_SAMPLE_CNT_INDX)) && !Rand_Sample_Passed);
while(TRNG->TRNG_BIST_CNTR0 <= 0);
while(TRNG->TRNG_BIST_CNTR1 <= 0);
while(TRNG->TRNG_BIST_CNTR2 <= 0);
if (Rand_Sample_Passed)
break;
}
TRNG->TRNG_SrcEN = 0;
}
/************************************************************************************
* @fn trng_read_rand_num
*
* @brief Read random numbers.
*
* @param fp_buffer: random numbers buffer.
* @param length: random numbers length, max 24 byte.
*/
void trng_read_rand_num(uint8_t *fp_buffer, uint8_t length)
{
int i;
uint32_t lu32_buffer[6];
uint8_t *Point = (uint8_t *)lu32_buffer;
if (length > 24)
length = 24;
/* TRNG enable */
TRNG->TRNG_SrcEN = 1;
/* Wait VALID */
while(!(TRNG->TRNG_ISR & TRNG_STATUS_EHR_VALID));
for(int i = 0; i < 6; i++)
lu32_buffer[i] = TRNG->TRNG_Data[i];
for (int i = 0; i < length; i++)
fp_buffer[i] = Point[i];
/* TRNG disable */
TRNG->TRNG_SrcEN = 0;
/* Clear status */
TRNG->TRNG_ICR = TRNG_STATUS_EHR_VALID;
}

View File

@ -0,0 +1,325 @@
/*
******************************************************************************
* @file driver_uart.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief UART module driver.
* This file provides firmware functions to manage the
* Universal Asynchronous Receiver/Transmitter (UART) peripheral
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
/************************************************************************************
* @fn uart_IRQHandler
*
* @brief Handle UART interrupt request.
*
* @param huart: UART handle.
*/
__WEAK void uart_IRQHandler(UART_HandleTypeDef *huart)
{
switch (__UART_INT_GET_ID(huart->UARTx))
{
case INT_INDEX_TXE:
{
/* Data transit end */
if (huart->u32_TxCount >= huart->u32_TxSize)
{
__UART_INT_TXE_DISABLE(huart->UARTx);
huart->b_TxBusy = false;
}
else
{
/* UART_FIFO_ENABLE */
if (__UART_IS_FIFO_Enable(huart))
{
/* Until TxFIFO full */
while(!__UART_IS_TxFIFO_FULL(huart->UARTx))
{
huart->UARTx->DATA_DLL.DATA = huart->p_TxData[huart->u32_TxCount++];
/* Data transit end */
if (huart->u32_TxCount >= huart->u32_TxSize)
{
__UART_INT_TXE_DISABLE(huart->UARTx);
huart->b_TxBusy = false;
if (huart->TxCpltCallback != NULL)
{
huart->TxCpltCallback(huart);
}
break;
}
}
}
else
{
huart->UARTx->DATA_DLL.DATA = huart->p_TxData[huart->u32_TxCount++];
}
}
}break;
case INT_INDEX_RX:
case INT_INDEX_RX_TOUT:
{
/* Rx ready */
while (huart->UARTx->LSR.LSR_BIT.DR)
{
huart->p_RxData[huart->u32_RxCount++] = huart->UARTx->DATA_DLL.DATA;
/* Data receive end */
if (huart->u32_RxCount >= huart->u32_RxSize)
{
__UART_INT_RX_DISABLE(huart->UARTx);
huart->b_RxBusy = false;
if (huart->RxCpltCallback != NULL)
{
huart->RxCpltCallback(huart);
}
break;
}
}
}break;
default: break;
}
}
/************************************************************************************
* @fn uart_init
*
* @brief Initialize the UART according to the specified parameters in the struct_UARTInit_t
*
* @param huart: UART handle.
*/
void uart_init(UART_HandleTypeDef *huart)
{
/* Config Data Length */
huart->UARTx->LCR.Bits.DLS = huart->Init.DataLength;
/* Config Stop Bits*/
huart->UARTx->LCR.Bits.STOP = huart->Init.StopBits;
/* Config Auto Flow */
if(huart->Init.AUTO_FLOW)
{
__UART_AUTO_FLOW_CONTROL_ENABLE( huart->UARTx);
}
/* Config Parity */
if (huart->Init.Parity != UART_PARITY_NONE)
{
huart->UARTx->LCR.Bits.PEN = 1;
switch (huart->Init.Parity)
{
case UART_PARITY_ODD: huart->UARTx->LCR.Bits.SP = 0; huart->UARTx->LCR.Bits.EPS = 0; break;
case UART_PARITY_EVEN: huart->UARTx->LCR.Bits.SP = 0; huart->UARTx->LCR.Bits.EPS = 1; break;
case UART_PARITY_0: huart->UARTx->LCR.Bits.SP = 1; huart->UARTx->LCR.Bits.EPS = 1; break;
case UART_PARITY_1: huart->UARTx->LCR.Bits.SP = 1; huart->UARTx->LCR.Bits.EPS = 0; break;
default: break;
}
}
else
{
huart->UARTx->LCR.Bits.PEN = 0;
}
/* Config FIFO<46><4F>DMA<4D><41>RxFIF/TxFIFO threshold */
huart->FCR_Shadow = huart->Init.FIFO_Mode | (huart->Init.FIFO_Mode << FCR_DMAM);
huart->UARTx->FCR_IID.FCR = huart->FCR_Shadow;
/* Config BaudRate */
uart_config_baudRate(huart);
}
/************************************************************************************
* @fn uart_transmit
*
* @brief Send an amount of data in blocking mode.
*
* @param huart: UART handle.
* @param fp_Data: Pointer to data buffer.
* @param fu32_Size: Amount of data to be sent.
*/
void uart_transmit(UART_HandleTypeDef *huart, uint8_t *fp_Data, uint32_t fu32_Size)
{
/* UART_FIFO_ENABLE */
if (__UART_IS_FIFO_Enable(huart))
{
while (fu32_Size--)
{
/* TxFIFO FULL */
while(!(huart->UARTx->USR.TFNF));
/* Send data */
huart->UARTx->DATA_DLL.DATA = *fp_Data++;
}
}
else
{
while (fu32_Size--)
{
/* Tx not empty */
while(!(huart->UARTx->LSR.LSR_BIT.THRE));
/* Send data */
huart->UARTx->DATA_DLL.DATA = *fp_Data++;
}
}
}
/************************************************************************************
* @fn uart_receive
*
* @brief Receive an amount of data in blocking mode.
*
* @param huart: UART handle.
* @param fp_Data: Pointer to data buffer.
* @param fu32_Size: Amount of data to be receive.
*/
void uart_receive(UART_HandleTypeDef *huart, uint8_t *fp_Data, uint32_t fu32_Size)
{
while (fu32_Size--)
{
/* Rx ready */
while (!(huart->UARTx->LSR.LSR_BIT.DR));
/* receive data */
*fp_Data++ = huart->UARTx->DATA_DLL.DATA;
}
}
/************************************************************************************
* @fn uart_transmit_IT
*
* @brief Send an amount of data in interrupt mode.
*
* @param huart: UART handle.
* @param fp_Data: Pointer to data buffer.
* @param fu32_Size: Amount of data to be sent.
*/
void uart_transmit_IT(UART_HandleTypeDef *huart, uint8_t *fp_Data, uint32_t fu32_Size)
{
if (huart->b_TxBusy)
return;
huart->p_TxData = fp_Data;
huart->u32_TxCount = 0;
huart->u32_TxSize = fu32_Size;
huart->b_TxBusy = true;
/* UART_FIFO_ENABLE */
if (__UART_IS_FIFO_Enable(huart))
{
// /* Tx FIFO reset */
// __UART_TxFIFO_Reset(huart);
/* Tx empty interrupt and fifo enable */
__UART_INT_TXE_ENABLE_FE(huart->UARTx);
}
else
{
/* Tx empty interrupt and fifo disable */
__UART_INT_TXE_ENABLE_FD(huart->UARTx);
}
}
/************************************************************************************
* @fn uart_transmit_IT
*
* @brief Receive an amount of data in interrupt mode.
*
* @param huart: UART handle.
* @param fp_Data: Pointer to data buffer.
* @param fu32_Size: Amount of data to be receive.
*/
void uart_receive_IT(UART_HandleTypeDef *huart, uint8_t *fp_Data, uint32_t fu32_Size)
{
if (huart->b_RxBusy)
return;
huart->p_RxData = fp_Data;
huart->u32_RxCount = 0;
huart->u32_RxSize = fu32_Size;
huart->b_RxBusy = true;
// /* Rx FIFO reset */
// __UART_RxFIFO_Reset(huart);
/* data ready<64><79>character timeout interrupt enable */
__UART_INT_RX_ENABLE(huart->UARTx);
}
/************************************************************************************
* @fn uart_config_baudRate
*
* @brief Config BaudRate
*
* @param huart: UART handle.
*/
void uart_config_baudRate(UART_HandleTypeDef *huart)
{
uint32_t i;
uint32_t lu32_UartClock;
uint32_t lu32_Integer;
uint64_t lu64_Fractional;
uint16_t lu32_TempValue[2];
lu32_UartClock = system_get_peripheral_clock(PER_CLK_UARTx);
/* Calculate the integer part */
lu32_Integer = lu32_UartClock / (16 * huart->Init.BaudRate);
/* Calculate the fractional part */
lu64_Fractional = lu32_UartClock % (16 * huart->Init.BaudRate);
lu64_Fractional = (lu64_Fractional * 10000) / (16 * huart->Init.BaudRate);
for (i = 0; i < 0x3F; i++)
{
lu32_TempValue[0] = (i * 10000) / 64;
lu32_TempValue[1] = ((i + 1) * 10000) / 64;
if (lu64_Fractional >= lu32_TempValue[0] && lu64_Fractional <= lu32_TempValue[1])
{
if (lu64_Fractional - lu32_TempValue[0] < lu32_TempValue[1] - lu64_Fractional)
{
lu64_Fractional = i;
}
else
{
lu64_Fractional = i + 1;
}
break;
}
else if (i == 0x3E)
{
lu64_Fractional = 0x3F;
}
}
/* DLL<4C><4C>DLH register access enable */
__UART_DLL_DLH_ACCESS_ENABLE(huart->UARTx);
huart->UARTx->DATA_DLL.DLL = lu32_Integer & 0xFF;
huart->UARTx->IER_DLH.DLH = (lu32_Integer >> 8) & 0xFF;
huart->UARTx->DLF.DLF = lu64_Fractional;
/* DLL<4C><4C>DLH register access disable */
__UART_DLL_DLH_ACCESS_DISABLE(huart->UARTx);
}

View File

@ -0,0 +1,172 @@
/*
******************************************************************************
* @file driver_yuv2rgb.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2022
* @brief YUV2RGB module driver.
* This file provides firmware functions to manage the YUV2RGB.
******************************************************************************
* @attention
*
* Copyright (c) 2022 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "fr30xx.h"
/************************************************************************************
* @fn yuv2rgb_IRQHandler
*
* @brief yuv2rgb interrupt handler.
*
* @param hyuv2rgb: YUV2RGB handle.
*/
__WEAK void yuv2rgb_IRQHandler(YUV2RGB_HandleTypeDef *hyuv2rgb)
{
if (__YUV2RGB_GET_INT_STATUS(hyuv2rgb->YUV2RGBx) & YUV_FIFO_ALMOST_EMPTY)
{
while(!(__YUV2RGB_GET_INT_RAW_STATUS(hyuv2rgb->YUV2RGBx) & YUV_FIFO_FULL))
{
switch (hyuv2rgb->Init.YUV_Format)
{
case YUV_FORMAT_444: hyuv2rgb->YUV2RGBx->YUV_DATA = *hyuv2rgb->u_YUVData.p_u32++; break;
case YUV_FORMAT_422: hyuv2rgb->YUV2RGBx->YUV_DATA = *hyuv2rgb->u_YUVData.p_u16++; break;
default:break;
}
hyuv2rgb->u32_YUVCount++;
if (hyuv2rgb->u32_YUVCount >= hyuv2rgb->u32_Pixels)
{
__YUV2RGB_INT_DISABLE(hyuv2rgb->YUV2RGBx, YUV_FIFO_ALMOST_EMPTY);
break;
}
}
}
if (__YUV2RGB_GET_INT_STATUS(hyuv2rgb->YUV2RGBx) & RGB_FIFO_ALMOST_FULL)
{
while (!(__YUV2RGB_GET_INT_RAW_STATUS(hyuv2rgb->YUV2RGBx) & RGB_FIFO_EMPTY))
{
switch (hyuv2rgb->Init.RGB_Format)
{
case RGB_FORMAT_888: *hyuv2rgb->u_RGBData.p_u32++ = hyuv2rgb->YUV2RGBx->RGB_DATA; break;
case RGB_FORMAT_565: *hyuv2rgb->u_RGBData.p_u16++ = hyuv2rgb->YUV2RGBx->RGB_DATA; break;
case RGB_FORMAT_332: *hyuv2rgb->u_RGBData.p_u8++ = hyuv2rgb->YUV2RGBx->RGB_DATA; break;
default:break;
}
hyuv2rgb->u32_RGBCount++;
if (hyuv2rgb->u32_RGBCount >= hyuv2rgb->u32_Pixels)
{
__YUV2RGB_INT_DISABLE(hyuv2rgb->YUV2RGBx, RGB_FIFO_ALMOST_FULL);
hyuv2rgb->b_CovertBusy = false;
break;
}
}
}
}
/************************************************************************************
* @fn yuv2rgb_init
*
* @brief Initialize YUV2RGB UART according to the specified parameters
* in the struct_YUV2RGBInit_t.
*
* @param hyuv2rgb: YUV2RGB handle.
*/
void yuv2rgb_init(YUV2RGB_HandleTypeDef *hyuv2rgb)
{
/* YUV2RGB enable */
__YUV2RGB_ENABLE(hyuv2rgb->YUV2RGBx);
/* DMA default enable */
__YUV2RGB_DMA_ENABLE(hyuv2rgb->YUV2RGBx);
/* Set YUV2RGB format, calculate Mode */
hyuv2rgb->YUV2RGBx->YUV2RGB_CFG.RGB_FORMAT = hyuv2rgb->Init.RGB_Format;
hyuv2rgb->YUV2RGBx->YUV2RGB_CFG.YUV_FORMAT = hyuv2rgb->Init.YUV_Format;
hyuv2rgb->YUV2RGBx->YUV2RGB_CFG.YUV_MODE = hyuv2rgb->Init.YUV_CalculateMode;
if (hyuv2rgb->Init.YUV_Format == YUV_FORMAT_444)
hyuv2rgb->YUV2RGBx->FLOW_CTRL.YUV_FLOW_LEVEL = 1;
else
hyuv2rgb->YUV2RGBx->FLOW_CTRL.YUV_FLOW_LEVEL = 2;
hyuv2rgb->YUV2RGBx->FLOW_CTRL.RGB_FLOW_LEVEL = 30;
}
/************************************************************************************
* @fn yuv2rgb_convert
*
* @brief YUV to RGB convert in blocking mode.
*
* @param hyuv2rgb: YUV2RGB handle.
* YUV_Buffer: YUV data buffer.
* RGB_BUffer: RGB data buffer.
* fu32_Pixels:
*/
void yuv2rgb_convert(YUV2RGB_HandleTypeDef *hyuv2rgb, void *YUV_Buffer, void *RGB_Buffer, uint32_t fu32_Pixels)
{
uint32_t lu32_RGBCount = 0;
uint32_t lu32_YUVCount = 0;
hyuv2rgb->u_YUVData.p_data = YUV_Buffer;
hyuv2rgb->u_RGBData.p_data = RGB_Buffer;
while(true)
{
if (!(__YUV2RGB_GET_INT_RAW_STATUS(hyuv2rgb->YUV2RGBx) & RGB_FIFO_EMPTY))
{
if (lu32_RGBCount < fu32_Pixels)
{
switch (hyuv2rgb->Init.RGB_Format)
{
case RGB_FORMAT_888: *hyuv2rgb->u_RGBData.p_u32++ = hyuv2rgb->YUV2RGBx->RGB_DATA; break;
case RGB_FORMAT_565: *hyuv2rgb->u_RGBData.p_u16++ = hyuv2rgb->YUV2RGBx->RGB_DATA; break;
case RGB_FORMAT_332: *hyuv2rgb->u_RGBData.p_u8++ = hyuv2rgb->YUV2RGBx->RGB_DATA; break;
default:break;
}
lu32_RGBCount++;
if (lu32_RGBCount >= fu32_Pixels)
break;
}
}
if (!(__YUV2RGB_GET_INT_RAW_STATUS(hyuv2rgb->YUV2RGBx) & YUV_FIFO_FULL))
{
if (lu32_YUVCount < fu32_Pixels)
{
switch (hyuv2rgb->Init.YUV_Format)
{
case YUV_FORMAT_444: hyuv2rgb->YUV2RGBx->YUV_DATA = *hyuv2rgb->u_YUVData.p_u32++; break;
case YUV_FORMAT_422: hyuv2rgb->YUV2RGBx->YUV_DATA = *hyuv2rgb->u_YUVData.p_u16++; break;
default: break;
}
lu32_YUVCount++;
}
}
}
}
/************************************************************************************
* @fn yuv2rgb_convert_IT
*
* @brief YUV to RGB convert in interrupt mode.
*
* @param hyuv2rgb: YUV2RGB handle.
*/
void yuv2rgb_convert_IT(YUV2RGB_HandleTypeDef *hyuv2rgb, void *YUV_Buffer, void *RGB_Buffer, uint32_t fu32_Pixels)
{
hyuv2rgb->u_YUVData.p_data = YUV_Buffer;
hyuv2rgb->u_RGBData.p_data = RGB_Buffer;
hyuv2rgb->u32_RGBCount = 0;
hyuv2rgb->u32_YUVCount = 0;
hyuv2rgb->u32_Pixels = fu32_Pixels;
hyuv2rgb->b_CovertBusy = true;
__YUV2RGB_YUV_FIFO_ALMOST_EMPTY_LEVEL(hyuv2rgb->YUV2RGBx, 6);
__YUV2RGB_RGB_FIFO_ALMOST_FULL_LEVEL(hyuv2rgb->YUV2RGBx, 1);
__YUV2RGB_INT_ENABLE(hyuv2rgb->YUV2RGBx, YUV_FIFO_ALMOST_EMPTY);
__YUV2RGB_INT_ENABLE(hyuv2rgb->YUV2RGBx, RGB_FIFO_ALMOST_FULL);
}

View File

@ -0,0 +1,977 @@
/*
******************************************************************************
* @file usb_audio.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief This file provides the high layer firmware functions to manage the
* USB Audio Device.
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
*
******************************************************************************
*/
#include "usb_audio.h"
uint8_t gu8_Respond[5];
uint8_t gu8_AudioReport;
uint32_t gu32_BitWidthSpeaker;
uint32_t gu32_BitWidthMic;
uint32_t gu32_PacketLengthSpeaker;
uint32_t gu32_PacketLengthMic;
uint32_t gu32_SamplingFreqSpeaker;
uint32_t gu32_SamplingFreqMic;
uint16_t gu16_VolumeSpeaker = USB_AUDIO_VOLUME_MAX;
uint16_t gu16_VolumeMic = USB_AUDIO_VOLUME_MAX;
uint8_t gu8_MuteSpeaker = 0x00;
uint8_t gu8_MuteMic = 0x00;
/* Audio Set Control */
typedef enum
{
AUDIO_SET_VOL_SPEAKER, /* set Speaker Volume */
AUDIO_SET_VOL_MIC, /* set Microphone Volume */
AUDIO_SET_MUTE_SPEAKER, /* set Speaker Mute */
AUDIO_SET_MUTE_MIC, /* set Microphone Mute */
AUDIO_SET_SAMPLING_SPEAKER, /* set Speaker Sampling Frequency */
AUDIO_SET_SAMPLING_MIC, /* set Microphone Sampling Frequency */
}Audio_SetControl;
Audio_SetControl ge_CTLIndex;
/* USB Standard Device Descriptor */
const uint8_t USB_Audio_DeviceDesc[] =
{
0x12, /* bLength */
0x01, /* bDescriptorType */
0x00, /* bcdUSB */
0x02,
0x00, /* bDeviceClass */
0x00, /* bDeviceSubClass */
0x00, /* bDeviceProtocol */
0x40, /* bMaxPacketSize */
0xA4, /* idVendor */
0xA5, /* idVendor */
0xA6, /* idProduct */
0xA7, /* idProduct */
0x00, /* bcdDevice rel. 2.00 */
0x02,
0x01, /* Index of manufacturer string */
0x02, /* Index of product string */
0x03, /* Index of serial number string */
0x01, /* bNumConfigurations */
};
/* USB Standard Configuration Descriptor */
const uint8_t USB_Audio_ConfigurationDesc[] =
{
/* Configuration Descriptor */
0x09, /* bLength */
0x02, /* bDescriptorType */
0x1C, /* wTotalLength */
0x01,
0x04, /* bNumInterfaces */
0x01, /* bConfigurationValue */
0x00, /* iConfiguration */
0xC0, /* bmAttributes */
0x32, /* bMaxPower */
/* Audio Interface_0 Descriptor */
0x09, /* bLength */
0x04, /* bDescriptorType */
0x00, /* bInterfaceNumber */
0x00, /* bAlternateSetting */
0x00, /* bNumEndpoints */
0x01, /* bInterfaceClass: Audio */
0x01, /* bInterfaceSubClass: Audio Control */
0x00, /* bInterfaceProtocol */
0x00, /* iInterface */
/* Audio Control Interface Header Descriptor */
0x0A, /* bLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x01, /* bDescriptorSubtype: HEADER descriptor subtype */
0x00, /* bcdADC */
0x01,
0x4C, /* wTotalLength */
0x00,
0x02, /* bInCollection */
0x01, /* baInterfaceNr(1) */
0x02, /* baInterfaceNr(2) */
/* Audio Control Input Terminal Descriptor */
0x0C, /* bLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x02, /* bDescriptorSubtype: INPUT_TERMINAL */
0x01, /* bTerminalID */
0x01, /* wTerminalType: USB streaming */
0x01,
0x00, /* bAssocTerminal */
0x02, /* bNrChannels */
0x03, /* wChannelConfig */
0x00,
0x00, /* iChannelNames */
0x00, /* iTerminal */
/* Audio Control Feature Unit Descriptor */
0x0D, /* bLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x06, /* bDescriptorSubtype: FEATURE_UNIT */
0x02, /* bUnitID */
0x01, /* bSourceID */
0x02, /* bControlSize */
0x01,
0x00,
0x02,
0x00,
0x02,
0x00,
0x00, /* iFeature */
/* Audio Control Output Terminal Descriptor */
0x09, /* bLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x03, /* bDescriptorSubtype: OUTPUT_TERMINAL */
0x03, /* bTerminalID */
0x02, /* wTerminalType: Headphones */
0x03,
0x00, /* bAssocTerminal */
0x02, /* bSourceID */
0x00, /* iTerminal */
/* Audio Control Input Terminal Descriptor */
0x0C, /* bLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x02, /* bDescriptorSubtype: INPUT_TERMINAL */
0x04, /* bTerminalID */
0x01, /* wTerminalType: Microphone */
0x02,
0x00, /* bAssocTerminal */
0x01, /* bNrChannels */
0x04, /* wChannelConfig */
0x00,
0x00, /* iChannelNames */
0x00, /* iTerminal */
/* Audio Control Feature Unit Descriptor */
0x0B, /* bLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x06, /* bDescriptorSubtype: FEATURE_UNIT */
0x05, /* bUnitID */
0x04, /* bSourceID */
0x02, /* bControlSize */
0x01,
0x00,
0x02,
0x00,
0x00, /* iFeature */
/* Audio Control Output Terminal Descriptor */
0x09, /* bLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x03, /* bDescriptorSubtype: OUTPUT_TERMINAL */
0x06, /* bTerminalID */
0x01, /* wTerminalType: USB streaming */
0x01,
0x00, /* bAssocTerminal */
0x05, /* bSourceID */
0x00, /* iTerminal */
/* Audio Interface_1/0 Descriptor */
0x09, /* bLength */
0x04, /* bDescriptorType */
0x01, /* bInterfaceNumber */
0x00, /* bAlternateSetting */
0x00, /* bNumEndpoints */
0x01, /* bInterfaceClass: Audio */
0x02, /* bInterfaceSubClass: Audio Streaming */
0x00, /* bInterfaceProtocol */
0x00, /* iConfiguration */
/* HID Interface_1/1 Descriptor */
0x09, /* bLength */
0x04, /* bDescriptorType */
0x01, /* bInterfaceNumber */
0x01, /* bAlternateSetting */
0x01, /* bNumEndpoints */
0x01, /* bInterfaceClass: Audio */
0x02, /* bInterfaceSubClass: Audio Streaming */
0x00, /* bInterfaceProtocol */
0x00, /* iConfiguration */
/* Class-Specific AS Interface Descriptor */
0x07, /* bLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x01, /* bDescriptorSubtype: AS_GENERAL */
0x01, /* bTerminalLink */
0x00, /* bDelay */
0x01, /* wFormatTag: PCM */
0x00,
/* Class-Specific AS Format Type Descriptor */
0x14, /* bLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x02, /* bDescriptorSubtype: FORMAT_TYPE */
0x01, /* bFormatType: FORMAT_TYPE_I */
0x02, /* bNrChannels */
2, /* bSubframeSize: 2-Byte */
16, /* bBitResolution: 16-bit */
0x04, /* bSamFreqType */
0x80, /* tSamFreq [1] : 16K */
0x3E,
0x00,
0x00, /* tSamFreq [2] : 32K */
0x7D,
0x00,
0x80, /* tSamFreq [3] : 48K */
0xBB,
0x00,
0x00, /* tSamFreq [4] : 96K */
0x77,
0x01,
/* Endpoint 2 Descriptor */
0x09, /* bLength */
0x05, /* bDescriptorType */
0x02, /* bEndpointAddress: OUT 2 */
0x0D, /* bmAttributes: Isochronous */
0x00, /* wMaxPacketSize: 512byte */
0x02,
0x01, /* bInterval */
0x00, /* bRefresh */
0x00, /* bSynchAddress */
/* Audio Streaming Isochronous Audio Data Endpoint Descriptor */
0x07, /* bLength */
0x25, /* bDescriptorType: CS_ENDPOINT */
0x01, /* bDescriptorSubtype: EP_GENERAL */
0x01, /* bmAttributes */
0x01, /* bLockDelayUnits */
0x01, /* wLockDelay */
0x00, /* */
/* HID Interface_1/2 Descriptor */
0x09, /* bLength */
0x04, /* bDescriptorType */
0x01, /* bInterfaceNumber */
0x02, /* bAlternateSetting */
0x01, /* bNumEndpoints */
0x01, /* bInterfaceClass: Audio */
0x02, /* bInterfaceSubClass: Audio Streaming */
0x00, /* bInterfaceProtocol */
0x00, /* iConfiguration */
/* Class-Specific AS Interface Descriptor */
0x07, /* bLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x01, /* bDescriptorSubtype: AS_GENERAL */
0x01, /* bTerminalLink */
0x00, /* bDelay */
0x01, /* wFormatTag: PCM */
0x00,
/* Class-Specific AS Format Type Descriptor */
0x0B, /* bLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x02, /* bDescriptorSubtype: FORMAT_TYPE */
0x01, /* bFormatType: FORMAT_TYPE_I */
0x02, /* bNrChannels */
3, /* bSubframeSize: 3-Byte */
24, /* bBitResolution: 24-bit */
0x04, /* bSamFreqType */
0x80, /* tSamFreq [1] : 48K */
0xBB,
0x00,
/* Endpoint 2 Descriptor */
0x09, /* bLength */
0x05, /* bDescriptorType */
0x02, /* bEndpointAddress: OUT 2 */
0x0D, /* bmAttributes: Isochronous */
0x00, /* wMaxPacketSize: 512byte */
0x02,
0x01, /* bInterval */
0x00, /* bRefresh */
0x00, /* bSynchAddress */
/* Audio Streaming Isochronous Audio Data Endpoint Descriptor */
0x07, /* bLength */
0x25, /* bDescriptorType: CS_ENDPOINT */
0x01, /* bDescriptorSubtype: EP_GENERAL */
0x01, /* bmAttributes */
0x01, /* bLockDelayUnits */
0x01, /* wLockDelay */
0x00, /* */
/* Audio Interface_2/0 Descriptor */
0x09, /* bLength */
0x04, /* bDescriptorType */
0x02, /* bInterfaceNumber */
0x00, /* bAlternateSetting */
0x00, /* bNumEndpoints */
0x01, /* bInterfaceClass: Audio */
0x02, /* bInterfaceSubClass: Audio Streaming */
0x00, /* bInterfaceProtocol */
0x00, /* iConfiguration */
/* Audio Interface_2/1 Descriptor */
0x09, /* bLength */
0x04, /* bDescriptorType */
0x02, /* bInterfaceNumber */
0x01, /* bAlternateSetting */
0x01, /* bNumEndpoints */
0x01, /* bInterfaceClass: Audio */
0x02, /* bInterfaceSubClass: Audio Streaming */
0x00, /* bInterfaceProtocol */
0x00, /* iConfiguration */
/* Class-Specific AS Interface Descriptor */
0x07, /* bLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x01, /* bDescriptorSubtype: AS_GENERAL */
0x06, /* bTerminalLink */
0x00, /* bDelay */
0x01, /* wFormatTag: PCM */
0x00,
/* Class-Specific AS Format Type Descriptor */
0x14, /* bLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x02, /* bDescriptorSubtype: FORMAT_TYPE */
0x01, /* bFormatType: FORMAT_TYPE_I */
0x01, /* bNrChannels */
0x02, /* bSubframeSize */
0x10, /* bBitResolution */
0x04, /* bSamFreqType */
0x80, /* tSamFreq [1] */
0x3E,
0x00,
0x00, /* tSamFreq [2] */
0x7D,
0x00,
0x80, /* tSamFreq [3] */
0xBB,
0x00,
0x00, /* tSamFreq [4] */
0x77,
0x01,
/* Endpoint 1 Descriptor */
0x09, /* bLength */
0x05, /* bDescriptorType */
0x81, /* bEndpointAddress: IN 1 */
0x0D, /* bmAttributes: Isochronous */
0x00, /* wMaxPacketSize: 256byte */
0x01,
0x01, /* bInterval */
0x00, /* bRefresh */
0x00, /* bSynchAddress */
/* Audio Streaming Isochronous Audio Data Endpoint Descriptor */
0x07, /* bLength */
0x25, /* bDescriptorType: CS_ENDPOINT */
0x01, /* bDescriptorSubtype: EP_GENERAL */
0x00, /* bmAttributes */
0x01, /* bLockDelayUnits */
0x01, /* wLockDelay */
0x00,
/* HID Interface_3/0 Descriptor */
0x09, /* bLength */
0x04, /* bDescriptorType */
0x03, /* bInterfaceNumber */
0x00, /* bAlternateSetting */
0x01, /* bNumEndpoints */
0x03, /* bInterfaceClass: HID */
0x00, /* bInterfaceSubClass */
0x00, /* bInterfaceProtocol */
0x00, /* iConfiguration */
/* HID Descriptor */
0x09, /* bLength */
0x21, /* bDescriptorType: HID */
0x10, /* bcdHID: 1.10 */
0x01,
0x21, /* bCountryCode */
0x01, /* bNumDescriptors */
0x22, /* bDescriptorType: Report */
0x2A, /* wDescriptorLength */
0x00,
/* Endpoint 2 Descriptor */
0x07, /* bLength */
0x05, /* bDescriptorType */
0x82, /* bEndpointAddress: IN 2 */
0x03, /* bmAttributes: Interrupt */
0x02, /* wMaxPacketSize: 2byte */
0x00,
0x14, /* bInterval: 20ms */
};
/* USB Standard Manufacture Descriptor */
const uint8_t USB_Audio_ManufactureDesc[] =
{
0x12, /* bLength */
0x03, /* bDescriptorType */
'F', 0x00, /* BString */
'R', 0x00,
'E', 0x00,
'Q', 0x00,
'C', 0x00,
'H', 0x00,
'I', 0x00,
'P', 0x00,
};
/* USB Standard Product Descriptor */
const uint8_t USB_Audio_ProductDesc[] =
{
0x1E, /* bLength */
0x03, /* bDescriptorType */
'F', 0x00, /* BString */
'R', 0x00,
'E', 0x00,
'Q', 0x00,
'C', 0x00,
'H', 0x00,
'I', 0x00,
'P', 0x00,
'-', 0x00,
'A', 0x00,
'u', 0x00,
'd', 0x00,
'i', 0x00,
'o', 0x00,
};
/* USB Standard SerialNumber Descriptor */
const uint8_t USB_Audio_SerialNumberDesc[] =
{
0x1E, /* bLength */
0x03, /* bDescriptorType */
'2', 0x00, /* BString */
'0', 0x00,
'2', 0x00,
'1', 0x00,
'-', 0x00,
'1', 0x00,
'0', 0x00,
'0', 0x00,
'1', 0x00,
'-', 0x00,
'B', 0x00,
'1', 0x00,
'3', 0x00,
'6', 0x00,
};
/* USB Standard LanuageID Descriptor */
const uint8_t USB_Audio_LanuageIDDesc[] =
{
0x04, /* bLength */
0x03, /* bDescriptorType */
0x09, /* BString */
0x04,
};
/* HID device report Descriptor */
uint8_t USB_HID_Audio_ReportDesc[] =
{
0x2A, /* Length */
0x06, 0x0C, 0x00,
0x09, 0x01,
0xA1, 0x01,
0x25, 0x01,
0x15, 0x00,
0x0A, 0xE2, 0x00, /* Mute */
0x0A, 0xEA, 0x00, /* Volume Decrement */
0x0A, 0xE9, 0x00, /* Volume Increment */
0x0A, 0xB6, 0x00, /* Scan Previous Track */
0x0A, 0xCD, 0x00, /* Play/Pause */
0x0A, 0xB5, 0x00, /* Scan Next Track */
0x0A, 0xB7, 0x00, /* STOP */
0x0A, 0xB7, 0x00, /* STOP */
0x75, 0x01,
0x95, 0x08,
0x81, 0x02,
0xC0,
};
/*********************************************************************
* @fn usb_hid_set_Audio_report
*
* @brief set report
*/
void usb_hid_set_Audio_report(uint8_t fu8_Value)
{
gu8_AudioReport = fu8_Value;
}
/*********************************************************************
* @fn usb_hid_send_Audio_report
*
* @brief set report
*/
int usb_hid_send_Audio_report(void)
{
usb_selecet_endpoint(ENDPOINT_2);
if (usb_Endpoints_GET_TxPktRdy() == false)
{
usb_write_fifo(ENDPOINT_2, &gu8_AudioReport, 1);
usb_Endpoints_SET_TxPktRdy();
}
else
{
return -1;
}
return 0;
}
/*********************************************************************
* @fn usb_Audio_SetControl
*
* @brief Set Speaker volume, Set microphone volume
* Set Speaker Mute, Set microphone Mute
* Set Speaker sampling frequency, Set microphone sampling frequency
*/
static void usb_Audio_SetControl(void)
{
uint8_t lu8_RxCount;
lu8_RxCount = usb_Endpoint0_get_RxCount();
switch (ge_CTLIndex)
{
case AUDIO_SET_VOL_SPEAKER: usb_read_fifo(ENDPOINT_0, (uint8_t *)&gu16_VolumeSpeaker, lu8_RxCount); break;
case AUDIO_SET_VOL_MIC: usb_read_fifo(ENDPOINT_0, (uint8_t *)&gu16_VolumeMic, lu8_RxCount); break;
case AUDIO_SET_MUTE_SPEAKER: usb_read_fifo(ENDPOINT_0, (uint8_t *)&gu8_MuteSpeaker, lu8_RxCount); break;
case AUDIO_SET_MUTE_MIC: usb_read_fifo(ENDPOINT_0, (uint8_t *)&gu8_MuteMic, lu8_RxCount); break;
case AUDIO_SET_SAMPLING_SPEAKER:
{
usb_read_fifo(ENDPOINT_0, (uint8_t *)&gu32_SamplingFreqSpeaker, lu8_RxCount);
void usb_Audio_ChangeSamplingRate_callback(uint8_t Index);
usb_Audio_ChangeSamplingRate_callback(AUDIO_SET_SAMPLING_SPEAKER);
}break;
case AUDIO_SET_SAMPLING_MIC:
{
usb_read_fifo(ENDPOINT_0, (uint8_t *)&gu32_SamplingFreqMic, lu8_RxCount);
void usb_Audio_ChangeSamplingRate_callback(uint8_t Index);
usb_Audio_ChangeSamplingRate_callback(AUDIO_SET_SAMPLING_MIC);
}break;
default: break;
}
usb_Endpoint0_FlushFIFO();
Endpoint_0_DataOut_Handler = NULL;
}
/*********************************************************************
* @fn usb_Audio_ClassRequest_Handler
*
* @brief Audio Class Request Handler
*
* @param None.
* @return None.
*/
static void usb_Audio_ClassRequest_Handler(usb_StandardRequest_t* pStandardRequest, usb_ReturnData_t* pReturnData)
{
if (pStandardRequest->bmRequestType & RECIPIENT_INTERFACE)
{
switch (pStandardRequest->bRequest)
{
case GET_CUR:
{
if (pStandardRequest->wValue[1] == MUTE_CONTROL)
{
if (pStandardRequest->wIndex[1] == 0x02)
{
gu8_Respond[0] = gu8_MuteSpeaker;
}
else if (pStandardRequest->wIndex[1] == 0x05)
{
gu8_Respond[0] = gu8_MuteMic;
}
pReturnData->DataBuffer = gu8_Respond;
pReturnData->DataLength = 1;
}
else if (pStandardRequest->wValue[1] == VOLUME_CONTROL)
{
if (pStandardRequest->wIndex[1] == 0x02)
{
gu8_Respond[0] = gu16_VolumeSpeaker & 0xFF;
gu8_Respond[1] = gu16_VolumeSpeaker >> 8 & 0xFF;
}
else if (pStandardRequest->wIndex[1] == 0x05)
{
gu8_Respond[0] = gu16_VolumeMic & 0xFF;
gu8_Respond[1] = gu16_VolumeMic >> 8 & 0xFF;
}
pReturnData->DataBuffer = gu8_Respond;
pReturnData->DataLength = 2;
}
}break;
case GET_MIN:
{
if (pStandardRequest->wValue[1] == VOLUME_CONTROL)
{
gu8_Respond[0] = 0x00;
gu8_Respond[1] = 0x00;
pReturnData->DataBuffer = gu8_Respond;
pReturnData->DataLength = 2;
}
}break;
case GET_MAX:
{
if (pStandardRequest->wValue[1] == VOLUME_CONTROL)
{
gu8_Respond[0] = USB_AUDIO_VOLUME_MAX;
gu8_Respond[1] = 0x00;
pReturnData->DataBuffer = gu8_Respond;
pReturnData->DataLength = 2;
}
}break;
case GET_RES:
{
if (pStandardRequest->wValue[1] == VOLUME_CONTROL)
{
gu8_Respond[0] = 0x01;
gu8_Respond[1] = 0x00;
pReturnData->DataBuffer = gu8_Respond;
pReturnData->DataLength = 2;
}
}break;
case SET_CUR:
{
if (pStandardRequest->wValue[1] == VOLUME_CONTROL)
{
/* Speaker */
if (pStandardRequest->wIndex[1] == 0x02)
{
ge_CTLIndex = AUDIO_SET_VOL_SPEAKER;
}
/* microphone */
else if (pStandardRequest->wIndex[1] == 0x05)
{
ge_CTLIndex = AUDIO_SET_VOL_MIC;
}
Endpoint_0_DataOut_Handler = usb_Audio_SetControl;
}
else if (pStandardRequest->wValue[1] == MUTE_CONTROL)
{
/* Speaker */
if (pStandardRequest->wIndex[1] == 0x02)
{
ge_CTLIndex = AUDIO_SET_MUTE_SPEAKER;
}
/* microphone */
else if (pStandardRequest->wIndex[1] == 0x05)
{
ge_CTLIndex = AUDIO_SET_MUTE_MIC;
}
Endpoint_0_DataOut_Handler = usb_Audio_SetControl;
}
}
default: break;
}
}
else if (pStandardRequest->bmRequestType & RECIPIENT_ENDPOINT)
{
switch (pStandardRequest->bRequest)
{
case SET_CUR:
{
if (pStandardRequest->wValue[1] == SAMPLING_FREQ_CONTROL)
{
/* IN Endpoint */
if (pStandardRequest->wIndex[0] == 0x81)
{
ge_CTLIndex = AUDIO_SET_SAMPLING_MIC;
}
/* OUT Endpoint */
else if (pStandardRequest->wIndex[0] == 0x02)
{
ge_CTLIndex = AUDIO_SET_SAMPLING_SPEAKER;
}
Endpoint_0_DataOut_Handler = usb_Audio_SetControl;
}
}break;
default: break;
}
}
}
/*********************************************************************
* @fn usb_hid_StandardClassRequest_Handler
*
* @brief HID Standard Class Request Handler
*
* @param None.
* @return None.
*/
static void usb_hid_StandardClassRequest_Handler(usb_StandardRequest_t* pStandardRequest, usb_ReturnData_t* pReturnData)
{
switch (pStandardRequest->wValue[1])
{
case DESCRIPTOR_HID_REPORT:
{
if (pStandardRequest->wIndex[0] == 3){
pReturnData->DataLength = USB_HID_Audio_ReportDesc[0];
pReturnData->DataBuffer = &USB_HID_Audio_ReportDesc[1];
}
}break;
default: break;
}
}
extern volatile uint16_t MIC_Buffer[960];
extern volatile uint32_t MIC_Packet;
extern volatile uint32_t MIC_RxCount;
extern volatile uint32_t MIC_TxCount;
extern volatile bool MIC_Start;
extern volatile uint32_t Speaker_Buffer[192 * 2 * 10];
extern volatile uint32_t Speaker_Packet;
extern volatile uint32_t Speaker_RxCount;
extern volatile uint32_t Speaker_TxCount;
extern volatile bool Speaker_Start;
/*********************************************************************
* @fn usb_Audio_Endpoints_Handler
*
* @brief Audio Endpoints Handler
*
*/
void usb_Audio_Endpoints_Handler(uint8_t RxStatus, uint8_t TxStatus)
{
uint32_t lu32_RxCount;
/* ENDPOINT_2 Rx */
if (RxStatus & 0x04)
{
/* Receive audio playback data */
usb_selecet_endpoint(ENDPOINT_2);
if (usb_Endpoints_GET_RxPktRdy())
{
switch (gu32_BitWidthSpeaker)
{
case USB_AUDIO_DATA_WIDTH_16BIT:
{
lu32_RxCount = usb_Endpoints_get_RxCount_16bit();
usb_read_fifo(ENDPOINT_2, (uint8_t *)&Speaker_Buffer[gu32_PacketLengthSpeaker * Speaker_Packet], lu32_RxCount);
usb_Endpoints_FlushRxFIFO();
Speaker_Packet += 1;
if (Speaker_Packet >= 10)
{
Speaker_Packet = 0;
}
Speaker_RxCount = Speaker_Packet * gu32_PacketLengthSpeaker;
if (Speaker_Packet >= 5 && Speaker_Start == false)
{
Speaker_Start = true;
}
}break;
case USB_AUDIO_DATA_WIDTH_24BIT:
{
lu32_RxCount = usb_Endpoints_get_RxCount_16bit();
uint32_t BufferIndex = (gu32_PacketLengthSpeaker * 2) * Speaker_Packet;
for(int i = 0; i < lu32_RxCount/3; i++)
usb_read_fifo(ENDPOINT_2, (uint8_t *)&Speaker_Buffer[BufferIndex + i], 3);
usb_Endpoints_FlushRxFIFO();
Speaker_Packet += 1;
if (Speaker_Packet >= 10)
{
Speaker_Packet = 0;
}
Speaker_RxCount = Speaker_Packet * (gu32_PacketLengthSpeaker * 2);
if (Speaker_Packet >= 5 && Speaker_Start == false)
{
Speaker_Start = true;
}
}break;
default:break;
}
}
}
/* ENDPOINT_1 Tx */
if (TxStatus & 0x02)
{
/* Send microphone data to Host */
if (MIC_Start)
{
usb_selecet_endpoint(ENDPOINT_1);
if (usb_Endpoints_GET_TxPktRdy() == false)
{
usb_write_fifo(ENDPOINT_1, (uint8_t *)&MIC_Buffer[MIC_TxCount], gu32_PacketLengthMic*2);
usb_Endpoints_SET_TxPktRdy();
MIC_TxCount += gu32_PacketLengthMic;
if (MIC_TxCount >= gu32_PacketLengthMic*10)
{
MIC_TxCount = 0;
}
}
}
}
}
void usb_Audio_InterfaceAlternateSet_callback(uint8_t Interface)
{
switch (Interface)
{
/* Speaker Interface */
case 1:
{
/* Change the data bit width */
if (usbdev_get_interface_alternate_num(1) == 1)
gu32_BitWidthSpeaker = USB_AUDIO_DATA_WIDTH_16BIT;
else if (usbdev_get_interface_alternate_num(1) == 2)
gu32_BitWidthSpeaker = USB_AUDIO_DATA_WIDTH_24BIT;
}break;
default:break;
}
}
void usb_Audio_ChangeSamplingRate_callback(uint8_t Index)
{
switch (Index)
{
/* Change the Speaker sampling rate */
case AUDIO_SET_SAMPLING_SPEAKER:
{
gu32_PacketLengthSpeaker = gu32_SamplingFreqSpeaker/1000;
}break;
/* Change the Mic sampling rate */
case AUDIO_SET_SAMPLING_MIC:
{
gu32_PacketLengthMic = gu32_SamplingFreqMic/1000;
}break;
default:break;
}
}
uint32_t usb_Audio_get_Speaker_Packet_Length(void)
{
return gu32_PacketLengthSpeaker;
}
uint32_t usb_Audio_get_Mic_Packet_Length(void)
{
return gu32_PacketLengthMic;
}
uint32_t usb_Audio_get_Speaker_Bit_Width(void)
{
return gu32_BitWidthSpeaker;
}
uint32_t usb_Audio_get_Mic_Bit_Width(void)
{
return gu32_BitWidthMic;
}
uint32_t usb_Audio_get_Speaker_Mute_status(void)
{
return gu8_MuteSpeaker;
}
uint32_t usb_Audio_get_Mic_Mute_status(void)
{
return gu8_MuteMic;
}
uint32_t usb_Audio_get_Speaker_Volume(void)
{
return gu16_VolumeSpeaker;
}
uint32_t usb_Audio_get_Mic_Volume(void)
{
return gu16_VolumeMic;
}
uint32_t usb_Audio_get_Speaker_SamplingFreq(void)
{
return gu32_SamplingFreqSpeaker;
}
uint32_t usb_Audio_get_Mic_SamplingFreq(void)
{
return gu32_SamplingFreqMic;
}
/*********************************************************************
* @fn usb_audio_init
*
* @brief audio device parameter initialization
*
* @param None.
* @return None.
*/
void usb_audio_init(void)
{
/* Initialize the relevant pointer */
usbdev_get_dev_desc((uint8_t *)USB_Audio_DeviceDesc);
usbdev_get_config_desc((uint8_t *)USB_Audio_ConfigurationDesc);
usbdev_get_string_Manufacture((uint8_t *)USB_Audio_ManufactureDesc);
usbdev_get_string_Product((uint8_t *)USB_Audio_ProductDesc);
usbdev_get_string_SerialNumber((uint8_t *)USB_Audio_SerialNumberDesc);
usbdev_get_string_LanuageID((uint8_t *)USB_Audio_LanuageIDDesc);
Endpoint_0_StandardClassRequest_Handler = usb_hid_StandardClassRequest_Handler;
Endpoint_0_ClassRequest_Handler = usb_Audio_ClassRequest_Handler;
Endpoints_Handler = usb_Audio_Endpoints_Handler;
USB_InterfaceAlternateSet_callback = usb_Audio_InterfaceAlternateSet_callback;
USB_Reset_Handler = usb_audio_init;
/* config data endpoint fifo */
usb_selecet_endpoint(ENDPOINT_1);
usb_TxSyncEndpoint_enable();
usb_endpoint_Txfifo_config(64/8, 5); /* 256 Byte, 64 ~ 319 */
usb_TxMaxP_set(256/8);
usb_selecet_endpoint(ENDPOINT_2);
usb_RxSyncEndpoint_enable();
usb_endpoint_Rxfifo_config(320/8, 6); /* 512 Byte, 320 ~ 831 */
usb_RxMaxP_set(512/8);
usb_endpoint_Txfifo_config(832/8, 1); /* 16 Byte, 832 ~ 464 */
usb_TxMaxP_set(16/8);
usb_TxInt_Enable(ENDPOINT_1);
usb_RxInt_Enable(ENDPOINT_2);
}

View File

@ -0,0 +1,518 @@
/*
******************************************************************************
* @file usb_cdc.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief This file provides the high layer firmware functions to manage the
* USB CDC Class.(Communication Device Class)
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
*
******************************************************************************
* How to use, for example:
*
* int main(void)
* {
* NVIC_ClearPendingIRQ(USBMCU_IRQn);
* NVIC_SetPriority(USBMCU_IRQn, 0);
* NVIC_EnableIRQ(USBMCU_IRQn);
*
* usb_device_init();
* usb_cdc_init();
*
* // Wait for other initialization of the MCU
* while(1)
* {
* usb_cdc_serialReceive();
* }
* }
******************************************************************************
*/
#include "usb_cdc.h"
extern UART_HandleTypeDef Uart_CDC_handle;
#define CDC_MAX_PACK (64) /* Fixed 64 bytes */
#define CDC_MAX_IN_PACK (1024) /* IN Endpoint max pack buffer */
volatile bool COM_Activate = false;
volatile uint32_t Tx_Count = 0;
volatile uint32_t Tx_Total = 0;
uint8_t RxBuffer[CDC_MAX_PACK];
uint8_t TxBuffer[CDC_MAX_IN_PACK];
USBD_CDC_LineCodingTypeDef LineCoding;
/* USB Standard Device Descriptor */
const uint8_t USB_CDC_DeviceDesc[] =
{
0x12, /* bLength */
0x01, /* bDescriptorType */
0x00, /* bcdUSB */
0x02,
0x02, /* bDeviceClass */
0x02, /* bDeviceSubClass */
0x00, /* bDeviceProtocol */
0x40, /* bMaxPacketSize */
0xAA, /* idVendor */
0xFF, /* idVendor */
0x55, /* idProduct */
0x55, /* idProduct */
0x00, /* bcdDevice rel. 2.00 */
0x20,
0x01, /* Index of manufacturer string */
0x02, /* Index of product string */
0x03, /* Index of serial number string */
0x01, /* bNumConfigurations */
};
/* USB Standard Configuration Descriptor */
const uint8_t USB_CDC_ConfigurationDesc[] =
{
/* Configuration Descriptor */
0x09, /* bLength */
0x02, /* bDescriptorType */
0x43, /* wTotalLength */
0x00,
0x02, /* bNumInterfaces */
0x01, /* bConfigurationValue */
0x00, /* iConfiguration */
0xC0, /* bmAttributes */
0x32, /* bMaxPower */
/* CDC Interface Descriptor */
0x09, /* bLength */
0x04, /* bDescriptorType */
0x00, /* bInterfaceNumber */
0x00, /* bAlternateSetting */
0x01, /* bNumEndpoints */
0x02, /* bInterfaceClass */
0x02, /* bInterfaceSubClass */
0x01, /* bInterfaceProtocol */
0x00, /* iConfiguration */
/* Header Functional Descriptor */
0x05, /* bLength: Endpoint Descriptor size */
0x24, /* bDescriptorType: CS_INTERFACE */
0x00, /* bDescriptorSubtype: Header Func Desc */
0x10, /* bcdCDC: spec release number */
0x01,
/* Call Management Functional Descriptor */
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x01, /* bDescriptorSubtype: Call Management Func Desc */
0x00, /* bmCapabilities: D0+D1 */
0x01, /* bDataInterface: 1 */
/* ACM Functional Descriptor */
0x04, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x02, /* bDescriptorSubtype: Abstract Control Management desc */
0x02, /* bmCapabilities */
/* Union Functional Descriptor */
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x06, /* bDescriptorSubtype: Union func desc */
0x00, /* bMasterInterface: Communication class interface */
0x01, /* bSlaveInterface0: Data Class Interface */
/* Endpoint 2 Descriptor */
0x07, /* bLength */
0x05, /* bDescriptorType */
0x82, /* bEndpointAddress */
0x03, /* bmAttributes: Interrupt */
0x08, /* wMaxPacketSize: */
0x00,
0x10, /* bInterval */
/* Data class interface descriptor */
0x09, /* bLength */
0x04, /* bDescriptorType */
0x01, /* bInterfaceNumber */
0x00, /* bAlternateSetting */
0x02, /* bNumEndpoints */
0x0A, /* bInterfaceClass */
0x00, /* bInterfaceSubClass */
0x00, /* bInterfaceProtocol */
0x00, /* iConfiguration */
/* Endpoint OUT Descriptor */
0x07, /* bLength */
0x05, /* bDescriptorType */
0x01, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
0x40, /* wMaxPacketSize */
0x00,
0x00, /* bInterval */
/* Endpoint IN Descriptor */
0x07, /* bLength */
0x05, /* bDescriptorType */
0x81, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
0x40, /* wMaxPacketSize */
0x00,
0x00, /* bInterval */
};
/* USB Standard Manufacture Descriptor */
const uint8_t USB_CDC_ManufactureDesc[] =
{
0x12, /* bLength */
0x03, /* bDescriptorType */
'F', 0x00, /* BString */
'R', 0x00,
'E', 0x00,
'Q', 0x00,
'C', 0x00,
'H', 0x00,
'I', 0x00,
'P', 0x00,
};
/* USB Standard Configuration Descriptor */
const uint8_t USB_CDC_ProductDesc[] =
{
0x1A, /* bLength */
0x03, /* bDescriptorType */
'F', 0x00, /* BString */
'R', 0x00,
'E', 0x00,
'Q', 0x00,
'C', 0x00,
'H', 0x00,
'I', 0x00,
'P', 0x00,
'-', 0x00,
'C', 0x00,
'O', 0x00,
'M', 0x00,
};
/* USB Standard Configuration Descriptor */
const uint8_t USB_CDC_SerialNumberDesc[] =
{
0x1E, /* bLength */
0x03, /* bDescriptorType */
'2', 0x00, /* BString */
'0', 0x00,
'2', 0x00,
'1', 0x00,
'-', 0x00,
'1', 0x00,
'0', 0x00,
'0', 0x00,
'1', 0x00,
'-', 0x00,
'A', 0x00,
'1', 0x00,
'3', 0x00,
'5', 0x00,
};
/* USB Standard Configuration Descriptor */
const uint8_t USB_CDC_LanuageIDDesc[] =
{
0x04, /* bLength */
0x03, /* bDescriptorType */
0x09, /* BString */
0x04,
};
/*********************************************************************
* @fn usb_cdc_serialReceive
*
* @brief serial port receives data
*
* @param None.
* @return None.
*/
void usb_cdc_serialReceive(void)
{
uint32_t SendLength;
while (!__UART_IS_RxFIFO_EMPTY(Uart_CDC_handle.UARTx))
{
TxBuffer[Tx_Total++] = __UART_READ_FIFO(Uart_CDC_handle.UARTx);
if (Tx_Total >= CDC_MAX_IN_PACK)
{
Tx_Total = 0;
}
}
/* have Data to be sent */
SendLength = Tx_Total >= Tx_Count ? Tx_Total - Tx_Count : CDC_MAX_IN_PACK - Tx_Count;
if (SendLength)
{
usb_selecet_endpoint(ENDPOINT_1);
if (usb_Endpoints_GET_TxPktRdy() == false)
{
if (SendLength > CDC_MAX_PACK)
{
usb_write_fifo(ENDPOINT_1, &TxBuffer[Tx_Count], CDC_MAX_PACK);
Tx_Count += CDC_MAX_PACK;
}
else
{
usb_write_fifo(ENDPOINT_1, &TxBuffer[Tx_Count], SendLength);
Tx_Count += SendLength;
}
if (Tx_Count >= CDC_MAX_IN_PACK)
{
Tx_Count = 0;
}
usb_Endpoints_SET_TxPktRdy();
}
}
}
/*********************************************************************
* @fn usb_cdc_serialSend
*
* @brief Sending data over a serial port
*
* @param None.
* @return None.
*/
static void usb_cdc_serialSend(uint8_t *Buffer, uint8_t Size)
{
while (Size--)
{
/* Tx empty */
while(__UART_IS_TxFIFO_FULL(Uart_CDC_handle.UARTx));
/* Send data */
__UART_WRITE_FIFO(Uart_CDC_handle.UARTx, *Buffer++);
}
}
/* CDC Line coding */
uint8_t CDC_LineCoding[7];
/*********************************************************************
* @fn usb_cdc_SetLineCoding
*
* @brief receive Host data and Set Line Coding
*
* @param None.
* @return None.
*/
static void usb_cdc_SetLineCoding(void)
{
USBD_CDC_LineCodingTypeDef Temp_LineCoding;
uint8_t lu8_RxCount;
uint8_t lu8_UartLine;
lu8_RxCount = usb_Endpoint0_get_RxCount();
usb_read_fifo(ENDPOINT_0, CDC_LineCoding, lu8_RxCount);
usb_Endpoint0_FlushFIFO();
Endpoint_0_DataOut_Handler = NULL;
Temp_LineCoding.dwDTERate = CDC_LineCoding[0];
Temp_LineCoding.dwDTERate |= CDC_LineCoding[1] << 8;
Temp_LineCoding.dwDTERate |= CDC_LineCoding[2] << 16;
Temp_LineCoding.dwDTERate |= CDC_LineCoding[3] << 24;
Temp_LineCoding.bCharFormat = CDC_LineCoding[4];
Temp_LineCoding.bParityType = CDC_LineCoding[5];
Temp_LineCoding.bDataBits = CDC_LineCoding[6];
/* Modify the uart configuration */
if (LineCoding.dwDTERate != Temp_LineCoding.dwDTERate)
{
LineCoding.dwDTERate = Temp_LineCoding.dwDTERate;
Uart_CDC_handle.Init.BaudRate = LineCoding.dwDTERate;
uart_config_baudRate(&Uart_CDC_handle);
}
if (LineCoding.bCharFormat != Temp_LineCoding.bCharFormat ||
LineCoding.bParityType != Temp_LineCoding.bParityType ||
LineCoding.bDataBits != Temp_LineCoding.bDataBits)
{
LineCoding.bCharFormat = Temp_LineCoding.bCharFormat;
LineCoding.bParityType = Temp_LineCoding.bParityType;
LineCoding.bDataBits = Temp_LineCoding.bDataBits;
switch (LineCoding.bDataBits)
{
case 8: lu8_UartLine = 0x03; break;
case 7: lu8_UartLine = 0x02; break;
case 6: lu8_UartLine = 0x01; break;
case 5: lu8_UartLine = 0x00; break;
default: break;
}
switch (LineCoding.bCharFormat)
{
case 0: lu8_UartLine |= 0x03; break;
case 1:
case 2: lu8_UartLine |= 1 << 2; break;
default: break;
}
switch (LineCoding.bParityType)
{
case 1: lu8_UartLine |= (1 << 3); break;
case 2: lu8_UartLine |= (1 << 3) | (1 << 4); break;
default: break;
}
__UART_SET_LINE_CTRL(Uart_CDC_handle.UARTx, lu8_UartLine);
}
}
/*********************************************************************
* @fn usb_cdc_ClassRequest_Handler
*
* @brief CDC Class Request Handler
*
* @param None.
* @return None.
*/
static void usb_cdc_ClassRequest_Handler(usb_StandardRequest_t* pStandardRequest, usb_ReturnData_t* pReturnData)
{
switch (pStandardRequest->bRequest)
{
case CDC_SET_LINE_CODING:
{
/* Host data out */
Endpoint_0_DataOut_Handler = usb_cdc_SetLineCoding;
}break;
case CDC_GET_LINE_CODING:
{
CDC_LineCoding[0] = (LineCoding.dwDTERate >> 0) & 0xFF;
CDC_LineCoding[1] = (LineCoding.dwDTERate >> 8) & 0xFF;
CDC_LineCoding[2] = (LineCoding.dwDTERate >> 16) & 0xFF;
CDC_LineCoding[3] = (LineCoding.dwDTERate >> 24) & 0xFF;
CDC_LineCoding[4] = LineCoding.bCharFormat;
CDC_LineCoding[5] = LineCoding.bParityType;
CDC_LineCoding[6] = LineCoding.bDataBits;
pReturnData->DataBuffer = CDC_LineCoding;
pReturnData->DataLength = sizeof(CDC_LineCoding);
}break;
case CDC_SET_CONTROL_LINE_STATE:
{
/* COM acitvate or inacitvate */
if (pStandardRequest->wValue[0])
{
COM_Activate = true;
}
else
{
COM_Activate = false;
}
/* clear count */
Tx_Count = 0;
Tx_Total = 0;
/* Flush FIFO */
usb_selecet_endpoint(ENDPOINT_1);
usb_Endpoints_FlushRxFIFO();
usb_Endpoints_FlushTxFIFO();
usb_selecet_endpoint(ENDPOINT_0);
}break;
default: break;
}
}
/*********************************************************************
* @fn usb_cdc_OtherEndpoints_Handler
*
* @brief CDC other Endpoints handler
*
* @param None.
* @return None.
*/
static void usb_cdc_OtherEndpoints_Handler(uint8_t RxStatus, uint8_t TxStatus)
{
uint8_t lu8_RxCount;
/* DATA OUT */
if (RxStatus & ENDPOINT_1_MASK)
{
usb_selecet_endpoint(ENDPOINT_1);
lu8_RxCount = usb_Endpoints_get_RxCount();
usb_read_fifo(ENDPOINT_1, RxBuffer, lu8_RxCount);
usb_cdc_serialSend(RxBuffer, lu8_RxCount);
usb_Endpoints_FlushRxFIFO();
}
}
/*********************************************************************
* @fn usb_cdc_init
*
* @brief CDC device parameter initialization
*
* @param None.
* @return None.
*/
void usb_cdc_init(void)
{
/* Initialize the relevant pointer */
usbdev_get_dev_desc((uint8_t *)USB_CDC_DeviceDesc);
usbdev_get_config_desc((uint8_t *)USB_CDC_ConfigurationDesc);
usbdev_get_string_Manufacture((uint8_t *)USB_CDC_ManufactureDesc);
usbdev_get_string_Product((uint8_t *)USB_CDC_ProductDesc);
usbdev_get_string_SerialNumber((uint8_t *)USB_CDC_SerialNumberDesc);
usbdev_get_string_LanuageID((uint8_t *)USB_CDC_LanuageIDDesc);
Endpoint_0_ClassRequest_Handler = usb_cdc_ClassRequest_Handler;
Endpoints_Handler = usb_cdc_OtherEndpoints_Handler;
USB_Reset_Handler = usb_cdc_init;
/* config data endpoint fifo */
usb_selecet_endpoint(ENDPOINT_1);
usb_endpoint_Txfifo_config(0x08, 3);
usb_endpoint_Rxfifo_config(0x10, 3);
usb_TxMaxP_set(8);
usb_RxMaxP_set(8);
usb_selecet_endpoint(ENDPOINT_2);
usb_endpoint_Txfifo_config(0x28, 1);
usb_RxMaxP_set(1);
/* Endpoint_1 Rx interrupt enable */
usb_RxInt_Enable(ENDPOINT_1);
LineCoding.dwDTERate = 115200;
LineCoding.bCharFormat = 0x00;
LineCoding.bParityType = 0x00;
LineCoding.bDataBits = 0x08;
}

View File

@ -0,0 +1,492 @@
/*
******************************************************************************
* @file usb_core.c
* @author FreqChip Firmware Team
* @version V1.1.0
* @date 2021
* @brief This file provides all the USB core functions.
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "usb_core.h"
/*********************************************************************
* @fn usb_device_init
*
* @brief Initializes the usb-otg as a device.
*/
void usb_device_init(void)
{
/* OTG_CID = 1 */
/* OTG_VBUS_LO = 1 */
/* OTG_VBUS_SES = 1 */
/* OTG_VBUS_VAL = 1 */
/* USB_PHY_ADP_CFG = 9 */
USB_OTG_CTRL = USB_OTG_CTRL_DEVICE_CFG;
/* Disable USB all Interrupt except endpoint0 and Bus reset*/
USB->IntrUSBE = 0x04; /* Enable Bus reset INT */
USB->IntrTx1E = 0x01; /* Enable Endpoint0 INT */
USB->IntrTx2E = 0x00;
USB->IntrRx1E = 0x00;
USB->IntrRx2E = 0x00;
}
/*********************************************************************
* @fn usb_host_init
*
* @brief Initializes the usb-otg as a host.
*/
void usb_host_init(void)
{
/* OTG_CID = 0 */
/* OTG_VBUS_LO = 1 */
/* OTG_VBUS_SES = 1 */
/* OTG_VBUS_VAL = 1 */
/* USB_PHY_ADP_CFG = 9 */
USB_OTG_CTRL = USB_OTG_CTRL_HOST_CFG;
/* Disable USB all Interrupt except endpoint0 and Bus reset*/
USB->IntrUSBE = 0x00; /* Enable Bus reset INT */
USB->IntrTx1E = 0x01; /* Enable Endpoint0 INT */
USB->IntrTx2E = 0x00;
USB->IntrRx1E = 0x00;
USB->IntrRx2E = 0x00;
}
/*********************************************************************
* @fn usb_selecet_endpoint
*
* @brief Selected Endpoint
*
* @param Endpoint : endpoint select.
* @return None.
*/
void usb_selecet_endpoint(enum_Endpoint_t Endpoint)
{
USB->Index = Endpoint;
}
/*********************************************************************
* @fn usb_get_endpoint
*
* @brief get current Endpoint
*
* @param None.
* @return current Endpoint
*/
uint8_t usb_get_endpoint(void)
{
return USB->Index;
}
/*********************************************************************
* @fn usb_set_address
*
* @brief set device address
*
* @param address : device address.
* @return None.
*/
void usb_set_address(uint8_t address)
{
USB->FAddr = address;
}
/*********************************************************************
* @fn usb_get_frame
*
* @brief get current frame number
*
* @param None.
* @return None.
*/
uint32_t usb_get_frame(void)
{
uint32_t lu32_Frame;
lu32_Frame = (uint32_t)USB->Frame2 << 8;
lu32_Frame |= (uint32_t)USB->Frame1;
return lu32_Frame;
}
/*********************************************************************
* @fn usb_TxEndpointSync_enable
*
* @brief Tx Synchronous endpoint enable
*/
void usb_TxSyncEndpoint_enable(void)
{
USB_POINTS->TxCSR2 |= USB_TXCSR2_ISO;
}
/*********************************************************************
* @fn usb_RxSyncEndpoint_enable
*
* @brief Rx Synchronous endpoint enable
*/
void usb_RxSyncEndpoint_enable(void)
{
USB_POINTS->RxCSR2 |= USB_RXCSR2_DEVICE_ISO;
}
/*********************************************************************
* @fn usb_SignalInt_Enable
*
* @brief Enable Signal detect interrupt.
*
* @param fu8_Signal : Signal select.
* @return None.
*/
void usb_SingleInt_Enable(uint8_t fu8_Signal)
{
USB->IntrUSBE |= fu8_Signal;
}
/*********************************************************************
* @fn usb_SignalInt_Disable
*
* @brief Disable Signal detect interrupt.
*
* @param fu8_Signal : Signal select.
* @return None.
*/
void usb_SignalInt_Disable(uint8_t fu8_Signal)
{
USB->IntrUSBE &= ~fu8_Signal;
}
/*********************************************************************
* @fn usb_TxInt_Enable
*
* @brief Enable transmit completion interrupt
*
* @param Endpoint : endpoint select.
* @return None.
*/
void usb_TxInt_Enable(enum_Endpoint_t Endpoint)
{
USB->IntrTx1E |= 1 << Endpoint;
}
/*********************************************************************
* @fn usb_TxInt_Disable
*
* @brief Disable transmit completion interrupt
*
* @param Endpoint : endpoint select.
* @return None.
*/
void usb_TxInt_Disable(enum_Endpoint_t Endpoint)
{
USB->IntrTx1E &= ~(1 << Endpoint);
}
/*********************************************************************
* @fn usb_RxInt_Enable
*
* @brief Enable receive completion interrupt
*
* @param Endpoint : endpoint select.
* @return None.
*/
void usb_RxInt_Enable(enum_Endpoint_t Endpoint)
{
if (Endpoint == ENDPOINT_0)
return;
USB->IntrRx1E |= 1 << Endpoint;
}
/*********************************************************************
* @fn usb_RxInt_Disable
*
* @brief Disable receive completion interrupt
*
* @param Endpoint : endpoint select.
* @return None.
*/
void usb_RxInt_Disable(enum_Endpoint_t Endpoint)
{
if (Endpoint == ENDPOINT_0)
return;
USB->IntrRx1E &= ~(1 << Endpoint);
}
/*********************************************************************
* @fn usb_endpoint_Txfifo_config
*
* @brief config Txfifo
*
* @param StartAddress: Start address of the endpoint FIFO.
* MaxPacket : Maximum packet size.
*
* @return None.
*/
void usb_endpoint_Txfifo_config(uint32_t StartAddress, uint32_t MaxPacket)
{
/* Start address of the endpoint FIFO in units of 8 TxFIFO1 bytes as follows: */
/* --------------------------------- */
/* | StartAddress | Address | */
/* | 0x00 | 0x000 | */
/* | 0x01 | 0x008 | */
/* | 0x02 | 0x010 | */
/* | ... | ... | */
/* | 0x7F | 0x3FF | */
/* --------------------------------- */
/* Maximum packet size to be allowed for */
/* --------------------------------------- */
/* | MaxPacket | Packet Size(Bytes) | */
/* | 0 | 8 | */
/* | 1 | 16 | */
/* | 2 | 32 | */
/* | 3 | 64 | */
/* | 4 | 128 | */
/* | 5 | 256 | */
/* | 6 | 512 | */
/* | 7 | 1024 | */
/* --------------------------------------- */
/* use only 7bit */
StartAddress &= 0x7F;
/* use only 3bit */
MaxPacket &= 0x7;
USB_POINTS->TxFIFO1 = StartAddress;
USB_POINTS->TxFIFO2 = MaxPacket << 5;
}
/*********************************************************************
* @fn usb_endpoint_Rxfifo_config
*
* @brief config Rxfifo
*
* @param StartAddress: Start address of the endpoint FIFO.
* MaxPacket : Maximum packet size.
*
* @return None.
*/
void usb_endpoint_Rxfifo_config(uint32_t StartAddress, uint32_t MaxPacket)
{
/*
reference usb_endpoint_Txfifo_config()
*/
/* use only 7bit */
StartAddress &= 0x7F;
/* use only 3bit */
MaxPacket &= 0x7;
USB_POINTS->RxFIFO1 = StartAddress;
USB_POINTS->RxFIFO2 = MaxPacket << 5;
}
/*********************************************************************
* @fn usb_TxMaxP_set
*
* @brief the maximum packet size for transactions through the
* currently-selected Tx endpoint
*
* @param MaxPacket: in units of 8 bytes
* @return None.
*/
void usb_TxMaxP_set(uint32_t MaxPacket)
{
/* Maximum packet size to be allowed for */
/* --------------------------------------- */
/* | MaxPacket | Packet Size(Bytes) | */
/* | 0 | 0 | */
/* | 1 | 8 | */
/* | 2 | 16 | */
/* | ... | ... | */
/* | 128 | 1024 | */
/* --------------------------------------- */
USB_POINTS->TxMaxP = MaxPacket;
}
/*********************************************************************
* @fn usb_RxMaxP_set
*
* @brief the maximum packet size for transactions through the
* currently-selected Rx endpoint
*
* @param MaxPacket: in units of 8 bytes
* @return None.
*/
void usb_RxMaxP_set(uint32_t MaxPacket)
{
/*
reference usb_TxMaxP_set()
*/
USB_POINTS->RxMaxP = MaxPacket;
}
/*********************************************************************
* @fn usb_Host_TxEndpointType
*
* @brief In host mode, the tx endpoint type select.
*
* @param fe_Type: Endpoint Type
* @return None.
*/
void usb_Host_TxEndpointType(enum_HostEndpointType_t fe_Type)
{
USB_POINTS->TxType &= ~USB_HOST_TXTYPE_PROTOCOL_MSK;
USB_POINTS->TxType |= fe_Type << USB_HOST_TXTYPE_PROTOCOL_POS;
}
/*********************************************************************
* @fn usb_Host_RxEndpointType
*
* @brief In host mode, the rx endpoint type select.
*
* @param fe_Type: Endpoint Type
* @return None.
*/
void usb_Host_RxEndpointType(enum_HostEndpointType_t fe_Type)
{
USB_POINTS->RxType &= ~USB_HOST_RXTYPE_PROTOCOL_MSK;
USB_POINTS->RxType |= fe_Type << USB_HOST_RXTYPE_PROTOCOL_POS;
}
/*********************************************************************
* @fn usb_Host_TxTargetEndpoint
*
* @brief The tx target endpoint number of the host transmit.
*
* @param fe_Type: Endpoint Type
* @return None.
*/
void usb_Host_TxTargetEndpoint(uint8_t fu8_TargetEndpointNum)
{
USB_POINTS->TxType &= ~USB_HOST_TXTYPE_TARGET_ENDP_NUM_MSK;
USB_POINTS->TxType |= fu8_TargetEndpointNum;
}
/*********************************************************************
* @fn usb_Host_RxTargetEndpoint
*
* @brief The rx target endpoint number of the host receive.
*
* @param fe_Type: Endpoint Type
* @return None.
*/
void usb_Host_RxTargetEndpoint(uint8_t fu8_TargetEndpointNum)
{
USB_POINTS->RxType &= ~USB_HOST_RXTYPE_TARGET_ENDP_NUM_MSK;
USB_POINTS->RxType |= fu8_TargetEndpointNum;
}
/*********************************************************************
* @fn usb_Host_TxPollingInterval
*
* @brief Tx Polling Interval in interrup or isochronous transfers.
* The unit is ms.(1 ~ 255)
*
* @param fu8_TxInterval: Polling interval.
* @return None.
*/
void usb_Host_TxPollingInterval(uint8_t fu8_TxInterval)
{
USB_POINTS->TxInterval = fu8_TxInterval;
}
/*********************************************************************
* @fn usb_Host_TxNAKLimit
*
* @brief Tx NAK limit in bulk transfer. NAK Limit 2 ~ 255.
* Note: A value of 0 or 1 disable the NAK timeout function.
*
* @param fu8_TxNAKLimit: Tx NAK limit value.
* @return None.
*/
void usb_Host_TxNAKLimit(uint8_t fu8_TxNAKLimit)
{
USB_POINTS->TxInterval = fu8_TxNAKLimit;
}
/*********************************************************************
* @fn usb_Host_RxPollingInterval
*
* @brief Rx Polling Interval in interrup or isochronous transfers.
* The unit is ms.(1 ~ 255)
*
* @param fu8_RxInterval: Polling interval.
* @return None.
*/
void usb_Host_RxPollingInterval(uint8_t fu8_RxInterval)
{
USB_POINTS->RxInterval = fu8_RxInterval;
}
/*********************************************************************
* @fn usb_Host_RxNAKLimit
*
* @brief Rx NAK limit in bulk transfer. NAK Limit 2 ~ 255.
* Note: A value of 0 or 1 disable the NAK timeout function.
*
* @param fu8_RxNAKLimit: Rx NAK limit value.
* @return None.
*/
void usb_Host_RxNAKLimit(uint8_t fu8_RxNAKLimit)
{
USB_POINTS->RxInterval = fu8_RxNAKLimit;
}
/*********************************************************************
* @fn usb_write_fifo
*
* @brief Write data to the endpoint fifo
*
* @param Endpoint : endpoint select.
* Buffer : transmit buffer pointer.
* Size : transmit Size.
* @return None.
*/
void usb_write_fifo(enum_Endpoint_t Endpoint, uint8_t *Buffer, uint32_t Size)
{
volatile uint8_t *fifo;
fifo = &USB_POINTS->FIFO[Endpoint * 4];
while (Size--)
{
*fifo = *Buffer++;
}
}
/*********************************************************************
* @fn usb_read_fifo
*
* @brief Reads data from the endpoint fifo
*
* @param Endpoint : endpoint select.
* Buffer : receive buffer pointer.
* Size : receive Size.
* @return None.
*/
void usb_read_fifo(enum_Endpoint_t Endpoint, uint8_t *Buffer, uint32_t Size)
{
volatile uint8_t *fifo;
fifo = &USB_POINTS->FIFO[Endpoint * 4];
while (Size--)
{
*Buffer++ = *fifo;
}
}

View File

@ -0,0 +1,620 @@
/*
******************************************************************************
* @file usb_dev.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief This file provides all the USBD device functions.
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "usb_dev.h"
uint16_t USB_Interface_Status; /* Interface status */
uint16_t USB_Device_Status = 0x0002; /* Device status */
uint16_t USB_IN_Endpoint_Status[5]; /* IN endpoints status */
uint16_t USB_OUT_Endpoint_Status[5]; /* OUT endpoints status */
uint8_t USB_Configuration; /* Configuration setting */
uint8_t USB_InterfaceAlternateSet[20]; /* Interface Alternate setting */
usb_DescriptorsTypeDef_t DevDescriptors;
usb_StandardRequest_t StandardRequest;
usb_ReturnData_t ReturnData;
void (*Endpoint_0_StandardClassRequest_Handler)(usb_StandardRequest_t* pStandardRequest, usb_ReturnData_t* pReturnData) = NULL;
void (*Endpoint_0_ClassRequest_Handler)(usb_StandardRequest_t* pStandardRequest, usb_ReturnData_t* pReturnData) = NULL;
void (*Endpoint_0_VendorRequest_Handler)(usb_StandardRequest_t* pStandardRequest, usb_ReturnData_t* pReturnData) = NULL;
void (*Endpoint_0_DataOut_Handler)(void) = NULL;
void (*Endpoints_Handler)(uint8_t RxStatus, uint8_t TxStatus) = NULL;
void (*USB_SOF_Handler)(void) = NULL;
void (*USB_Reset_Handler)(void) = NULL;
void (*USB_Resume_Handler)(void) = NULL;
void (*USB_Suspend_Handler)(void) = NULL;
void (*USB_Connect_Handler)(void) = NULL;
void (*USB_InterfaceAlternateSet_callback)(uint8_t Interface);
/*********************************************************************
* @fn usbdev_get_dev_desc
*
* @brief Get device descriptor buffer pointer.
*********************************************************************/
void usbdev_get_dev_desc(uint8_t *Descriptor)
{
DevDescriptors.DeviceDescriptor = Descriptor;
}
/*********************************************************************
* @fn usbdev_get_config_desc
*
* @brief USB full speed device Get Configuration<6F><6E>Interface<63><65>
* Endpoint Descriptor.
*********************************************************************/
void usbdev_get_config_desc(uint8_t *Descriptor)
{
DevDescriptors.ConfigurationDescriptor = Descriptor;
}
/*********************************************************************
* @fn usbdev_get_string_Manufacture
*
* @brief Get device Manufacture string Descriptor.
*********************************************************************/
void usbdev_get_string_Manufacture(uint8_t *Descriptor)
{
DevDescriptors.stringManufacture = Descriptor;
}
/*********************************************************************
* @fn usbdev_get_string_Product
*
* @brief Get device Product string Descriptor.
*********************************************************************/
void usbdev_get_string_Product(uint8_t *Descriptor)
{
DevDescriptors.stringProduct = Descriptor;
}
/*********************************************************************
* @fn usbdev_get_string_SerialNumber
*
* @brief Get device SerialNumber string Descriptor.
*********************************************************************/
void usbdev_get_string_SerialNumber(uint8_t *Descriptor)
{
DevDescriptors.stringSerialNumber = Descriptor;
}
/*********************************************************************
* @fn usbdev_get_string_LanuageID
*
* @brief Get device LanuageID string Descriptor.
*********************************************************************/
void usbdev_get_string_LanuageID(uint8_t *Descriptor)
{
DevDescriptors.stringLanuageID = Descriptor;
}
/*********************************************************************
* @fn usbdev_get_string_OS
*
* @brief Get OS String Descriptor.
*********************************************************************/
void usbdev_get_string_OS(uint8_t *Descriptor)
{
DevDescriptors.stringOS = Descriptor;
}
/*********************************************************************
* @fn usbdev_get_device_status
*
* @brief Get device_status. bit0 : self-powered
* bit1 : device remove wakeup
*********************************************************************/
uint16_t usbdev_get_device_status(void)
{
return USB_Device_Status;
}
/*********************************************************************
* @fn usbdev_get_in_endpoints_status
*
* @brief Get in endpoints status. bit0 : 0 normal
* bit0 : 1 endpoint_halt
* @param index: In endpoints index.
*********************************************************************/
uint16_t usbdev_get_in_endpoints_status(uint32_t index)
{
return USB_IN_Endpoint_Status[index];
}
/*********************************************************************
* @fn usbdev_get_out_endpoints_status
*
* @brief Get out endpoints status.
*
* @param index: Out endpoints index.
*********************************************************************/
uint16_t usbdev_get_out_endpoints_status(uint32_t index)
{
return USB_OUT_Endpoint_Status[index];
}
/*********************************************************************
* @fn usbdev_get_device_configuration_num
*
* @brief Get device configuration num
*********************************************************************/
uint8_t usbdev_get_device_configuration_num(void)
{
return USB_Configuration;
}
/*********************************************************************
* @fn usbdev_get_interface_alternate_num
*
* @brief Get device interface alternate num
*
* @param index: interface index.
*********************************************************************/
uint8_t usbdev_get_interface_alternate_num(uint32_t index)
{
return USB_InterfaceAlternateSet[index];
}
/*********************************************************************
* @fn Endpoint_0_IRQHandler
*
* @brief USB endpoint0 Interrupt Request handler
*
* @param None.
* @return None.
*/
static void Endpoint_0_IRQHandler(void)
{
uint8_t lu8_RxCount;
static bool lb_WaitSetAddress = false;
static bool lb_PktMAX = false;
usb_selecet_endpoint(ENDPOINT_0);
/* Clear SetupEnd status */
if (USB_POINT0->CSR01 & USB_CSR01_SETUPEND)
{
USB_POINT0->CSR01 |= USB_CSR01_SVCSETUPEND;
}
/* endpoint 0 receive a packet */
if (usb_Endpoint0_GET_RxPktRdy())
{
/* Data Out packet */
if (Endpoint_0_DataOut_Handler != NULL)
{
Endpoint_0_DataOut_Handler();
}
/* Standard Request packet */
else
{
lu8_RxCount = usb_Endpoint0_get_RxCount();
usb_read_fifo(ENDPOINT_0, (uint8_t *)&StandardRequest, lu8_RxCount);
/* Standard Request */
if ((StandardRequest.bmRequestType & REQUEST_TYPE_MASK) == TYPE_STANDARD)
{
switch (StandardRequest.bRequest)
{
/* request descriptor */
case REQUEST_GET_DESCRIPTOR:
{
/* Build the returned data */
ReturnData.RequestLength = (uint16_t)StandardRequest.wLength[1] << 8;
ReturnData.RequestLength |= (uint16_t)StandardRequest.wLength[0];
switch (StandardRequest.wValue[1])
{
case DESCRIPTOR_DEVICE:
{
ReturnData.DataBuffer = DevDescriptors.DeviceDescriptor;
ReturnData.DataLength = ReturnData.DataBuffer[0];
}break;
case DESCRIPTOR_CONFIGURATION:
{
ReturnData.DataBuffer = DevDescriptors.ConfigurationDescriptor;
ReturnData.DataLength = (uint32_t)ReturnData.DataBuffer[3] << 8;
ReturnData.DataLength |= (uint32_t)ReturnData.DataBuffer[2];
}break;
case DESCRIPTOR_STRING:
{
switch (StandardRequest.wValue[0])
{
case STRING_MANUFACTURE:
{
ReturnData.DataBuffer = DevDescriptors.stringManufacture;
}break;
case STRING_PRODUCT:
{
ReturnData.DataBuffer = DevDescriptors.stringProduct;
}break;
case STRING_SERIAL_Number:
{
ReturnData.DataBuffer = DevDescriptors.stringSerialNumber;
}break;
case STRING_LANUAGE_ID:
{
ReturnData.DataBuffer = DevDescriptors.stringLanuageID;
}break;
case STRING_OS:
{
ReturnData.DataBuffer = DevDescriptors.stringOS;
}break;
default: break;
}
ReturnData.DataLength = ReturnData.DataBuffer[0];
}break;
case DESCRIPTOR_DEVICE_QUALIFIER:
{
/* USB2.0 full speed send stall */
usb_Endpoint0_SendStall();
}break;
case DESCRIPTOR_BOS:
{
/* USB2.0 does not support DESCRIPTOR_BOS */
usb_Endpoint0_SendStall();
}break;
case DESCRIPTOR_HID:
case DESCRIPTOR_HID_REPORT:
{
if (Endpoint_0_StandardClassRequest_Handler != NULL)
{
Endpoint_0_StandardClassRequest_Handler(&StandardRequest, &ReturnData);
}
}break;
default: break;
}
}break;
/* set device address */
case REQUEST_SET_ADDRESS:
{
/* wait an empty IN packet */
lb_WaitSetAddress = true;
}break;
/* set configuration */
case REQUEST_SET_CONFIGURATION:
{
USB_Configuration = StandardRequest.wValue[0];
}break;
/* get configuration */
case REQUEST_GET_CONFIGURATION:
{
ReturnData.RequestLength = 1;
ReturnData.DataBuffer = &USB_Configuration;
ReturnData.DataLength = 1;
}break;
/* set interface */
case REQUEST_SET_INTERFACE:
{
USB_InterfaceAlternateSet[StandardRequest.wIndex[0]] = StandardRequest.wValue[0];
if (USB_InterfaceAlternateSet_callback != NULL)
{
USB_InterfaceAlternateSet_callback(StandardRequest.wIndex[0]);
}
}break;
/* get interface */
case REQUEST_GET_INTERFACE:
{
ReturnData.RequestLength = (uint16_t)StandardRequest.wLength[1] << 8;
ReturnData.RequestLength |= (uint16_t)StandardRequest.wLength[0];
ReturnData.DataBuffer = &USB_InterfaceAlternateSet[StandardRequest.wIndex[0]];
ReturnData.DataLength = ReturnData.RequestLength;
}break;
/* get status */
case REQUEST_GET_STATUS:
{
/* Get Device status */
if ((StandardRequest.bmRequestType & REQUEST_RECIPIENT_MASK) == RECIPIENT_DEVICE)
{
ReturnData.DataBuffer = (uint8_t *)&USB_Device_Status;
}
/* Get Interface status */
else if ((StandardRequest.bmRequestType & REQUEST_RECIPIENT_MASK) == RECIPIENT_INTERFACE)
{
ReturnData.DataBuffer = (uint8_t *)&USB_Interface_Status;
}
/* Get Endpoints status */
else if((StandardRequest.bmRequestType & REQUEST_RECIPIENT_MASK) == RECIPIENT_ENDPOINT)
{
if (StandardRequest.wIndex[0] & DIRECTION_IN)
{
ReturnData.DataBuffer = (uint8_t *)&USB_IN_Endpoint_Status[StandardRequest.wIndex[0] & 0x0F];
}
else
{
ReturnData.DataBuffer = (uint8_t *)&USB_OUT_Endpoint_Status[StandardRequest.wIndex[0] & 0x0F];
}
}
/* Build the returned data */
ReturnData.RequestLength = 2;
ReturnData.DataLength = 2;
}break;
/* Set feature */
case REQUEST_SET_FEATURE:
{
/* clear device feature */
if ((StandardRequest.bmRequestType & REQUEST_RECIPIENT_MASK) == RECIPIENT_DEVICE)
{
if ((StandardRequest.wValue[0] == 1) && (StandardRequest.wValue[1] == 0))
{
USB_Device_Status |= 0x0002;
}
}
/* Set Endpoint feature */
else if ((StandardRequest.bmRequestType & REQUEST_RECIPIENT_MASK) == RECIPIENT_ENDPOINT)
{
if ((StandardRequest.wValue[0] == 0) && (StandardRequest.wValue[1] == 0))
{
if (StandardRequest.wIndex[0] & DIRECTION_IN)
{
USB_IN_Endpoint_Status[StandardRequest.wIndex[0] & 0x0F] = 0x0001;
}
else
{
USB_OUT_Endpoint_Status[StandardRequest.wIndex[0] & 0x0F] = 0x0001;
}
}
}
}break;
/* Clear feature */
case REQUEST_CLEAR_FEATURE:
{
/* clear device feature */
if ((StandardRequest.bmRequestType & REQUEST_RECIPIENT_MASK) == RECIPIENT_DEVICE)
{
if ((StandardRequest.wValue[0] == 1) && (StandardRequest.wValue[1] == 0))
{
USB_Device_Status &= ~0x0002;
}
}
/* clear Endpoint feature */
else if ((StandardRequest.bmRequestType & REQUEST_RECIPIENT_MASK) == RECIPIENT_ENDPOINT)
{
if ((StandardRequest.wValue[0] == 0) && (StandardRequest.wValue[1] == 0))
{
if (StandardRequest.wIndex[0] & DIRECTION_IN)
{
USB_IN_Endpoint_Status[StandardRequest.wIndex[0] & 0x0F] = 0x0000;
}
else
{
USB_OUT_Endpoint_Status[StandardRequest.wIndex[0] & 0x0F] = 0x0000;
}
}
}
}break;
default: break;
}
}
/* Class Request */
else if ((StandardRequest.bmRequestType & REQUEST_TYPE_MASK) == TYPE_CLASS)
{
if (Endpoint_0_ClassRequest_Handler != NULL)
{
Endpoint_0_ClassRequest_Handler(&StandardRequest, &ReturnData);
}
}
/* Vendor Request */
else if ((StandardRequest.bmRequestType & REQUEST_TYPE_MASK) == TYPE_VENDOR)
{
if (Endpoint_0_VendorRequest_Handler != NULL)
{
Endpoint_0_VendorRequest_Handler(&StandardRequest, &ReturnData);
}
}
/* clear TxPktRdy/RxPktRdy */
usb_Endpoint0_FlushFIFO();
}
}
/* endpoint 0 transmit a packet */
else
{
if (lb_WaitSetAddress == true)
{
lb_WaitSetAddress = false;
usb_set_address(StandardRequest.wValue[0]);
}
}
/* DataBuffer needs to be sent */
if (ReturnData.DataLength)
{
if (ReturnData.RequestLength < ReturnData.DataLength)
{
ReturnData.DataLength = ReturnData.RequestLength;
}
if (ReturnData.DataLength > ENDPOINT0_MAX)
{
usb_write_fifo(ENDPOINT_0, ReturnData.DataBuffer, ENDPOINT0_MAX);
ReturnData.DataLength -= ENDPOINT0_MAX;
ReturnData.DataBuffer += ENDPOINT0_MAX;
}
else
{
usb_write_fifo(ENDPOINT_0, ReturnData.DataBuffer, ReturnData.DataLength);
if (ReturnData.DataLength == ENDPOINT0_MAX)
{ /* Packet length is equal to 64 byte, without DataEnd */
lb_PktMAX = true;
}
else
{
usb_Endpoint0_DataEnd();
}
ReturnData.DataLength = 0;
}
usb_Endpoint0_SET_TxPktRdy();
}
else
{
/* The packet length of 64 bytes was sent */
if (lb_PktMAX)
{
/* The next packet is empty */
usb_Endpoint0_DataEnd();
usb_Endpoint0_SET_TxPktRdy();
lb_PktMAX = false;
}
}
}
/*********************************************************************
* @fn Endpoints_IRQHandler
*
* @brief ALL Endpoint Interrupt Request handler
*
* @param None.
* @return None.
*/
static void Endpoints_IRQHandler(void)
{
volatile uint8_t lu8_RxStatus;
volatile uint8_t lu8_TxStatus;
volatile uint8_t lu8_EndpointBackup;
lu8_EndpointBackup = usb_get_endpoint();
lu8_TxStatus = usb_get_TxStatus();
lu8_RxStatus = usb_get_RxStatus();
/* endpoint 0 Interrupt handler */
if (lu8_TxStatus & ENDPOINT_0_MASK)
{
lu8_TxStatus &= ~ENDPOINT_0_MASK;
Endpoint_0_IRQHandler();
}
/* other endpoints Rx/Tx Interrupt handler */
if (lu8_RxStatus | lu8_TxStatus)
{
if (Endpoints_Handler != NULL)
{
Endpoints_Handler(lu8_RxStatus, lu8_TxStatus);
}
}
usb_selecet_endpoint((enum_Endpoint_t)lu8_EndpointBackup);
}
static void USB_Status_IRQHandler(void)
{
volatile uint8_t lu8_EndpointBackup;
volatile uint8_t lu8_USBStatus;
lu8_EndpointBackup = usb_get_endpoint();
lu8_USBStatus = usb_get_USBStatus();
/* USB Bus SOF packet */
if (lu8_USBStatus & USB_INT_STATUS_SOF)
{
if (USB_SOF_Handler != NULL)
{
USB_SOF_Handler();
}
}
/* USB Bus reset signal, Will be clear USB register */
/* need configure USB register again */
if (lu8_USBStatus & USB_INT_STATUS_RESET)
{
USB->IntrUSBE = 0x04; /* Enable Bus reset INT */
USB->IntrTx1E = 0x01; /* Enable Endpoint0 INT */
USB->IntrTx2E = 0x00;
USB->IntrRx1E = 0x00;
USB->IntrRx2E = 0x00;
if (USB_Reset_Handler != NULL)
{
USB_Reset_Handler();
}
}
/* USB Bus Resume signal */
if (lu8_USBStatus & USB_INT_STATUS_RESUME)
{
if (USB_Resume_Handler != NULL)
{
USB_Resume_Handler();
}
}
/* USB Bus Suspend signal */
if (lu8_USBStatus & USB_INT_STATUS_SUSPEND)
{
if (USB_Suspend_Handler != NULL)
{
USB_Suspend_Handler();
}
}
/* USB Bus connect signal */
if (lu8_USBStatus & USB_INT_STATUS_CONN)
{
if (USB_Connect_Handler != NULL)
{
USB_Connect_Handler();
}
}
usb_selecet_endpoint((enum_Endpoint_t)lu8_EndpointBackup);
}
#define USB_IRQHandler usbotg_irq
/*********************************************************************
* @fn USB_IRQHandler
*
* @brief USB interrupt Request handler
*
* @param None.
* @return None.
*/
void USB_IRQHandler(void)
{
Endpoints_IRQHandler();
USB_Status_IRQHandler();
}

View File

@ -0,0 +1,612 @@
/*
******************************************************************************
* @file usb_hid.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief This file provides the high layer firmware functions to manage the
* USB HID Device.(Human Interface Device)
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
*
******************************************************************************
* How to use, for example:
*
* int main(void)
* {
* NVIC_ClearPendingIRQ(USBMCU_IRQn);
* NVIC_SetPriority(USBMCU_IRQn, 0);
* NVIC_EnableIRQ(USBMCU_IRQn);
*
* usb_device_init();
* usb_hid_init();
*
* // Wait for other initialization of the MCU
*
* while(1)
* {
* usb_hid_send_mouse_report();
* usb_hid_send_keyboard_report();
* }
* }
******************************************************************************
*/
#include "usb_hid.h"
#define REPORT0_LENGTH (4)
#define REPORT1_LENGTH (8)
uint8_t HID_Mouse_Report[REPORT0_LENGTH];
uint8_t HID_Keyboard_Report[REPORT1_LENGTH];
/* USB Standard Device Descriptor */
const uint8_t USB_HID_DeviceDesc[] =
{
0x12, /* bLength */
0x01, /* bDescriptorType */
0x00, /* bcdUSB */
0x02,
0x00, /* bDeviceClass */
0x00, /* bDeviceSubClass */
0x00, /* bDeviceProtocol */
0x40, /* bMaxPacketSize */
0xA4, /* idVendor */
0xA8, /* idVendor */
0x55, /* idProduct */
0x22, /* idProduct */
0x00, /* bcdDevice rel. 2.00 */
0x20,
0x01, /* Index of manufacturer string */
0x02, /* Index of product string */
0x03, /* Index of serial number string */
0x01, /* bNumConfigurations */
};
/* HID Descriptor */
#define HID_DESCRIPTOR_0 0x09, /* bLength */ \
0x21, /* bDescriptorType: HID */ \
0x10, /* bcdHID: 1.10 */ \
0x01, \
0x21, /* bCountryCode */ \
0x01, /* bNumDescriptors */ \
0x22, /* bDescriptorType: Report */ \
0x2E, /* wDescriptorLength */ \
0x00
/* HID Descriptor */
#define HID_DESCRIPTOR_1 0x09, /* bLength */ \
0x21, /* bDescriptorType: HID */ \
0x10, /* bcdHID: 1.10 */ \
0x01, \
0x21, /* bCountryCode */ \
0x01, /* bNumDescriptors */ \
0x22, /* bDescriptorType: Report */ \
0x41, /* wDescriptorLength */ \
0x00
const uint8_t USB_HID_Desc_0[] =
{
HID_DESCRIPTOR_0,
};
const uint8_t USB_HID_Desc_1[] =
{
HID_DESCRIPTOR_1,
};
/* USB Standard Configuration Descriptor */
const uint8_t USB_HID_ConfigurationDesc[] =
{
/* Configuration Descriptor */
0x09, /* bLength */
0x02, /* bDescriptorType */
0x42, /* wTotalLength */
0x00,
0x02, /* bNumInterfaces */
0x01, /* bConfigurationValue */
0x00, /* iConfiguration */
0xA0, /* bmAttributes */
0x32, /* bMaxPower */
/* HID Interface_0 Descriptor */
0x09, /* bLength */
0x04, /* bDescriptorType */
0x00, /* bInterfaceNumber */
0x00, /* bAlternateSetting */
0x01, /* bNumEndpoints */
0x03, /* bInterfaceClass: HID */
0x01, /* bInterfaceSubClass: Boot interface */
0x02, /* bInterfaceProtocol: Mouse */
0x00, /* iConfiguration */
/* HID Descriptor */
HID_DESCRIPTOR_0,
/* Endpoint 1 Descriptor */
0x07, /* bLength */
0x05, /* bDescriptorType */
0x81, /* bEndpointAddress */
0x03, /* bmAttributes: Interrupt */
0x40, /* wMaxPacketSize: 64byte */
0x00,
0x08, /* bInterval */
/* HID Interface_1 Descriptor */
0x09, /* bLength */
0x04, /* bDescriptorType */
0x01, /* bInterfaceNumber */
0x00, /* bAlternateSetting */
0x02, /* bNumEndpoints */
0x03, /* bInterfaceClass: HID */
0x01, /* bInterfaceSubClass: Boot interface */
0x01, /* bInterfaceProtocol: Keyboard */
0x00, /* iConfiguration */
/* HID Descriptor */
HID_DESCRIPTOR_1,
/* Endpoint 2 IN Descriptor */
0x07, /* bLength */
0x05, /* bDescriptorType */
0x82, /* bEndpointAddress */
0x03, /* bmAttributes: Interrupt */
0x40, /* wMaxPacketSize: 64byte */
0x00,
0x0A, /* bInterval */
/* Endpoint 2 OUT Descriptor */
0x07, /* bLength */
0x05, /* bDescriptorType */
0x02, /* bEndpointAddress */
0x03, /* bmAttributes: Interrupt */
0x40, /* wMaxPacketSize: 64byte */
0x00,
0x0A, /* bInterval */
};
/* USB Standard Manufacture Descriptor */
const uint8_t USB_HID_ManufactureDesc[] =
{
0x12, /* bLength */
0x03, /* bDescriptorType */
'F', 0x00, /* BString */
'R', 0x00,
'E', 0x00,
'Q', 0x00,
'C', 0x00,
'H', 0x00,
'I', 0x00,
'P', 0x00,
};
/* USB Standard Configuration Descriptor */
const uint8_t USB_HID_ProductDesc[] =
{
0x1A, /* bLength */
0x03, /* bDescriptorType */
'F', 0x00, /* BString */
'R', 0x00,
'E', 0x00,
'Q', 0x00,
'C', 0x00,
'H', 0x00,
'I', 0x00,
'P', 0x00,
'-', 0x00,
'H', 0x00,
'I', 0x00,
'D', 0x00,
};
/* USB Standard Configuration Descriptor */
const uint8_t USB_HID_SerialNumberDesc[] =
{
0x1E, /* bLength */
0x03, /* bDescriptorType */
'2', 0x00, /* BString */
'0', 0x00,
'2', 0x00,
'1', 0x00,
'-', 0x00,
'1', 0x00,
'0', 0x00,
'0', 0x00,
'1', 0x00,
'-', 0x00,
'B', 0x00,
'1', 0x00,
'3', 0x00,
'5', 0x00,
};
/* USB Standard Configuration Descriptor */
const uint8_t USB_HID_LanuageIDDesc[] =
{
0x04, /* bLength */
0x03, /* bDescriptorType */
0x09, /* BString */
0x04,
};
/* HID device report Descriptor */
uint8_t USB_HID_Mouse_ReportDesc[] =
{
0x2E, /* Length */
0x05, 0x01,
0x09, 0x02,
0xA1, 0x01,
0x09, 0x01,
0xA1, 0x00,
0x05, 0x09,
0x19, 0x01,
0x29, 0x03,
0x15, 0x00,
0x25, 0x01,
0x95, 0x08,
0x75, 0x01,
0x81, 0x02,
0x05, 0x01,
0x09, 0x30,
0x09, 0x31,
0x09, 0x38,
0x15, 0x81,
0x25, 0x7F,
0x75, 0x08,
0x95, 0x03,
0x81, 0x06,
0xC0,
0xC0,
};
/* HID device report Descriptor */
uint8_t USB_HID_Keyboard_ReportDesc[] =
{
0x41, /* Length */
0x05, 0x01,
0x09, 0x06,
0xA1, 0x01,
0x05, 0x07,
0x19, 0xE0,
0x29, 0xE7,
0x15, 0x00,
0x25, 0x01,
0x75, 0x01,
0x95, 0x08,
0x81, 0x02,
0x95, 0x01,
0x75, 0x08,
0x81, 0x01,
0x95, 0x03,
0x75, 0x01,
0x05, 0x08,
0x19, 0x01,
0x29, 0x03,
0x91, 0x02,
0x95, 0x05,
0x75, 0x01,
0x91, 0x01,
0x95, 0x06,
0x75, 0x08,
0x15, 0x00,
0x26, 0xFF, 0x00,
0x05, 0x07,
0x19, 0x00,
0x2A, 0xFF, 0x00,
0x81, 0x00,
0xC0,
0xC0,
};
/*********************************************************************
* @fn usb_hid_set_mouse_report
*
* @brief set report
*
* @param None.
* @return None.
*/
void usb_hid_set_mouse_report(uint8_t fu8_Index, uint8_t fu8_Value)
{
HID_Mouse_Report[fu8_Index] = fu8_Value;
/*
HID_Report[0]: 0000 0001 left button
0000 0010 right button
0000 0100 middle button
HID_Report[1]: X (-127 ~ +127)
HID_Report[2]: Y (-127 ~ +127)
HID_Report[3]: wheel (-127 ~ +127)
*/
}
/*********************************************************************
* @fn usb_hid_set_keyboard_report
*
* @brief set report
*
* @param None.
* @return None.
*/
void usb_hid_set_keyboard_report(uint16_t fu16_Key)
{
uint32_t i;
switch (fu16_Key)
{
case KEY_LEFT_CONTROL: HID_Keyboard_Report[0] |= 0x01; break;
case KEY_LEFT_SHIFT: HID_Keyboard_Report[0] |= 0x02; break;
case KEY_LEFT_ALT: HID_Keyboard_Report[0] |= 0x04; break;
case KEY_LEFT_GUI: HID_Keyboard_Report[0] |= 0x08; break;
case KEY_RIGHT_CONTROL: HID_Keyboard_Report[0] |= 0x10; break;
case KEY_RIGHT_SHIFT: HID_Keyboard_Report[0] |= 0x20; break;
case KEY_RIGHT_ALT: HID_Keyboard_Report[0] |= 0x40; break;
case KEY_RIGHT_GUI: HID_Keyboard_Report[0] |= 0x80; break;
default:
{
for (i = 2; i < 8; i++)
{
if (HID_Keyboard_Report[i] == fu16_Key)
{
break;
}
if (HID_Keyboard_Report[i] == 0x00)
{
HID_Keyboard_Report[i] = fu16_Key;
break;
}
}
}break;
}
}
/*********************************************************************
* @fn usb_hid_clear_keyboard_report
*
* @brief set report
*
* @param None.
* @return None.
*/
void usb_hid_clear_keyboard_report(uint16_t fu16_Key)
{
uint32_t i, k;
switch (fu16_Key)
{
case KEY_LEFT_CONTROL: HID_Keyboard_Report[0] &= ~0x01; break;
case KEY_LEFT_SHIFT: HID_Keyboard_Report[0] &= ~0x02; break;
case KEY_LEFT_ALT: HID_Keyboard_Report[0] &= ~0x04; break;
case KEY_LEFT_GUI: HID_Keyboard_Report[0] &= ~0x08; break;
case KEY_RIGHT_CONTROL: HID_Keyboard_Report[0] &= ~0x10; break;
case KEY_RIGHT_SHIFT: HID_Keyboard_Report[0] &= ~0x20; break;
case KEY_RIGHT_ALT: HID_Keyboard_Report[0] &= ~0x40; break;
case KEY_RIGHT_GUI: HID_Keyboard_Report[0] &= ~0x80; break;
default:
{
for (i = 2; i < 8; i++)
{
if (HID_Keyboard_Report[i] == fu16_Key)
{
HID_Keyboard_Report[i] = 0x00;
for (k = i; k < 7; k++)
{
if (HID_Keyboard_Report[k + 1] != 0x00)
{
HID_Keyboard_Report[k] = HID_Keyboard_Report[k + 1];
HID_Keyboard_Report[k + 1] = 0x00;
}
else
{
break;
}
}
break;
}
}
}break;
}
}
/*********************************************************************
* @fn usb_hid_send_mouse_report
*
* @brief send report to host
*
* @param None.
* @return None.
*/
void usb_hid_send_mouse_report(void)
{
usb_selecet_endpoint(ENDPOINT_1);
/* FIFO empty */
if (usb_Endpoints_GET_TxPktRdy() == false)
{
usb_write_fifo(ENDPOINT_1, HID_Mouse_Report, REPORT0_LENGTH);
usb_Endpoints_SET_TxPktRdy();
}
}
/*********************************************************************
* @fn usb_hid_send_keyboard_report
*
* @brief send report to host
*
* @param None.
* @return None.
*/
void usb_hid_send_keyboard_report(void)
{
usb_selecet_endpoint(ENDPOINT_2);
/* FIFO empty */
if (usb_Endpoints_GET_TxPktRdy() == false)
{
usb_write_fifo(ENDPOINT_2, HID_Keyboard_Report, REPORT1_LENGTH);
usb_Endpoints_SET_TxPktRdy();
}
}
/*********************************************************************
* @fn usb_hid_ClassRequest_Handler
*
* @brief HID Class Request Handler
*
* @param None.
* @return None.
*/
static void usb_hid_ClassRequest_Handler(usb_StandardRequest_t* pStandardRequest, usb_ReturnData_t* pReturnData)
{
static uint8_t HID_Protocol = 1; // 0: Boot Protocol
// 1: Report Protocol
switch (pStandardRequest->bRequest)
{
case HID_GET_PROTOCOL:
{
pReturnData->DataBuffer = &HID_Protocol;
pReturnData->DataLength = 1;
}break;
case HID_SET_PROTOCOL:
{
HID_Protocol = pStandardRequest->wValue[0];
}break;
case HID_GET_IDLE:
{
/* Device does not support Getidle command */
usb_Endpoint0_SendStall();
}break;
case HID_SET_IDLE:
{
/* Device does not support Setidle command */
usb_Endpoint0_SendStall();
}break;
default: break;
}
}
/*********************************************************************
* @fn usb_hid_StandardClassRequest_Handler
*
* @brief HID Standard Class Request Handler
*
* @param None.
* @return None.
*/
static void usb_hid_StandardClassRequest_Handler(usb_StandardRequest_t* pStandardRequest, usb_ReturnData_t* pReturnData)
{
switch (pStandardRequest->wValue[1])
{
case DESCRIPTOR_HID_REPORT:
{
if (pStandardRequest->wIndex[0] == 0){
pReturnData->DataLength = USB_HID_Mouse_ReportDesc[0];
pReturnData->DataBuffer = &USB_HID_Mouse_ReportDesc[1];
}
else if (pStandardRequest->wIndex[0] == 1){
pReturnData->DataLength = USB_HID_Keyboard_ReportDesc[0];
pReturnData->DataBuffer = &USB_HID_Keyboard_ReportDesc[1];
}
}break;
case DESCRIPTOR_HID:
{
if (pStandardRequest->wIndex[0] == 0){
pReturnData->DataLength = 9;
pReturnData->DataBuffer = (uint8_t *)USB_HID_Desc_0;
}
else if (pStandardRequest->wIndex[0] == 1){
pReturnData->DataLength = 9;
pReturnData->DataBuffer = (uint8_t *)USB_HID_Desc_1;
}
}break;
default: break;
}
}
/*********************************************************************
* @fn usb_hid_Endpoints_Handler
*
* @brief hid Endpoints Handler
*
* @param None.
* @return None.
*/
void usb_hid_Endpoints_Handler(uint8_t RxStatus, uint8_t TxStatus)
{
uint8_t lu8_RxCount;
uint8_t lu8_Buffer[4] = {0,0,0,0};
if (RxStatus & 1 << ENDPOINT_2)
{
usb_selecet_endpoint(ENDPOINT_2);
lu8_RxCount = usb_Endpoints_get_RxCount();
usb_read_fifo(ENDPOINT_2, lu8_Buffer, lu8_RxCount);
usb_Endpoints_FlushRxFIFO();
}
}
/*********************************************************************
* @fn usb_hid_init
*
* @brief hid device parameter initialization
*
* @param None.
* @return None.
*/
void usb_hid_init(void)
{
/* Initialize the relevant pointer */
usbdev_get_dev_desc((uint8_t *)USB_HID_DeviceDesc);
usbdev_get_config_desc((uint8_t *)USB_HID_ConfigurationDesc);
usbdev_get_string_Manufacture((uint8_t *)USB_HID_ManufactureDesc);
usbdev_get_string_Product((uint8_t *)USB_HID_ProductDesc);
usbdev_get_string_SerialNumber((uint8_t *)USB_HID_SerialNumberDesc);
usbdev_get_string_LanuageID((uint8_t *)USB_HID_LanuageIDDesc);
Endpoint_0_StandardClassRequest_Handler = usb_hid_StandardClassRequest_Handler;
Endpoint_0_ClassRequest_Handler = usb_hid_ClassRequest_Handler;
Endpoints_Handler = usb_hid_Endpoints_Handler;
USB_Reset_Handler = usb_hid_init;
/* config data endpoint fifo */
usb_selecet_endpoint(ENDPOINT_1);
usb_endpoint_Txfifo_config(0x08, 3);
usb_TxMaxP_set(8);
usb_RxMaxP_set(8);
usb_selecet_endpoint(ENDPOINT_2);
usb_endpoint_Txfifo_config(0x18, 3);
usb_endpoint_Rxfifo_config(0x20, 3);
usb_TxMaxP_set(8);
usb_RxMaxP_set(8);
usb_RxInt_Enable(ENDPOINT_2);
usb_SuspendDetectEn();
usb_SingleInt_Enable(USB_INT_STATUS_SUSPEND);
usb_SingleInt_Enable(USB_INT_STATUS_RESUME);
}

View File

@ -0,0 +1,526 @@
/*
******************************************************************************
* @file usb_mass_storage.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2023
* @brief This file provides the high layer firmware functions to manage the
* Mass Storage Device.
******************************************************************************
* @attention
*
* Copyright (c) 2023 FreqChip.
* All rights reserved.
*
******************************************************************************
* How to use, for example:
*
* int main(void)
* {
* NVIC_ClearPendingIRQ(USBMCU_IRQn);
* NVIC_SetPriority(USBMCU_IRQn, 0);
* NVIC_EnableIRQ(USBMCU_IRQn);
*
* usb_device_init();
* usb_mass_storage_init();
*
* // Wait for other initialization of the MCU
*
* while(1)
* {
* }
* }
******************************************************************************
*/
#include "fr30xx.h"
#define DISK_BLOCKS (100)
#define DISK_PAGE_SIZE (512) /* one page 512 byte fixed */
#define RAM_SIMULATE_DISK_CAPACITY (DISK_PAGE_SIZE * DISK_BLOCKS)
uint8_t Disk[RAM_SIMULATE_DISK_CAPACITY];
/* USB Standard Device Descriptor */
const uint8_t USB_MassStorage_DeviceDesc[] =
{
0x12, /* bLength */
0x01, /* bDescriptorType */
0x00, /* bcdUSB */
0x02,
0x00, /* bDeviceClass: Class info in ifc Descriptors */
0x00, /* bDeviceSubClass */
0x00, /* bDeviceProtocol */
0x40, /* bMaxPacketSize */
0xA9, /* idVendor */
0x13, /* idVendor */
0xCC, /* idProduct */
0x10, /* idProduct */
0x00, /* bcdDevice rel. 2.00 */
0x20,
0x01, /* Index of manufacturer string */
0x02, /* Index of product string */
0x03, /* Index of serial number string */
0x01, /* bNumConfigurations */
};
/* USB Standard Configuration Descriptor */
const uint8_t USB_MassStorage_ConfigurationDesc[] =
{
/* Configuration Descriptor */
0x09, /* bLength */
0x02, /* bDescriptorType */
0x20, /* wTotalLength */
0x00,
0x01, /* bNumInterfaces */
0x01, /* bConfigurationValue */
0x00, /* iConfiguration */
0x80, /* bmAttributes */
0x96, /* bMaxPower */
/* Interface Descriptor */
0x09, /* bLength */
0x04, /* bDescriptorType */
0x00, /* bInterfaceNumber */
0x00, /* bAlternateSetting */
0x02, /* bNumEndpoints */
0x08, /* bInterfaceClass: Mass Storage */
0x06, /* bInterfaceSubClass SCSI Transparent Conmmand Set */
0x50, /* bInterfaceProtocol Bulk-Only Transport */
0x00, /* iConfiguration */
/* Endpoint 1 IN Descriptor */
0x07, /* bLength */
0X05, /* bDescriptorType */
0x81, /* bEndpointAddress */
0x02, /* bmAttributes: bulk */
0x40, /* wMaxPacketSize: 64byte */
0x00,
0x00, /* bInterval */
/* Endpoint 1 OUT Descriptor */
0x07, /* bLength */
0X05, /* bDescriptorType */
0x01, /* bEndpointAddress */
0x02, /* bmAttributes: bulk */
0x40, /* wMaxPacketSize: 64byte */
0x00,
0x00, /* bInterval */
};
/* USB Standard Manufacture Descriptor */
const uint8_t USB_MassStorage_ManufactureDesc[] =
{
0x12, /* bLength */
0x03, /* bDescriptorType */
'F', 0x00, /* BString */
'R', 0x00,
'E', 0x00,
'Q', 0x00,
'C', 0x00,
'H', 0x00,
'I', 0x00,
'P', 0x00,
};
/* USB Standard Configuration Descriptor */
const uint8_t USB_MassStorage_ProductDesc[] =
{
0x2C, /* bLength */
0x03, /* bDescriptorType */
'F', 0x00, /* BString */
'R', 0x00,
'E', 0x00,
'Q', 0x00,
'C', 0x00,
'H', 0x00,
'I', 0x00,
'P', 0x00,
'-', 0x00,
'D', 0x00,
'a', 0x00,
't', 0x00,
'a', 0x00,
'T', 0x00,
'r', 0x00,
'a', 0x00,
'v', 0x00,
'e', 0x00,
'l', 0x00,
'e', 0x00,
'r', 0x00,
};
/* USB Standard Configuration Descriptor */
const uint8_t USB_MassStorage_SerialNumberDesc[] =
{
0x1E, /* bLength */
0x03, /* bDescriptorType */
'2', 0x00, /* BString */
'0', 0x00,
'2', 0x00,
'3', 0x00,
'-', 0x00,
'2', 0x00,
'0', 0x00,
'0', 0x00,
'2', 0x00,
'-', 0x00,
'C', 0x00,
'1', 0x00,
'3', 0x00,
'5', 0x00,
};
/* USB Standard Configuration Descriptor */
const uint8_t USB_MassStorage_LanuageIDDesc[] =
{
0x04, /* bLength */
0x03, /* bDescriptorType */
0x09, /* BString */
0x04,
};
const uint8_t SCSI_Inquiry_Response[] =
{
0x00, /* Device Type */
0x80, /* Removable */
0x00, /* Version */
0x01, /* Response Data Format */
0x1F, /* Additional Length */
0x00,0x00,0x00,
'F','r','e','q','c','h','i','p',
'2','0','1','3','-','4','5','3','2','-','A','D','E','F','G','H',
'1','.','0','0',
};
uint8_t SCSI_ReadForamtCapacity_Response[] =
{
0x00,0x00,0x00,
0x08, /* list length */
0x00,0x00,0x01,0x90, /* Blocks */
0x02,
0x00,0x02,0x00, /* Page size */
};
uint8_t SCSI_ReadCapacity_Response[] =
{
0x00,0x00,0x01,0x8F, /* Blocks */
0x00,0x00,0x02,0x00, /* Page size */
};
const uint8_t SCSI_SENSE6_Response[] =
{
0x03,0x00,0x00,0x00,
};
static uint8_t USB_MessageBuffer[10];
/*********************************************************************
* @fn usb_MassStorage_ClassRequest_Handler
*
* @brief Mass Storage Class Request Handler
*/
static void usb_MassStorage_ClassRequest_Handler(usb_StandardRequest_t* pStandardRequest, usb_ReturnData_t* pReturnData)
{
switch (pStandardRequest->bRequest)
{
case BULK_ONLY_MASS_STORAGE_RESET:
{
usb_Endpoint0_DataEnd();
usb_Endpoint0_SET_TxPktRdy();
}break;
case GET_MAX_LUN:
{
USB_MessageBuffer[0] = FREQCHIP_MASS_STORAGE_MAX_LUN - 1;
pReturnData->DataBuffer = USB_MessageBuffer;
pReturnData->DataLength = 1;
}break;
default: break;
}
}
/*********************************************************************
* @fn usb_MassStorage_SendCSW
*
* @brief SCSI Send CSW
*/
static void usb_MassStorage_SendCSW(uint32_t fu32_CBWTag)
{
#define CBW_LEN (13)
uint8_t USB_CSWBuffer[CBW_LEN];
usb_CSW_t *CSW;
CSW = (usb_CSW_t *)USB_CSWBuffer;
CSW->dCSWSignature = CSW_SIGNATURE;
CSW->dCSWTag = fu32_CBWTag;
CSW->dCSWDataResidue = 0;
CSW->bmCSWStatus = 0x00;
if (usb_Endpoints_GET_TxPktRdy() == false)
{
usb_write_fifo(ENDPOINT_1, (uint8_t *)USB_CSWBuffer, CBW_LEN);
usb_Endpoints_SET_TxPktRdy();
}
}
/*********************************************************************
* @fn Endpoint1_Handler
*
* @brief endpoint1 RX TX Handler
*/
static void Endpoint1_Handler(uint8_t RxStatus, uint8_t TxStatus)
{
static uint8_t USB_CBWBuffer[64];
static uint32_t lu32_WriteStatus = 0;
static uint8_t *lu32_WriteDiskPoint;
static uint32_t lu32_WriteCnt;
static uint32_t lu32_ReadStatus = 0;
static uint8_t *lu32_ReadDiskPoint;
static uint32_t lu32_ReadCnt;
static usb_CBW_t *CBW;
uint32_t lu32_BlockAddr;
uint16_t lu16_BlockCnt;
uint8_t lu8_RxCount;
if (RxStatus & ENDPOINT_1_MASK)
{
usb_selecet_endpoint(ENDPOINT_1);
if (lu32_WriteStatus)
{
usb_read_fifo(ENDPOINT_1, lu32_WriteDiskPoint, 64);
usb_Endpoints_FlushRxFIFO();
lu32_WriteDiskPoint += 64;
lu32_WriteCnt -= 1;
if (lu32_WriteCnt == 0)
{
usb_MassStorage_SendCSW(CBW->dCBWTag);
lu32_WriteStatus = false;
}
}
else
{
lu8_RxCount = usb_Endpoints_get_RxCount();
if (lu8_RxCount == 0)
return;
usb_read_fifo(ENDPOINT_1, USB_CBWBuffer, lu8_RxCount);
usb_Endpoints_FlushRxFIFO();
CBW = (usb_CBW_t *)USB_CBWBuffer;
if (CBW->dCBWSignature == CBW_SIGNATURE)
{
switch (CBW->CBWCB[0])
{
case SCSI_CMD_Inquiry:
{
if (usb_Endpoints_GET_TxPktRdy() == false)
{
usb_write_fifo(ENDPOINT_1, (uint8_t *)SCSI_Inquiry_Response, sizeof(SCSI_Inquiry_Response));
usb_Endpoints_SET_TxPktRdy();
}
while(usb_Endpoints_GET_TxPktRdy());
usb_MassStorage_SendCSW(CBW->dCBWTag);
}break;
case SCSI_CMD_ReadForamtCapacity:
{
SCSI_ReadForamtCapacity_Response[4] = (DISK_BLOCKS >> 24) & 0xFF;
SCSI_ReadForamtCapacity_Response[5] = (DISK_BLOCKS >> 16) & 0xFF;
SCSI_ReadForamtCapacity_Response[6] = (DISK_BLOCKS >> 8) & 0xFF;
SCSI_ReadForamtCapacity_Response[7] = DISK_BLOCKS & 0xFF;
if (usb_Endpoints_GET_TxPktRdy() == false)
{
usb_write_fifo(ENDPOINT_1, (uint8_t *)SCSI_ReadForamtCapacity_Response, 12);
usb_Endpoints_SET_TxPktRdy();
}
while(usb_Endpoints_GET_TxPktRdy());
usb_MassStorage_SendCSW(CBW->dCBWTag);
}break;
case SCSI_CMD_ReadCapacity:
{
uint32_t lu32_Blocks = DISK_BLOCKS - 1;
SCSI_ReadCapacity_Response[0] = (lu32_Blocks >> 24) & 0xFF;
SCSI_ReadCapacity_Response[1] = (lu32_Blocks >> 16) & 0xFF;
SCSI_ReadCapacity_Response[2] = (lu32_Blocks >> 8) & 0xFF;
SCSI_ReadCapacity_Response[3] = lu32_Blocks & 0xFF;
if (usb_Endpoints_GET_TxPktRdy() == false)
{
usb_write_fifo(ENDPOINT_1, (uint8_t *)SCSI_ReadCapacity_Response, 8);
usb_Endpoints_SET_TxPktRdy();
}
while(usb_Endpoints_GET_TxPktRdy());
usb_MassStorage_SendCSW(CBW->dCBWTag);
}break;
case SCSI_CMD_ModeSENSE6:
{
if (usb_Endpoints_GET_TxPktRdy() == false)
{
usb_write_fifo(ENDPOINT_1, (uint8_t *)SCSI_SENSE6_Response, sizeof(SCSI_SENSE6_Response));
usb_Endpoints_SET_TxPktRdy();
}
while(usb_Endpoints_GET_TxPktRdy());
usb_MassStorage_SendCSW(CBW->dCBWTag);
}break;
case SCSI_CMD_Read10:
{
lu32_ReadDiskPoint = Disk;
lu32_BlockAddr = CBW->CBWCB[2] << 24;
lu32_BlockAddr |= CBW->CBWCB[3] << 16;
lu32_BlockAddr |= CBW->CBWCB[4] << 8;
lu32_BlockAddr |= CBW->CBWCB[5];
lu16_BlockCnt = CBW->CBWCB[7] << 8;
lu16_BlockCnt |= CBW->CBWCB[8];
lu32_ReadDiskPoint += DISK_PAGE_SIZE * lu32_BlockAddr;
lu32_ReadCnt += (lu16_BlockCnt * DISK_PAGE_SIZE)/64;
lu32_ReadStatus = true;
while(usb_Endpoints_GET_TxPktRdy());
usb_write_fifo(ENDPOINT_1, lu32_ReadDiskPoint, 64);
usb_Endpoints_SET_TxPktRdy();
lu32_ReadDiskPoint += 64;
lu32_ReadCnt -= 1;
usb_TxInt_Enable(ENDPOINT_1);
}break;
case SCSI_CMD_Write10:
{
lu32_WriteDiskPoint = Disk;
lu32_BlockAddr = CBW->CBWCB[2] << 24;
lu32_BlockAddr |= CBW->CBWCB[3] << 16;
lu32_BlockAddr |= CBW->CBWCB[4] << 8;
lu32_BlockAddr |= CBW->CBWCB[5];
lu16_BlockCnt = CBW->CBWCB[7] << 8;
lu16_BlockCnt |= CBW->CBWCB[8];
lu32_WriteDiskPoint += DISK_PAGE_SIZE * lu32_BlockAddr;
lu32_WriteCnt = (lu16_BlockCnt*DISK_PAGE_SIZE)/64;
lu32_WriteStatus = true;
}break;
case SCSI_CMD_TestUnitReady:
case SCSI_CMD_Prevent:
{
usb_MassStorage_SendCSW(CBW->dCBWTag);
}break;
default:
{
usb_MassStorage_SendCSW(CBW->dCBWTag);
}break;
}
}
}
}
if (TxStatus & ENDPOINT_1_MASK)
{
usb_selecet_endpoint(ENDPOINT_1);
if (lu32_ReadStatus)
{
if (usb_Endpoints_GET_TxPktRdy() == false)
{
if (lu32_ReadCnt > 0)
{
usb_write_fifo(ENDPOINT_1, (uint8_t *)lu32_ReadDiskPoint, 64);
usb_Endpoints_SET_TxPktRdy();
lu32_ReadDiskPoint += 64;
lu32_ReadCnt -= 1;
}
else if (lu32_ReadCnt == 0)
{
while(usb_Endpoints_GET_TxPktRdy());
usb_MassStorage_SendCSW(CBW->dCBWTag);
lu32_ReadStatus = false;
usb_TxInt_Disable(ENDPOINT_1);
}
}
}
}
}
/*********************************************************************
* @fn usb_mass_storage_init
*
* @brief mass storage parameter initialization
*
* @param None.
* @return None.
*/
void usb_mass_storage_init(void)
{
/* Initialize the relevant pointer */
usbdev_get_dev_desc((uint8_t *)USB_MassStorage_DeviceDesc);
usbdev_get_config_desc((uint8_t *)USB_MassStorage_ConfigurationDesc);
usbdev_get_string_Manufacture((uint8_t *)USB_MassStorage_ManufactureDesc);
usbdev_get_string_Product((uint8_t *)USB_MassStorage_ProductDesc);
usbdev_get_string_SerialNumber((uint8_t *)USB_MassStorage_SerialNumberDesc);
usbdev_get_string_LanuageID((uint8_t *)USB_MassStorage_LanuageIDDesc);
Endpoint_0_ClassRequest_Handler = usb_MassStorage_ClassRequest_Handler;
Endpoints_Handler = Endpoint1_Handler;
USB_Reset_Handler = usb_mass_storage_init;
/* config data endpoint fifo */
usb_selecet_endpoint(ENDPOINT_1);
usb_endpoint_Txfifo_config(0x08, 3);
usb_TxMaxP_set(8);
usb_RxMaxP_set(8);
usb_selecet_endpoint(ENDPOINT_1);
usb_endpoint_Rxfifo_config(0x10, 3);
usb_TxMaxP_set(8);
usb_RxMaxP_set(8);
usb_RxInt_Enable(ENDPOINT_1);
}

View File

@ -0,0 +1,364 @@
/*
******************************************************************************
* @file usb_winusb.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2021
* @brief This file provides the high layer firmware functions to manage the
* WinUSB Device.
******************************************************************************
* @attention
*
* Copyright (c) 2021 FreqChip.
* All rights reserved.
*
******************************************************************************
* How to use, for example:
*
* int main(void)
* {
* NVIC_ClearPendingIRQ(USBMCU_IRQn);
* NVIC_SetPriority(USBMCU_IRQn, 0);
* NVIC_EnableIRQ(USBMCU_IRQn);
*
* usb_device_init();
* usb_winusb_init();
*
* // Wait for other initialization of the MCU
*
* usb_DP_Pullup_Enable();
*
* while(1)
* {
* }
* }
******************************************************************************
*/
#include "usb_winusb.h"
uint8_t WinUSB_Buffer[512];
/* USB Standard Device Descriptor */
const uint8_t USB_WinUSB_DeviceDesc[] =
{
0x12, /* bLength */
0x01, /* bDescriptorType */
0x00, /* bcdUSB */
0x02,
0xFF, /* bDeviceClass: Vendor customization */
0x00, /* bDeviceSubClass */
0x00, /* bDeviceProtocol */
0x40, /* bMaxPacketSize */
0xAA, /* idVendor */
0xBB, /* idVendor */
0xCC, /* idProduct */
0x11, /* idProduct */
0x00, /* bcdDevice rel. 2.00 */
0x20,
0x01, /* Index of manufacturer string */
0x02, /* Index of product string */
0x03, /* Index of serial number string */
0x01, /* bNumConfigurations */
};
/* USB Standard Configuration Descriptor */
const uint8_t USB_WinUSB_ConfigurationDesc[] =
{
/* Configuration Descriptor */
0x09, /* bLength */
0x02, /* bDescriptorType */
0x20, /* wTotalLength */
0x00,
0x01, /* bNumInterfaces */
0x01, /* bConfigurationValue */
0x00, /* iConfiguration */
0x80, /* bmAttributes */
0xFA, /* bMaxPower */
/* Interface Descriptor */
0x09, /* bLength */
0x04, /* bDescriptorType */
0x00, /* bInterfaceNumber */
0x00, /* bAlternateSetting */
0x02, /* bNumEndpoints */
0x00, /* bInterfaceClass */
0x00, /* bInterfaceSubClass */
0x00, /* bInterfaceProtocol */
0x00, /* iConfiguration */
/* Endpoint 1 IN Descriptor */
0x07, /* bLength */
0X05, /* bDescriptorType */
0x81, /* bEndpointAddress */
0x02, /* bmAttributes: bulk */
0x40, /* wMaxPacketSize: 64byte */
0x00,
0x00, /* bInterval */
/* Endpoint 1 OUT Descriptor */
0x07, /* bLength */
0X05, /* bDescriptorType */
0x01, /* bEndpointAddress */
0x02, /* bmAttributes: bulk */
0x40, /* wMaxPacketSize: 64byte */
0x00,
0x00, /* bInterval */
};
/* USB Standard Manufacture Descriptor */
const uint8_t USB_WinUSB_ManufactureDesc[] =
{
0x12, /* bLength */
0x03, /* bDescriptorType */
'F', 0x00, /* BString */
'R', 0x00,
'E', 0x00,
'Q', 0x00,
'C', 0x00,
'H', 0x00,
'I', 0x00,
'P', 0x00,
};
/* USB Standard Configuration Descriptor */
const uint8_t USB_WinUSB_ProductDesc[] =
{
0x20, /* bLength */
0x03, /* bDescriptorType */
'F', 0x00, /* BString */
'R', 0x00,
'E', 0x00,
'Q', 0x00,
'C', 0x00,
'H', 0x00,
'I', 0x00,
'P', 0x00,
'-', 0x00,
'W', 0x00,
'i', 0x00,
'n', 0x00,
'U', 0x00,
'S', 0x00,
'B', 0x00,
};
/* USB Standard Configuration Descriptor */
const uint8_t USB_WinUSB_SerialNumberDesc[] =
{
0x1E, /* bLength */
0x03, /* bDescriptorType */
'2', 0x00, /* BString */
'0', 0x00,
'2', 0x00,
'1', 0x00,
'-', 0x00,
'1', 0x00,
'0', 0x00,
'0', 0x00,
'1', 0x00,
'-', 0x00,
'C', 0x00,
'1', 0x00,
'3', 0x00,
'5', 0x00,
};
/* USB Standard Configuration Descriptor */
const uint8_t USB_WinUSB_LanuageIDDesc[] =
{
0x04, /* bLength */
0x03, /* bDescriptorType */
0x09, /* BString */
0x04,
};
/* Compat ID OS Descriptor */
const uint8_t USB_WinUSB_OSDesc[] =
{
0x12, /* bLength */
0x03, /* bDescriptorType */
'M', 0x00, /* BString */
'S', 0x00,
'F', 0x00,
'T', 0x00,
'1', 0x00,
'0', 0x00,
'0', 0x00,
0x01,
0x00,
};
/* Compat ID OS Descriptor */
const uint8_t WINUSB_Extended_Compat_ID_OS_Feature_Descriptor[] =
{
0x28, 0x00, 0x00, 0x00, // dwLength
0x00, 0x01, // bcdVersion
0x04, 0x00, // wIndex
0x01, // bCount
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Reserved[7]
0x00, // bFirstInterfaceNumber
0x01, // RESERVED ( 0x01 )
'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, // compactiableID[8]
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // subCompactiableID[8]
0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Reserved[6]
};
/* L"DeviceInterfaceGUID" : wIndex = 0x0005 */
/* L"{12345678-1234-1234-1234-123456789ABC}" */
const uint8_t WINUSB_Extended_Property_OS_Feature_Descriptor[142] =
{
0x8E, 0x00, 0x00, 0x00, // dwTotalSize = Header + All sections
0x00, 0x01, // bcdVersion
0x05, 0x00, // wIndex
0x01, 0x00, // wCount
0x84, 0x00, 0x00, 0x00, // dwSize -- this section
0x01, 0x00, 0x00, 0x00, // dwPropertyDataType
0x28, 0x00, // wPropertyNameLength
'D', 0x00, 'e', 0x00, // bProperytName : WCHAR : L"DeviceInterfaceGUID"
'v', 0x00, 'i', 0x00, // bProperytName : WCHAR
'c', 0x00, 'e', 0x00, // bProperytName : WCHAR
'I', 0x00, 'n', 0x00, // bProperytName : WCHAR
't', 0x00, 'e', 0x00, // bProperytName : WCHAR
'r', 0x00, 'f', 0x00, // bProperytName : WCHAR
'a', 0x00, 'c', 0x00, // bProperytName : WCHAR
'e', 0x00, 'G', 0x00, // bProperytName : WCHAR
'U', 0x00, 'I', 0x00, // bProperytName : WCHAR
'D', 0x00, 0x00, 0x00, // bProperytName : WCHAR
0x4E, 0x00, 0x00, 0x00, // dwPropertyDataLength : 78 Bytes = 0x0000004E
'{', 0x00, '1', 0x00, // bPropertyData : WCHAR : L"{12345678-1234-1234-1234-123456789ABC}"
'2', 0x00, '3', 0x00, // bPropertyData
'4', 0x00, '5', 0x00, // bPropertyData
'6', 0x00, '7', 0x00, // bPropertyData
'8', 0x00, '-', 0x00, // bPropertyData
'1', 0x00, '2', 0x00, // bPropertyData
'3', 0x00, '4', 0x00, // bPropertyData
'-', 0x00, '1', 0x00, // bPropertyData
'2', 0x00, '3', 0x00, // bPropertyData
'4', 0x00, '-', 0x00, // bPropertyData
'1', 0x00, '2', 0x00, // bPropertyData
'3', 0x00, '4', 0x00, // bPropertyData
'-', 0x00, '1', 0x00, // bPropertyData
'2', 0x00, '3', 0x00, // bPropertyData
'4', 0x00, '5', 0x00, // bPropertyData
'6', 0x00, '7', 0x00, // bPropertyData
'8', 0x00, '9', 0x00, // bPropertyData
'A', 0x00, 'B', 0x00, // bPropertyData
'C', 0x00, '}', 0x00, // bPropertyData
0x00, 0x00 // bPropertyData
};
/*********************************************************************
* @fn usb_winusb_VendorRequest_Handler
*
* @brief winusb Vendor Request Handler
*
* @param None.
* @return None.
*/
static void usb_winusb_VendorRequest_Handler(usb_StandardRequest_t* pStandardRequest, usb_ReturnData_t* pReturnData)
{
pReturnData->RequestLength = (uint16_t)pStandardRequest->wLength[1] << 8;
pReturnData->RequestLength |= (uint16_t)pStandardRequest->wLength[0];
switch (pStandardRequest->bRequest)
{
case GET_MS_DESCRIPTOR:
{
switch (pStandardRequest->wIndex[0])
{
case EXTENDED_COMPAT_ID:
{
pReturnData->DataBuffer = (uint8_t *)WINUSB_Extended_Compat_ID_OS_Feature_Descriptor;
pReturnData->DataLength = sizeof(WINUSB_Extended_Compat_ID_OS_Feature_Descriptor);
}break;
case EXTENDED_PROPERTIES:
{
pReturnData->DataBuffer = (uint8_t *)WINUSB_Extended_Property_OS_Feature_Descriptor;
pReturnData->DataLength = sizeof(WINUSB_Extended_Property_OS_Feature_Descriptor);
}break;
default: break;
}
}break;
default: break;
}
}
/*********************************************************************
* @fn Endpoint1_Handler
*
* @brief endpoint1 RX TX Handler
*
* @param None.
* @return None.
*/
static void Endpoint1_Handler(uint8_t RxStatus, uint8_t TxStatus)
{
uint8_t lu8_RxCount;
if (RxStatus & ENDPOINT_1_MASK)
{
usb_selecet_endpoint(ENDPOINT_1);
lu8_RxCount = usb_Endpoints_get_RxCount();
usb_read_fifo(ENDPOINT_1, WinUSB_Buffer, lu8_RxCount);
usb_Endpoints_FlushRxFIFO();
if (usb_Endpoints_GET_TxPktRdy() == false)
{
usb_write_fifo(ENDPOINT_1, WinUSB_Buffer, lu8_RxCount);
usb_Endpoints_SET_TxPktRdy();
}
}
}
/*********************************************************************
* @fn usb_winusb_init
*
* @brief winusb device parameter initialization
*
* @param None.
* @return None.
*/
void usb_winusb_init(void)
{
/* Initialize the relevant pointer */
usbdev_get_dev_desc((uint8_t *)USB_WinUSB_DeviceDesc);
usbdev_get_config_desc((uint8_t *)USB_WinUSB_ConfigurationDesc);
usbdev_get_string_Manufacture((uint8_t *)USB_WinUSB_ManufactureDesc);
usbdev_get_string_Product((uint8_t *)USB_WinUSB_ProductDesc);
usbdev_get_string_SerialNumber((uint8_t *)USB_WinUSB_SerialNumberDesc);
usbdev_get_string_LanuageID((uint8_t *)USB_WinUSB_LanuageIDDesc);
usbdev_get_string_OS((uint8_t *)USB_WinUSB_OSDesc);
Endpoint_0_VendorRequest_Handler = usb_winusb_VendorRequest_Handler;
Endpoints_Handler = Endpoint1_Handler;
USB_Reset_Handler = usb_winusb_init;
/* config data endpoint fifo */
usb_selecet_endpoint(ENDPOINT_1);
usb_endpoint_Txfifo_config(0x08, 3);
usb_TxMaxP_set(8);
usb_RxMaxP_set(8);
usb_selecet_endpoint(ENDPOINT_1);
usb_endpoint_Rxfifo_config(0x10, 3);
usb_TxMaxP_set(8);
usb_RxMaxP_set(8);
usb_RxInt_Enable(ENDPOINT_1);
}

Some files were not shown because too many files have changed in this diff Show More