This commit is contained in:
moyuhai
2026-06-11 13:00:46 +08:00
commit e8074162f3
2017 changed files with 507042 additions and 0 deletions
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,265 @@
/*!
* \file xc6xxx.h
*
* \brief CMSIS xc6xxx Device Peripheral Access Layer Header File.
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __XC6xxx_H
#define __XC6xxx_H
#ifdef __cplusplus
extern "C"
{
#endif
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
/** @addtogroup Device_Included
* @{
*/
#if defined(XC60XX)
#include "xc60xx.h"
#elif defined(XC_LORA_XX)
#include "xc_lora_xx.h"
#else
#error \
"Please select first the target XC6xxx device used in your application (in xc6xxx.h file)"
#endif
#include "xc_drv_config.h"
/**
* @}
*/
/*------------------------------------------------------------------------------------
TypeDef
-------------------------------------------------------------------------------------*/
/** @addtogroup Exported_types
* @{
*/
typedef enum
{
RESET = 0,
SET = !RESET
} FlagStatus, ITStatus;
typedef enum
{
XR_OK = 0,
XR_ERROR,
XR_TIMEOUT,
XR_UNKNOWN = 0xFF,
} eXC_RESULT;
/**
* @}
*/
extern __RAM_CODE int sendchar(int c);
/*------------------------------------------------------------------------------------
Macros
-------------------------------------------------------------------------------------*/
/** @addtogroup Exported_macro
* @{
*/
#define GD_FlASH_RDID 0x1364c8
#define SET_BIT(REG, BIT) ((REG) |= (BIT))
#define CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT))
#define READ_BIT(REG, BIT) ((REG) & (BIT))
#define CLEAR_REG(REG) ((REG) = (0x0))
#define WRITE_REG(REG, VAL) ((REG) = (VAL))
#define READ_REG(REG) ((REG))
#define MODIFY_REG(REG, CLEARMASK, SETMASK) \
WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK)))
#define REG_BIT_VAL_GET(REG, MSK, POS) ((REG & MSK) >> POS)
#define BIT_BUILD(VAL, POS, MSK) ((uint32_t)(((VAL) << POS) & MSK))
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) < (b) ? (b) : (a))
// power of 2 macro
#define POW2(pow) (1 << (pow))
// Is A greater than or equal to B macro ?
#define A_MAXEQ_B(a, b) ((a) >= (b))
#define ALIGN_DOWN_ADDR(a, size) (a & (~(size - 1)))
#define ALIGN_UP_ADDR(a, size) ((a + size - 1) & (~(size - 1)))
#ifdef DEBUG_ENABLE
#define DEBUG(fmt, ...) printf(fmt, ##__VA_ARGS__)
#define PRINT(fmt, ...) printf(fmt, ##__VA_ARGS__)
#define RAM_DEBUG(str) \
{ \
const char* s = (str); \
while (*s) { \
sendchar(*s++); \
} \
}
#else
#define DEBUG(fmt, ...)
#define PRINT(fmt, ...)
#endif
#define RSTN_VALID (0UL)
#define RSTN_INVALID (1UL)
#ifndef ENABLE
#define ENABLE 0x01
#endif
#ifndef DISABLE
#define DISABLE 0x00
#endif
#ifndef RSTCTL_ENABLE
#define RSTCTL_ENABLE 0x00
#endif
#ifndef RSTCTL_DISABLE
#define RSTCTL_DISABLE 0x01
#endif
#ifndef ASSERT_ERR
#define ASSERT_ERR(cond) \
{ \
}
#endif
/** @brief Enable interrupts globally in the system.
* This macro must be used when the initialization phase is over and the interrupts
* can start being handled by the system.
*/
#define GLOBAL_INT_START() ; \
do { \
__enable_irq(); \
} while(0);
#define GLOBAL_INT_STOP() ; \
do { \
__disable_irq(); \
} while(0);
#define GLOBAL_INT_DISABLE() ; \
do { \
uint32_t irq_temp; \
irq_temp = __disable_irq();
#define GLOBAL_INT_RESTORE() ; \
if(!irq_temp) \
{ \
__enable_irq(); \
} \
} while(0);
/**
* @}
*/
#include "xc_drv_conf.h"
/**
* @brief HAL Status structures definition
*/
typedef enum
{
HAL_OK = 0x00U,
HAL_ERROR = 0x01U,
HAL_BUSY = 0x02U,
HAL_TIMEOUT = 0x03U
} HAL_StatusTypeDef;
/**
* @brief HAL Lock structures definition
*/
typedef enum
{
HAL_UNLOCKED = 0x00U,
HAL_LOCKED = 0x01U
} HAL_LockTypeDef;
#define UNUSED(X) (void)X /* To avoid gcc/g++ warnings */
#define HAL_Delay delay_ms
void HAL_Delay(unsigned int Delay);
void Error_Handler(void);
#define __HAL_LOCK(__HANDLE__) \
do { \
if ((__HANDLE__)->Lock == HAL_LOCKED) { \
return HAL_BUSY; \
} else { \
(__HANDLE__)->Lock = HAL_LOCKED; \
} \
} while (0U)
#define __HAL_UNLOCK(__HANDLE__) \
do { \
(__HANDLE__)->Lock = HAL_UNLOCKED; \
} while (0U)
/* Macro to get variable aligned on 4-bytes, for __ICCARM__ the directive
* "#pragma data_alignment=4" must be used instead */
#if defined(__ARMCC_VERSION) && \
(__ARMCC_VERSION >= 6010050) /* ARM Compiler V6 */
#ifndef __ALIGN_BEGIN
#define __ALIGN_BEGIN
#endif
#ifndef __ALIGN_END
#define __ALIGN_END __attribute__((aligned(4)))
#endif
#elif defined(__GNUC__) && !defined(__CC_ARM) /* GNU Compiler */
#ifndef __ALIGN_END
#define __ALIGN_END __attribute__((aligned(4)))
#endif /* __ALIGN_END */
#ifndef __ALIGN_BEGIN
#define __ALIGN_BEGIN
#endif /* __ALIGN_BEGIN */
#else
#ifndef __ALIGN_END
#define __ALIGN_END
#endif /* __ALIGN_END */
#ifndef __ALIGN_BEGIN
#if defined(__CC_ARM) /* ARM Compiler V5*/
#define __ALIGN_BEGIN __align(4)
#elif defined(__ICCARM__) /* IAR Compiler */
#define __ALIGN_BEGIN
#endif /* __CC_ARM */
#endif /* __ALIGN_BEGIN */
#endif /* __GNUC__ */
#ifdef __cplusplus
}
#endif
#endif /* __XC6xxx_H */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,807 @@
#ifndef _XC_REG_ADC_H_
#define _XC_REG_ADC_H_
#include <stdint.h>
#define XC_REG_ADC_BASE_ADDR 0x40018000
#define XC_REG_ADC_DECODING_MASK 0x0000003F
/**
* @brief ADC_MAIN_CTL register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 15:12 EXT_SAMPLE_NUM 0x0
* 11 EXT_DATA_MODE 0
* 10:08 EXT_TRIGGER_SEL 0x0
* 05:04 EXT_EDGE_SEL 0x0
* 03 EDGE_SEL 0
* 02 AUTO_SW 0
* 01 DMAS_ON 0
* 00 ADC_EN 0
* </pre>
*/
#define ADC_MAIN_CTL_REG (*(volatile uint32_t *)(0x40018000))
#define ADC_MAIN_CTL_ADDR 0x40018000
#define ADC_MAIN_CTL_OFFSET 0x00000000
__INLINE uint32_t adc_main_ctl_get(void)
{
return ADC_MAIN_CTL_REG;
}
__INLINE void adc_main_ctl_set(uint32_t value)
{
ADC_MAIN_CTL_REG = value;
}
// field definitions
#define EXT_SAMPLE_NUM_MASK 0x0000F000
#define EXT_SAMPLE_NUM_LSB 12
#define EXT_SAMPLE_NUM_WIDTH 0x00000004
#define EXT_DATA_MODE_BIT 0x00000800
#define EXT_DATA_MODE_POS 11
#define EXT_TRIGGER_SEL_MASK 0x00000700
#define EXT_TRIGGER_SEL_LSB 8
#define EXT_TRIGGER_SEL_WIDTH 0x00000003
#define EXT_EDGE_SEL_MASK 0x00000030
#define EXT_EDGE_SEL_LSB 4
#define EXT_EDGE_SEL_WIDTH 0x00000002
#define EDGE_SEL_BIT 0x00000008
#define EDGE_SEL_POS 3
#define AUTO_SW_BIT 0x00000004
#define AUTO_SW_POS 2
#define DMAS_ON_BIT 0x00000002
#define DMAS_ON_POS 1
#define ADC_EN_BIT 0x00000001
#define ADC_EN_POS 0
#define EXT_SAMPLE_NUM_RST 0x0
#define EXT_DATA_MODE_RST 0x0
#define EXT_TRIGGER_SEL_RST 0x0
#define EXT_EDGE_SEL_RST 0x0
#define EDGE_SEL_RST 0x0
#define AUTO_SW_RST 0x0
#define DMAS_ON_RST 0x0
#define ADC_EN_RST 0x0
__INLINE void adc_main_ctl_pack(uint8_t ext_sample_num, uint8_t ext_data_mode, uint8_t ext_trigger_sel, uint8_t ext_edge_sel, uint8_t edge_sel, uint8_t auto_sw, uint8_t dmas_on, uint8_t adc_en)
{
ASSERT_ERR(((ext_sample_num << 12) & ~0x0000F000) == 0);
ASSERT_ERR(((ext_data_mode << 11) & ~0x00000800) == 0);
ASSERT_ERR(((ext_trigger_sel << 8) & ~0x00000700) == 0);
ASSERT_ERR(((ext_edge_sel << 4) & ~0x00000030) == 0);
ASSERT_ERR(((edge_sel << 3) & ~0x00000008) == 0);
ASSERT_ERR(((auto_sw << 2) & ~0x00000004) == 0);
ASSERT_ERR(((dmas_on << 1) & ~0x00000002) == 0);
ASSERT_ERR(((adc_en << 0) & ~0x00000001) == 0);
ADC_MAIN_CTL_REG = (ext_sample_num << 12) | (ext_data_mode << 11) | (ext_trigger_sel << 8) | (ext_edge_sel << 4) | (edge_sel << 3) | (auto_sw << 2) | (dmas_on << 1) | (adc_en << 0);
}
__INLINE void adc_main_ctl_unpack(uint8_t* ext_sample_num, uint8_t* ext_data_mode, uint8_t* ext_trigger_sel, uint8_t* ext_edge_sel, uint8_t* edge_sel, uint8_t* auto_sw, uint8_t* dmas_on, uint8_t* adc_en)
{
uint32_t localVal = ADC_MAIN_CTL_REG;
*ext_sample_num = (localVal & 0x0000F000) >> 12;
*ext_data_mode = (localVal & 0x00000800) >> 11;
*ext_trigger_sel = (localVal & 0x00000700) >> 8;
*ext_edge_sel = (localVal & 0x00000030) >> 4;
*edge_sel = (localVal & 0x00000008) >> 3;
*auto_sw = (localVal & 0x00000004) >> 2;
*dmas_on = (localVal & 0x00000002) >> 1;
*adc_en = (localVal & 0x00000001) >> 0;
}
__INLINE uint8_t adc_main_ctl__ext_sample_num__getf(void)
{
uint32_t localVal = ADC_MAIN_CTL_REG;
return ((localVal & 0x0000F000) >> 12);
}
__INLINE void adc_main_ctl__ext_sample_num__setf(uint8_t ext_sample_num)
{
ASSERT_ERR(((ext_sample_num << 12) & ~0x0000F000) == 0);
ADC_MAIN_CTL_REG = (ADC_MAIN_CTL_REG & ~0x0000F000) | (ext_sample_num << 12);
}
__INLINE uint8_t adc_main_ctl__ext_data_mode__getf(void)
{
uint32_t localVal = ADC_MAIN_CTL_REG;
return ((localVal & 0x00000800) >> 11);
}
__INLINE void adc_main_ctl__ext_data_mode__setf(uint8_t ext_data_mode)
{
ASSERT_ERR(((ext_data_mode << 11) & ~0x00000800) == 0);
ADC_MAIN_CTL_REG = (ADC_MAIN_CTL_REG & ~0x00000800) | (ext_data_mode << 11);
}
__INLINE uint8_t adc_main_ctl__ext_trigger_sel__getf(void)
{
uint32_t localVal = ADC_MAIN_CTL_REG;
return ((localVal & 0x00000700) >> 8);
}
__INLINE void adc_main_ctl__ext_trigger_sel__setf(uint8_t ext_trigger_sel)
{
ASSERT_ERR(((ext_trigger_sel << 8) & ~0x00000700) == 0);
ADC_MAIN_CTL_REG = (ADC_MAIN_CTL_REG & ~0x00000700) | (ext_trigger_sel << 8);
}
__INLINE uint8_t adc_main_ctl__ext_edge_sel__getf(void)
{
uint32_t localVal = ADC_MAIN_CTL_REG;
return ((localVal & 0x00000030) >> 4);
}
__INLINE void adc_main_ctl__ext_edge_sel__setf(uint8_t ext_edge_sel)
{
ASSERT_ERR(((ext_edge_sel << 4) & ~0x00000030) == 0);
ADC_MAIN_CTL_REG = (ADC_MAIN_CTL_REG & ~0x00000030) | (ext_edge_sel << 4);
}
__INLINE uint8_t adc_main_ctl__edge_sel__getf(void)
{
uint32_t localVal = ADC_MAIN_CTL_REG;
return ((localVal & 0x00000008) >> 3);
}
__INLINE void adc_main_ctl__edge_sel__setf(uint8_t edge_sel)
{
ASSERT_ERR(((edge_sel << 3) & ~0x00000008) == 0);
ADC_MAIN_CTL_REG = (ADC_MAIN_CTL_REG & ~0x00000008) | (edge_sel << 3);
}
__INLINE uint8_t adc_main_ctl__auto_sw__getf(void)
{
uint32_t localVal = ADC_MAIN_CTL_REG;
return ((localVal & 0x00000004) >> 2);
}
__INLINE void adc_main_ctl__auto_sw__setf(uint8_t auto_sw)
{
ASSERT_ERR(((auto_sw << 2) & ~0x00000004) == 0);
ADC_MAIN_CTL_REG = (ADC_MAIN_CTL_REG & ~0x00000004) | (auto_sw << 2);
}
__INLINE uint8_t adc_main_ctl__dmas_on__getf(void)
{
uint32_t localVal = ADC_MAIN_CTL_REG;
return ((localVal & 0x00000002) >> 1);
}
__INLINE void adc_main_ctl__dmas_on__setf(uint8_t dmas_on)
{
ASSERT_ERR(((dmas_on << 1) & ~0x00000002) == 0);
ADC_MAIN_CTL_REG = (ADC_MAIN_CTL_REG & ~0x00000002) | (dmas_on << 1);
}
__INLINE uint8_t adc_main_ctl__adc_en__getf(void)
{
uint32_t localVal = ADC_MAIN_CTL_REG;
return ((localVal & 0x00000001) >> 0);
}
__INLINE void adc_main_ctl__adc_en__setf(uint8_t adc_en)
{
ASSERT_ERR(((adc_en << 0) & ~0x00000001) == 0);
ADC_MAIN_CTL_REG = (ADC_MAIN_CTL_REG & ~0x00000001) | (adc_en << 0);
}
/**
* @brief ADC_CHAN_CTL register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 11:08 CHAN_AUTO 0x0
* 05:04 VCM_CHAN_AUTO 0x0
* 03:00 SELECT_CHAN 0x0
* </pre>
*/
#define ADC_CHAN_CTL_REG (*(volatile uint32_t *)(0x40018004))
#define ADC_CHAN_CTL_ADDR 0x40018004
#define ADC_CHAN_CTL_OFFSET 0x00000004
__INLINE uint32_t adc_chan_ctl_get(void)
{
return ADC_CHAN_CTL_REG;
}
__INLINE void adc_chan_ctl_set(uint32_t value)
{
ADC_CHAN_CTL_REG = value;
}
// field definitions
#define CHAN_AUTO_MASK 0x00000F00
#define CHAN_AUTO_LSB 8
#define CHAN_AUTO_WIDTH 0x00000004
#define VCM_CHAN_AUTO_MASK 0x00000030
#define VCM_CHAN_AUTO_LSB 4
#define VCM_CHAN_AUTO_WIDTH 0x00000002
#define SELECT_CHAN_MASK 0x0000000F
#define SELECT_CHAN_LSB 0
#define SELECT_CHAN_WIDTH 0x00000004
#define CHAN_AUTO_RST 0x0
#define VCM_CHAN_AUTO_RST 0x0
#define SELECT_CHAN_RST 0x0
__INLINE void adc_chan_ctl_pack(uint8_t chan_auto, uint8_t vcm_chan_auto, uint8_t select_chan)
{
ASSERT_ERR(((chan_auto << 8) & ~0x00000F00) == 0);
ASSERT_ERR(((vcm_chan_auto << 4) & ~0x00000030) == 0);
ASSERT_ERR(((select_chan << 0) & ~0x0000000F) == 0);
ADC_CHAN_CTL_REG = (chan_auto << 8) | (vcm_chan_auto << 4) | (select_chan << 0);
}
__INLINE void adc_chan_ctl_unpack(uint8_t* chan_auto, uint8_t* vcm_chan_auto, uint8_t* select_chan)
{
uint32_t localVal = ADC_CHAN_CTL_REG;
*chan_auto = (localVal & 0x00000F00) >> 8;
*vcm_chan_auto = (localVal & 0x00000030) >> 4;
*select_chan = (localVal & 0x0000000F) >> 0;
}
__INLINE uint8_t adc_chan_ctl__chan_auto__getf(void)
{
uint32_t localVal = ADC_CHAN_CTL_REG;
return ((localVal & 0x00000F00) >> 8);
}
__INLINE void adc_chan_ctl__chan_auto__setf(uint8_t chan_auto)
{
ASSERT_ERR(((chan_auto << 8) & ~0x00000F00) == 0);
ADC_CHAN_CTL_REG = (ADC_CHAN_CTL_REG & ~0x00000F00) | (chan_auto << 8);
}
__INLINE uint8_t adc_chan_ctl__vcm_chan_auto__getf(void)
{
uint32_t localVal = ADC_CHAN_CTL_REG;
return ((localVal & 0x00000030) >> 4);
}
__INLINE void adc_chan_ctl__vcm_chan_auto__setf(uint8_t vcm_chan_auto)
{
ASSERT_ERR(((vcm_chan_auto << 4) & ~0x00000030) == 0);
ADC_CHAN_CTL_REG = (ADC_CHAN_CTL_REG & ~0x00000030) | (vcm_chan_auto << 4);
}
__INLINE uint8_t adc_chan_ctl__select_chan__getf(void)
{
uint32_t localVal = ADC_CHAN_CTL_REG;
return ((localVal & 0x0000000F) >> 0);
}
__INLINE void adc_chan_ctl__select_chan__setf(uint8_t select_chan)
{
ASSERT_ERR(((select_chan << 0) & ~0x0000000F) == 0);
ADC_CHAN_CTL_REG = (ADC_CHAN_CTL_REG & ~0x0000000F) | (select_chan << 0);
}
/**
* @brief ADC_FIFO_CTL register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 04 FIFO_FLUSH 0
* 03:00 READ_REQ_THRESH 0x0
* </pre>
*/
#define ADC_FIFO_CTL_REG (*(volatile uint32_t *)(0x40018008))
#define ADC_FIFO_CTL_ADDR 0x40018008
#define ADC_FIFO_CTL_OFFSET 0x00000008
__INLINE uint32_t adc_fifo_ctl_get(void)
{
return ADC_FIFO_CTL_REG;
}
__INLINE void adc_fifo_ctl_set(uint32_t value)
{
ADC_FIFO_CTL_REG = value;
}
// field definitions
#define FIFO_FLUSH_BIT 0x00000010
#define FIFO_FLUSH_POS 4
#define READ_REQ_THRESH_MASK 0x0000000F
#define READ_REQ_THRESH_LSB 0
#define READ_REQ_THRESH_WIDTH 0x00000004
#define FIFO_FLUSH_RST 0x0
#define READ_REQ_THRESH_RST 0x0
__INLINE void adc_fifo_ctl_pack(uint8_t fifo_flush, uint8_t read_req_thresh)
{
ASSERT_ERR(((fifo_flush << 4) & ~0x00000010) == 0);
ASSERT_ERR(((read_req_thresh << 0) & ~0x0000000F) == 0);
ADC_FIFO_CTL_REG = (fifo_flush << 4) | (read_req_thresh << 0);
}
__INLINE void adc_fifo_ctl_unpack(uint8_t* fifo_flush, uint8_t* read_req_thresh)
{
uint32_t localVal = ADC_FIFO_CTL_REG;
*fifo_flush = (localVal & 0x00000010) >> 4;
*read_req_thresh = (localVal & 0x0000000F) >> 0;
}
__INLINE uint8_t adc_fifo_ctl__fifo_flush__getf(void)
{
uint32_t localVal = ADC_FIFO_CTL_REG;
return ((localVal & 0x00000010) >> 4);
}
__INLINE void adc_fifo_ctl__fifo_flush__setf(uint8_t fifo_flush)
{
ASSERT_ERR(((fifo_flush << 4) & ~0x00000010) == 0);
ADC_FIFO_CTL_REG = (ADC_FIFO_CTL_REG & ~0x00000010) | (fifo_flush << 4);
}
__INLINE uint8_t adc_fifo_ctl__read_req_thresh__getf(void)
{
uint32_t localVal = ADC_FIFO_CTL_REG;
return ((localVal & 0x0000000F) >> 0);
}
__INLINE void adc_fifo_ctl__read_req_thresh__setf(uint8_t read_req_thresh)
{
ASSERT_ERR(((read_req_thresh << 0) & ~0x0000000F) == 0);
ADC_FIFO_CTL_REG = (ADC_FIFO_CTL_REG & ~0x0000000F) | (read_req_thresh << 0);
}
/**
* @brief ADC_TIMER0 register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 07:00 SW_WAIT_CNT 0x0
* </pre>
*/
#define ADC_TIMER0_REG (*(volatile uint32_t *)(0x4001800C))
#define ADC_TIMER0_ADDR 0x4001800C
#define ADC_TIMER0_OFFSET 0x0000000C
__INLINE uint32_t adc_timer0_get(void)
{
return ADC_TIMER0_REG;
}
__INLINE void adc_timer0_set(uint32_t value)
{
ADC_TIMER0_REG = value;
}
// field definitions
#define SW_WAIT_CNT_MASK 0x000000FF
#define SW_WAIT_CNT_LSB 0
#define SW_WAIT_CNT_WIDTH 0x00000008
#define SW_WAIT_CNT_RST 0x0
__INLINE uint8_t adc_timer0__sw_wait_cnt__getf(void)
{
uint32_t localVal = ADC_TIMER0_REG;
ASSERT_ERR((localVal & ~0x000000FF) == 0);
return (localVal >> 0);
}
__INLINE void adc_timer0__sw_wait_cnt__setf(uint8_t sw_wait_cnt)
{
ASSERT_ERR(((sw_wait_cnt << 0) & ~0x000000FF) == 0);
ADC_TIMER0_REG = sw_wait_cnt << 0;
}
/**
* @brief ADC_TIMER1 register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 15:00 AUTO_SW_CNT 0x0
* </pre>
*/
#define ADC_TIMER1_REG (*(volatile uint32_t *)(0x40018010))
#define ADC_TIMER1_ADDR 0x40018010
#define ADC_TIMER1_OFFSET 0x00000010
__INLINE uint32_t adc_timer1_get(void)
{
return ADC_TIMER1_REG;
}
__INLINE void adc_timer1_set(uint32_t value)
{
ADC_TIMER1_REG = value;
}
// field definitions
#define AUTO_SW_CNT_MASK 0x0000FFFF
#define AUTO_SW_CNT_LSB 0
#define AUTO_SW_CNT_WIDTH 0x00000010
#define AUTO_SW_CNT_RST 0x0
__INLINE uint16_t adc_timer1__auto_sw_cnt__getf(void)
{
uint32_t localVal = ADC_TIMER1_REG;
ASSERT_ERR((localVal & ~0x0000FFFF) == 0);
return (localVal >> 0);
}
__INLINE void adc_timer1__auto_sw_cnt__setf(uint16_t auto_sw_cnt)
{
ASSERT_ERR(((auto_sw_cnt << 0) & ~0x0000FFFF) == 0);
ADC_TIMER1_REG = auto_sw_cnt << 0;
}
/**
* @brief ADC_INT register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 01 FIFO_ERROR_INT 0
* 00 READ_REQ_INT 0
* </pre>
*/
#define ADC_INT_REG (*(volatile uint32_t *)(0x40018014))
#define ADC_INT_ADDR 0x40018014
#define ADC_INT_OFFSET 0x00000014
__INLINE uint32_t adc_int_get(void)
{
return ADC_INT_REG;
}
__INLINE void adc_int_set(uint32_t value)
{
ADC_INT_REG = value;
}
// field definitions
#define FIFO_ERROR_INT_BIT 0x00000002
#define FIFO_ERROR_INT_POS 1
#define READ_REQ_INT_BIT 0x00000001
#define READ_REQ_INT_POS 0
#define FIFO_ERROR_INT_RST 0x0
#define READ_REQ_INT_RST 0x0
__INLINE void adc_int_pack(uint8_t fifo_error_int, uint8_t read_req_int)
{
ASSERT_ERR(((fifo_error_int << 1) & ~0x00000002) == 0);
ASSERT_ERR(((read_req_int << 0) & ~0x00000001) == 0);
ADC_INT_REG = (fifo_error_int << 1) | (read_req_int << 0);
}
__INLINE void adc_int_unpack(uint8_t* fifo_error_int, uint8_t* read_req_int)
{
uint32_t localVal = ADC_INT_REG;
*fifo_error_int = (localVal & 0x00000002) >> 1;
*read_req_int = (localVal & 0x00000001) >> 0;
}
__INLINE uint8_t adc_int__fifo_error_int__getf(void)
{
uint32_t localVal = ADC_INT_REG;
return ((localVal & 0x00000002) >> 1);
}
__INLINE void adc_int__fifo_error_int__setf(uint8_t fifo_error_int)
{
ASSERT_ERR(((fifo_error_int << 1) & ~0x00000002) == 0);
ADC_INT_REG = (ADC_INT_REG & ~0x00000002) | (fifo_error_int << 1);
}
__INLINE uint8_t adc_int__read_req_int__getf(void)
{
uint32_t localVal = ADC_INT_REG;
return ((localVal & 0x00000001) >> 0);
}
__INLINE void adc_int__read_req_int__setf(uint8_t read_req_int)
{
ASSERT_ERR(((read_req_int << 0) & ~0x00000001) == 0);
ADC_INT_REG = (ADC_INT_REG & ~0x00000001) | (read_req_int << 0);
}
/**
* @brief ADC_INT_RAW register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 01 FIFO_ERROR_RAW 0
* 00 READ_REQ_RAW 0
* </pre>
*/
#define ADC_INT_RAW_REG (*(volatile uint32_t *)(0x40018018))
#define ADC_INT_RAW_ADDR 0x40018018
#define ADC_INT_RAW_OFFSET 0x00000018
__INLINE uint32_t adc_int_raw_get(void)
{
return ADC_INT_RAW_REG;
}
// field definitions
#define FIFO_ERROR_RAW_BIT 0x00000002
#define FIFO_ERROR_RAW_POS 1
#define READ_REQ_RAW_BIT 0x00000001
#define READ_REQ_RAW_POS 0
#define FIFO_ERROR_RAW_RST 0x0
#define READ_REQ_RAW_RST 0x0
__INLINE void adc_int_raw_unpack(uint8_t* fifo_error_raw, uint8_t* read_req_raw)
{
uint32_t localVal = ADC_INT_RAW_REG;
*fifo_error_raw = (localVal & 0x00000002) >> 1;
*read_req_raw = (localVal & 0x00000001) >> 0;
}
__INLINE uint8_t adc_int_raw__fifo_error_raw__getf(void)
{
uint32_t localVal = ADC_INT_RAW_REG;
return ((localVal & 0x00000002) >> 1);
}
__INLINE uint8_t adc_int_raw__read_req_raw__getf(void)
{
uint32_t localVal = ADC_INT_RAW_REG;
return ((localVal & 0x00000001) >> 0);
}
/**
* @brief ADC_INT_EN register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 01 FIFO_ERROR_EN 0
* 00 READ_REQ_EN 0
* </pre>
*/
#define ADC_INT_EN_REG (*(volatile uint32_t *)(0x4001801C))
#define ADC_INT_EN_ADDR 0x4001801C
#define ADC_INT_EN_OFFSET 0x0000001C
__INLINE uint32_t adc_int_en_get(void)
{
return ADC_INT_EN_REG;
}
__INLINE void adc_int_en_set(uint32_t value)
{
ADC_INT_EN_REG = value;
}
// field definitions
#define FIFO_ERROR_EN_BIT 0x00000002
#define FIFO_ERROR_EN_POS 1
#define READ_REQ_EN_BIT 0x00000001
#define READ_REQ_EN_POS 0
#define FIFO_ERROR_EN_RST 0x0
#define READ_REQ_EN_RST 0x0
__INLINE void adc_int_en_pack(uint8_t fifo_error_en, uint8_t read_req_en)
{
ASSERT_ERR(((fifo_error_en << 1) & ~0x00000002) == 0);
ASSERT_ERR(((read_req_en << 0) & ~0x00000001) == 0);
ADC_INT_EN_REG = (fifo_error_en << 1) | (read_req_en << 0);
}
__INLINE void adc_int_en_unpack(uint8_t* fifo_error_en, uint8_t* read_req_en)
{
uint32_t localVal = ADC_INT_EN_REG;
*fifo_error_en = (localVal & 0x00000002) >> 1;
*read_req_en = (localVal & 0x00000001) >> 0;
}
__INLINE uint8_t adc_int_en__fifo_error_en__getf(void)
{
uint32_t localVal = ADC_INT_EN_REG;
return ((localVal & 0x00000002) >> 1);
}
__INLINE void adc_int_en__fifo_error_en__setf(uint8_t fifo_error_en)
{
ASSERT_ERR(((fifo_error_en << 1) & ~0x00000002) == 0);
ADC_INT_EN_REG = (ADC_INT_EN_REG & ~0x00000002) | (fifo_error_en << 1);
}
__INLINE uint8_t adc_int_en__read_req_en__getf(void)
{
uint32_t localVal = ADC_INT_EN_REG;
return ((localVal & 0x00000001) >> 0);
}
__INLINE void adc_int_en__read_req_en__setf(uint8_t read_req_en)
{
ASSERT_ERR(((read_req_en << 0) & ~0x00000001) == 0);
ADC_INT_EN_REG = (ADC_INT_EN_REG & ~0x00000001) | (read_req_en << 0);
}
/**
* @brief ADC_FIFO register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 31:00 FIFO_DOUT 0x0
* </pre>
*/
#define ADC_FIFO_REG (*(volatile uint32_t *)(0x40018020))
#define ADC_FIFO_ADDR 0x40018020
#define ADC_FIFO_OFFSET 0x00000020
__INLINE uint32_t adc_fifo_get(void)
{
return ADC_FIFO_REG;
}
// field definitions
#define FIFO_DOUT_MASK 0xFFFFFFFF
#define FIFO_DOUT_LSB 0
#define FIFO_DOUT_WIDTH 0x00000020
#define FIFO_DOUT_RST 0x0
__INLINE uint32_t adc_fifo__fifo_dout__getf(void)
{
uint32_t localVal = ADC_FIFO_REG;
ASSERT_ERR((localVal & ~0xFFFFFFFF) == 0);
return (localVal >> 0);
}
/**
* @brief ADC_RF_CTL register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 15:08 adc_clkdiv 0x0
* 04 ADC_ctl_mux 0
* 03 rst_ADC 0
* 02 diffsel_ADC 0
* 01 gadc_vref_sel 0
* 00 pd_ADC 0
* </pre>
*/
#define ADC_RF_CTL_REG (*(volatile uint32_t *)(0x40018024))
#define ADC_RF_CTL_ADDR 0x40018024
#define ADC_RF_CTL_OFFSET 0x00000024
__INLINE uint32_t adc_rf_ctl_get(void)
{
return ADC_RF_CTL_REG;
}
__INLINE void adc_rf_ctl_set(uint32_t value)
{
ADC_RF_CTL_REG = value;
}
// field definitions
#define ADC_CLKDIV_MASK 0x0000FF00
#define ADC_CLKDIV_LSB 8
#define ADC_CLKDIV_WIDTH 0x00000008
#define ADC_CTL_MUX_BIT 0x00000010
#define ADC_CTL_MUX_POS 4
#define RST_ADC_BIT 0x00000008
#define RST_ADC_POS 3
#define DIFFSEL_ADC_BIT 0x00000004
#define DIFFSEL_ADC_POS 2
#define GADC_VREF_SEL_BIT 0x00000002
#define GADC_VREF_SEL_POS 1
#define PD_ADC_BIT 0x00000001
#define PD_ADC_POS 0
#define ADC_CLKDIV_RST 0x0
#define ADC_CTL_MUX_RST 0x0
#define RST_ADC_RST 0x0
#define DIFFSEL_ADC_RST 0x0
#define GADC_VREF_SEL_RST 0x0
#define PD_ADC_RST 0x0
__INLINE void adc_rf_ctl_pack(uint8_t adc_clkdiv, uint8_t adc_ctl_mux, uint8_t rst_adc, uint8_t diffsel_adc, uint8_t gadc_vref_sel, uint8_t pd_adc)
{
ASSERT_ERR(((adc_clkdiv << 8) & ~0x0000FF00) == 0);
ASSERT_ERR(((adc_ctl_mux << 4) & ~0x00000010) == 0);
ASSERT_ERR(((rst_adc << 3) & ~0x00000008) == 0);
ASSERT_ERR(((diffsel_adc << 2) & ~0x00000004) == 0);
ASSERT_ERR(((gadc_vref_sel << 1) & ~0x00000002) == 0);
ASSERT_ERR(((pd_adc << 0) & ~0x00000001) == 0);
ADC_RF_CTL_REG = (adc_clkdiv << 8) | (adc_ctl_mux << 4) | (rst_adc << 3) | (diffsel_adc << 2) | (gadc_vref_sel << 1) | (pd_adc << 0);
}
__INLINE void adc_rf_ctl_unpack(uint8_t* adc_clkdiv, uint8_t* adc_ctl_mux, uint8_t* rst_adc, uint8_t* diffsel_adc, uint8_t* gadc_vref_sel, uint8_t* pd_adc)
{
uint32_t localVal = ADC_RF_CTL_REG;
*adc_clkdiv = (localVal & 0x0000FF00) >> 8;
*adc_ctl_mux = (localVal & 0x00000010) >> 4;
*rst_adc = (localVal & 0x00000008) >> 3;
*diffsel_adc = (localVal & 0x00000004) >> 2;
*gadc_vref_sel = (localVal & 0x00000002) >> 1;
*pd_adc = (localVal & 0x00000001) >> 0;
}
__INLINE uint8_t adc_rf_ctl__adc_clkdiv__getf(void)
{
uint32_t localVal = ADC_RF_CTL_REG;
return ((localVal & 0x0000FF00) >> 8);
}
__INLINE void adc_rf_ctl__adc_clkdiv__setf(uint8_t adc_clkdiv)
{
ASSERT_ERR(((adc_clkdiv << 8) & ~0x0000FF00) == 0);
ADC_RF_CTL_REG = (ADC_RF_CTL_REG & ~0x0000FF00) | (adc_clkdiv << 8);
}
__INLINE uint8_t adc_rf_ctl__adc_ctl_mux__getf(void)
{
uint32_t localVal = ADC_RF_CTL_REG;
return ((localVal & 0x00000010) >> 4);
}
__INLINE void adc_rf_ctl__adc_ctl_mux__setf(uint8_t adc_ctl_mux)
{
ASSERT_ERR(((adc_ctl_mux << 4) & ~0x00000010) == 0);
ADC_RF_CTL_REG = (ADC_RF_CTL_REG & ~0x00000010) | (adc_ctl_mux << 4);
}
__INLINE uint8_t adc_rf_ctl__rst_adc__getf(void)
{
uint32_t localVal = ADC_RF_CTL_REG;
return ((localVal & 0x00000008) >> 3);
}
__INLINE void adc_rf_ctl__rst_adc__setf(uint8_t rst_adc)
{
ASSERT_ERR(((rst_adc << 3) & ~0x00000008) == 0);
ADC_RF_CTL_REG = (ADC_RF_CTL_REG & ~0x00000008) | (rst_adc << 3);
}
__INLINE uint8_t adc_rf_ctl__diffsel_adc__getf(void)
{
uint32_t localVal = ADC_RF_CTL_REG;
return ((localVal & 0x00000004) >> 2);
}
__INLINE void adc_rf_ctl__diffsel_adc__setf(uint8_t diffsel_adc)
{
ASSERT_ERR(((diffsel_adc << 2) & ~0x00000004) == 0);
ADC_RF_CTL_REG = (ADC_RF_CTL_REG & ~0x00000004) | (diffsel_adc << 2);
}
__INLINE uint8_t adc_rf_ctl__gadc_vref_sel__getf(void)
{
uint32_t localVal = ADC_RF_CTL_REG;
return ((localVal & 0x00000002) >> 1);
}
__INLINE void adc_rf_ctl__gadc_vref_sel__setf(uint8_t gadc_vref_sel)
{
ASSERT_ERR(((gadc_vref_sel << 1) & ~0x00000002) == 0);
ADC_RF_CTL_REG = (ADC_RF_CTL_REG & ~0x00000002) | (gadc_vref_sel << 1);
}
__INLINE uint8_t adc_rf_ctl__pd_adc__getf(void)
{
uint32_t localVal = ADC_RF_CTL_REG;
return ((localVal & 0x00000001) >> 0);
}
__INLINE void adc_rf_ctl__pd_adc__setf(uint8_t pd_adc)
{
ASSERT_ERR(((pd_adc << 0) & ~0x00000001) == 0);
ADC_RF_CTL_REG = (ADC_RF_CTL_REG & ~0x00000001) | (pd_adc << 0);
}
#endif // _XC_REG_ADC_H_
@@ -0,0 +1,208 @@
#ifndef _XC_REG_AOTIMER_H_
#define _XC_REG_AOTIMER_H_
#include <stdint.h>
#include "xc6xxx.h"
#define XC_REG_AOTIMER_BASE_ADDR 0x40002800
#define XC_REG_AOTIMER_DECODING_MASK 0x0000001F
/**
* @brief AOTIMER_TLC register definition
*/
#define AOTIMER_TLC_REG(i) (*(volatile uint32_t *)(0x40002800 + aotimer_offset[i]))
#define AOTIMER_TLC_ADDR(i) (0x40002800 + aotimer_offset[i])
#define AOTIMER_TLC_OFFSET 0x00000000
__INLINE uint32_t aotimer_tlc_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 1);
return AOTIMER_TLC_REG(reg_idx);
}
__INLINE void aotimer_tlc_set(uint32_t reg_idx, uint32_t value)
{
ASSERT_ERR(reg_idx <= 1);
AOTIMER_TLC_REG(reg_idx) = value;
}
/**
* @brief AOTIMER_TCV register definition
*/
#define AOTIMER_TCV_REG(i) (*(volatile uint32_t *)(0x40002804 + aotimer_offset[i]))
#define AOTIMER_TCV_ADDR(i) (0x40002804 + aotimer_offset[i])
#define AOTIMER_TCV_OFFSET 0x00000004
__INLINE uint32_t aotimer_tcv_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 1);
return AOTIMER_TCV_REG(reg_idx);
}
/**
* @brief AOTIMER_TCR register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 02 TIM 0
* 01 TMS 0
* 00 TES 0
* </pre>
*/
#define AOTIMER_TCR_REG(i) (*(volatile uint32_t *)(0x40002808 + aotimer_offset[i]))
#define AOTIMER_TCR_ADDR(i) (0x40002808 + aotimer_offset[i])
#define AOTIMER_TCR_OFFSET 0x00000008
__INLINE uint32_t aotimer_tcr_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 1);
return AOTIMER_TCR_REG(reg_idx);
}
__INLINE void aotimer_tcr_set(uint32_t reg_idx, uint32_t value)
{
ASSERT_ERR(reg_idx <= 1);
AOTIMER_TCR_REG(reg_idx) = value;
}
// field definitions
#define TIM_BIT 0x00000004
#define TIM_POS 2
#define TMS_BIT 0x00000002
#define TMS_POS 1
#define TES_BIT 0x00000001
#define TES_POS 0
#define TIM_RST 0x0
#define TMS_RST 0x0
#define TES_RST 0x0
__INLINE void aotimer_tcr_pack(uint32_t reg_idx, uint8_t tim, uint8_t tms, uint8_t tes)
{
ASSERT_ERR(reg_idx <= 1);
ASSERT_ERR(((tim << 2) & ~0x00000004) == 0);
ASSERT_ERR(((tms << 1) & ~0x00000002) == 0);
ASSERT_ERR(((tes << 0) & ~0x00000001) == 0);
AOTIMER_TCR_REG(reg_idx) = (tim << 2) | (tms << 1) | (tes << 0);
}
__INLINE void aotimer_tcr_unpack(uint32_t reg_idx, uint8_t* tim, uint8_t* tms, uint8_t* tes)
{
ASSERT_ERR(reg_idx <= 1);
uint32_t localVal = AOTIMER_TCR_REG(reg_idx);
*tim = (localVal & 0x00000004) >> 2;
*tms = (localVal & 0x00000002) >> 1;
*tes = (localVal & 0x00000001) >> 0;
}
__INLINE uint8_t aotimer_tcr__tim__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 1);
uint32_t localVal = AOTIMER_TCR_REG(reg_idx);
return ((localVal & 0x00000004) >> 2);
}
__INLINE void aotimer_tcr__tim__setf(uint32_t reg_idx, uint8_t tim)
{
ASSERT_ERR(reg_idx <= 1);
ASSERT_ERR(((tim << 2) & ~0x00000004) == 0);
AOTIMER_TCR_REG(reg_idx) = (AOTIMER_TCR_REG(reg_idx) & ~0x00000004) | (tim << 2);
}
__INLINE uint8_t aotimer_tcr__tms__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 1);
uint32_t localVal = AOTIMER_TCR_REG(reg_idx);
return ((localVal & 0x00000002) >> 1);
}
__INLINE void aotimer_tcr__tms__setf(uint32_t reg_idx, uint8_t tms)
{
ASSERT_ERR(reg_idx <= 1);
ASSERT_ERR(((tms << 1) & ~0x00000002) == 0);
AOTIMER_TCR_REG(reg_idx) = (AOTIMER_TCR_REG(reg_idx) & ~0x00000002) | (tms << 1);
}
__INLINE uint8_t aotimer_tcr__tes__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 1);
uint32_t localVal = AOTIMER_TCR_REG(reg_idx);
return ((localVal & 0x00000001) >> 0);
}
__INLINE void aotimer_tcr__tes__setf(uint32_t reg_idx, uint8_t tes)
{
ASSERT_ERR(reg_idx <= 1);
ASSERT_ERR(((tes << 0) & ~0x00000001) == 0);
AOTIMER_TCR_REG(reg_idx) = (AOTIMER_TCR_REG(reg_idx) & ~0x00000001) | (tes << 0);
}
/**
* @brief AOTIMER_TIC register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 00 TIC 0
* </pre>
*/
#define AOTIMER_TIC_REG(i) (*(volatile uint32_t *)(0x4000280C + aotimer_offset[i]))
#define AOTIMER_TIC_ADDR(i) (0x4000280C + aotimer_offset[i])
#define AOTIMER_TIC_OFFSET 0x0000000C
__INLINE uint32_t aotimer_tic_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 1);
return AOTIMER_TIC_REG(reg_idx);
}
// field definitions
#define TIC_BIT 0x00000001
#define TIC_POS 0
#define TIC_RST 0x0
__INLINE uint8_t aotimer_tic__tic__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 1);
uint32_t localVal = AOTIMER_TIC_REG(reg_idx);
ASSERT_ERR((localVal & ~0x00000001) == 0);
return (localVal >> 0);
}
/**
* @brief AOTIMER_TIS register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 00 TIS 0
* </pre>
*/
#define AOTIMER_TIS_REG(i) (*(volatile uint32_t *)(0x40002810 + aotimer_offset[i]))
#define AOTIMER_TIS_ADDR(i) (0x40002810 + aotimer_offset[i])
#define AOTIMER_TIS_OFFSET 0x00000010
__INLINE uint32_t aotimer_tis_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 1);
return AOTIMER_TIS_REG(reg_idx);
}
// field definitions
#define TIS_BIT 0x00000001
#define TIS_POS 0
#define TIS_RST 0x0
__INLINE uint8_t aotimer_tis__tis__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 1);
uint32_t localVal = AOTIMER_TIS_REG(reg_idx);
ASSERT_ERR((localVal & ~0x00000001) == 0);
return (localVal >> 0);
}
#endif // _XC_REG_AOTIMER_H_
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,541 @@
#ifndef _XC_REG_FMC_CACHE_H_
#define _XC_REG_FMC_CACHE_H_
#include <stdint.h>
#define XC_REG_FMC_CACHE_BASE_ADDR 0x52000000
#define XC_REG_FMC_CACHE_DECODING_MASK 0x0000001F
/**
* @brief FMC_CACHE_CCR register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 06 STATISTIC_EN 0
* 05 SET_PREFETCH 0
* 04 SET_MAN_INV 0
* 03 SET_MAN_POW 0
* 02 POW_REQ 0
* 01 INV_REQ 0
* 00 EN 0
* </pre>
*/
#define FMC_CACHE_CCR_REG (*(volatile uint32_t *)(0x52000000))
#define FMC_CACHE_CCR_ADDR 0x52000000
#define FMC_CACHE_CCR_OFFSET 0x00000000
__INLINE uint32_t fmc_cache_ccr_get(void)
{
return FMC_CACHE_CCR_REG;
}
__INLINE void fmc_cache_ccr_set(uint32_t value)
{
FMC_CACHE_CCR_REG = value;
}
// field definitions
#define STATISTIC_EN_BIT 0x00000040
#define STATISTIC_EN_POS 6
#define SET_PREFETCH_BIT 0x00000020
#define SET_PREFETCH_POS 5
#define SET_MAN_INV_BIT 0x00000010
#define SET_MAN_INV_POS 4
#define SET_MAN_POW_BIT 0x00000008
#define SET_MAN_POW_POS 3
#define POW_REQ_BIT 0x00000004
#define POW_REQ_POS 2
#define INV_REQ_BIT 0x00000002
#define INV_REQ_POS 1
#define EN_BIT 0x00000001
#define EN_POS 0
#define STATISTIC_EN_RST 0x0
#define SET_PREFETCH_RST 0x0
#define SET_MAN_INV_RST 0x0
#define SET_MAN_POW_RST 0x0
#define POW_REQ_RST 0x0
#define INV_REQ_RST 0x0
#define EN_RST 0x0
__INLINE void fmc_cache_ccr_pack(uint8_t statistic_en, uint8_t set_prefetch, uint8_t set_man_inv, uint8_t set_man_pow, uint8_t pow_req, uint8_t inv_req, uint8_t en)
{
ASSERT_ERR(((statistic_en << 6) & ~0x00000040) == 0);
ASSERT_ERR(((set_prefetch << 5) & ~0x00000020) == 0);
ASSERT_ERR(((set_man_inv << 4) & ~0x00000010) == 0);
ASSERT_ERR(((set_man_pow << 3) & ~0x00000008) == 0);
ASSERT_ERR(((pow_req << 2) & ~0x00000004) == 0);
ASSERT_ERR(((inv_req << 1) & ~0x00000002) == 0);
ASSERT_ERR(((en << 0) & ~0x00000001) == 0);
FMC_CACHE_CCR_REG = (statistic_en << 6) | (set_prefetch << 5) | (set_man_inv << 4) | (set_man_pow << 3) | (pow_req << 2) | (inv_req << 1) | (en << 0);
}
__INLINE void fmc_cache_ccr_unpack(uint8_t* statistic_en, uint8_t* set_prefetch, uint8_t* set_man_inv, uint8_t* set_man_pow, uint8_t* pow_req, uint8_t* inv_req, uint8_t* en)
{
uint32_t localVal = FMC_CACHE_CCR_REG;
*statistic_en = (localVal & 0x00000040) >> 6;
*set_prefetch = (localVal & 0x00000020) >> 5;
*set_man_inv = (localVal & 0x00000010) >> 4;
*set_man_pow = (localVal & 0x00000008) >> 3;
*pow_req = (localVal & 0x00000004) >> 2;
*inv_req = (localVal & 0x00000002) >> 1;
*en = (localVal & 0x00000001) >> 0;
}
__INLINE uint8_t fmc_cache_ccr__statistic_en__getf(void)
{
uint32_t localVal = FMC_CACHE_CCR_REG;
return ((localVal & 0x00000040) >> 6);
}
__INLINE void fmc_cache_ccr__statistic_en__setf(uint8_t statistic_en)
{
ASSERT_ERR(((statistic_en << 6) & ~0x00000040) == 0);
FMC_CACHE_CCR_REG = (FMC_CACHE_CCR_REG & ~0x00000040) | (statistic_en << 6);
}
__INLINE uint8_t fmc_cache_ccr__set_prefetch__getf(void)
{
uint32_t localVal = FMC_CACHE_CCR_REG;
return ((localVal & 0x00000020) >> 5);
}
__INLINE void fmc_cache_ccr__set_prefetch__setf(uint8_t set_prefetch)
{
ASSERT_ERR(((set_prefetch << 5) & ~0x00000020) == 0);
FMC_CACHE_CCR_REG = (FMC_CACHE_CCR_REG & ~0x00000020) | (set_prefetch << 5);
}
__INLINE uint8_t fmc_cache_ccr__set_man_inv__getf(void)
{
uint32_t localVal = FMC_CACHE_CCR_REG;
return ((localVal & 0x00000010) >> 4);
}
__INLINE void fmc_cache_ccr__set_man_inv__setf(uint8_t set_man_inv)
{
ASSERT_ERR(((set_man_inv << 4) & ~0x00000010) == 0);
FMC_CACHE_CCR_REG = (FMC_CACHE_CCR_REG & ~0x00000010) | (set_man_inv << 4);
}
__INLINE uint8_t fmc_cache_ccr__set_man_pow__getf(void)
{
uint32_t localVal = FMC_CACHE_CCR_REG;
return ((localVal & 0x00000008) >> 3);
}
__INLINE void fmc_cache_ccr__set_man_pow__setf(uint8_t set_man_pow)
{
ASSERT_ERR(((set_man_pow << 3) & ~0x00000008) == 0);
FMC_CACHE_CCR_REG = (FMC_CACHE_CCR_REG & ~0x00000008) | (set_man_pow << 3);
}
__INLINE uint8_t fmc_cache_ccr__pow_req__getf(void)
{
uint32_t localVal = FMC_CACHE_CCR_REG;
return ((localVal & 0x00000004) >> 2);
}
__INLINE void fmc_cache_ccr__pow_req__setf(uint8_t pow_req)
{
ASSERT_ERR(((pow_req << 2) & ~0x00000004) == 0);
FMC_CACHE_CCR_REG = (FMC_CACHE_CCR_REG & ~0x00000004) | (pow_req << 2);
}
__INLINE uint8_t fmc_cache_ccr__inv_req__getf(void)
{
uint32_t localVal = FMC_CACHE_CCR_REG;
return ((localVal & 0x00000002) >> 1);
}
__INLINE void fmc_cache_ccr__inv_req__setf(uint8_t inv_req)
{
ASSERT_ERR(((inv_req << 1) & ~0x00000002) == 0);
FMC_CACHE_CCR_REG = (FMC_CACHE_CCR_REG & ~0x00000002) | (inv_req << 1);
}
__INLINE uint8_t fmc_cache_ccr__en__getf(void)
{
uint32_t localVal = FMC_CACHE_CCR_REG;
return ((localVal & 0x00000001) >> 0);
}
__INLINE void fmc_cache_ccr__en__setf(uint8_t en)
{
ASSERT_ERR(((en << 0) & ~0x00000001) == 0);
FMC_CACHE_CCR_REG = (FMC_CACHE_CCR_REG & ~0x00000001) | (en << 0);
}
/**
* @brief FMC_CACHE_SR register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 04 POW_STAT 0
* 02 INV_STAT 0
* 01:00 CS 0x0
* </pre>
*/
#define FMC_CACHE_SR_REG (*(volatile uint32_t *)(0x52000004))
#define FMC_CACHE_SR_ADDR 0x52000004
#define FMC_CACHE_SR_OFFSET 0x00000004
__INLINE uint32_t fmc_cache_sr_get(void)
{
return FMC_CACHE_SR_REG;
}
// field definitions
#define POW_STAT_BIT 0x00000010
#define POW_STAT_POS 4
#define INV_STAT_BIT 0x00000004
#define INV_STAT_POS 2
#define CS_MASK 0x00000003
#define CS_LSB 0
#define CS_WIDTH 0x00000002
#define POW_STAT_RST 0x0
#define INV_STAT_RST 0x0
#define CS_RST 0x0
__INLINE void fmc_cache_sr_unpack(uint8_t* pow_stat, uint8_t* inv_stat, uint8_t* cs)
{
uint32_t localVal = FMC_CACHE_SR_REG;
*pow_stat = (localVal & 0x00000010) >> 4;
*inv_stat = (localVal & 0x00000004) >> 2;
*cs = (localVal & 0x00000003) >> 0;
}
__INLINE uint8_t fmc_cache_sr__pow_stat__getf(void)
{
uint32_t localVal = FMC_CACHE_SR_REG;
return ((localVal & 0x00000010) >> 4);
}
__INLINE uint8_t fmc_cache_sr__inv_stat__getf(void)
{
uint32_t localVal = FMC_CACHE_SR_REG;
return ((localVal & 0x00000004) >> 2);
}
__INLINE uint8_t fmc_cache_sr__cs__getf(void)
{
uint32_t localVal = FMC_CACHE_SR_REG;
return ((localVal & 0x00000003) >> 0);
}
/**
* @brief FMC_CACHE_IRQMASK register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 01 MAN_INV_ERR0 0
* 00 POW_ERR0 0
* </pre>
*/
#define FMC_CACHE_IRQMASK_REG (*(volatile uint32_t *)(0x52000008))
#define FMC_CACHE_IRQMASK_ADDR 0x52000008
#define FMC_CACHE_IRQMASK_OFFSET 0x00000008
__INLINE uint32_t fmc_cache_irqmask_get(void)
{
return FMC_CACHE_IRQMASK_REG;
}
__INLINE void fmc_cache_irqmask_set(uint32_t value)
{
FMC_CACHE_IRQMASK_REG = value;
}
// field definitions
#define MAN_INV_ERR0_BIT 0x00000002
#define MAN_INV_ERR0_POS 1
#define POW_ERR0_BIT 0x00000001
#define POW_ERR0_POS 0
#define MAN_INV_ERR0_RST 0x0
#define POW_ERR0_RST 0x0
__INLINE void fmc_cache_irqmask_pack(uint8_t man_inv_err0, uint8_t pow_err0)
{
ASSERT_ERR(((man_inv_err0 << 1) & ~0x00000002) == 0);
ASSERT_ERR(((pow_err0 << 0) & ~0x00000001) == 0);
FMC_CACHE_IRQMASK_REG = (man_inv_err0 << 1) | (pow_err0 << 0);
}
__INLINE void fmc_cache_irqmask_unpack(uint8_t* man_inv_err0, uint8_t* pow_err0)
{
uint32_t localVal = FMC_CACHE_IRQMASK_REG;
*man_inv_err0 = (localVal & 0x00000002) >> 1;
*pow_err0 = (localVal & 0x00000001) >> 0;
}
__INLINE uint8_t fmc_cache_irqmask__man_inv_err0__getf(void)
{
uint32_t localVal = FMC_CACHE_IRQMASK_REG;
return ((localVal & 0x00000002) >> 1);
}
__INLINE void fmc_cache_irqmask__man_inv_err0__setf(uint8_t man_inv_err0)
{
ASSERT_ERR(((man_inv_err0 << 1) & ~0x00000002) == 0);
FMC_CACHE_IRQMASK_REG = (FMC_CACHE_IRQMASK_REG & ~0x00000002) | (man_inv_err0 << 1);
}
__INLINE uint8_t fmc_cache_irqmask__pow_err0__getf(void)
{
uint32_t localVal = FMC_CACHE_IRQMASK_REG;
return ((localVal & 0x00000001) >> 0);
}
__INLINE void fmc_cache_irqmask__pow_err0__setf(uint8_t pow_err0)
{
ASSERT_ERR(((pow_err0 << 0) & ~0x00000001) == 0);
FMC_CACHE_IRQMASK_REG = (FMC_CACHE_IRQMASK_REG & ~0x00000001) | (pow_err0 << 0);
}
/**
* @brief FMC_CACHE_IRQSTAT register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 01 MAN_INV_ERR1 0
* 00 POW_ERR1 0
* </pre>
*/
#define FMC_CACHE_IRQSTAT_REG (*(volatile uint32_t *)(0x5200000C))
#define FMC_CACHE_IRQSTAT_ADDR 0x5200000C
#define FMC_CACHE_IRQSTAT_OFFSET 0x0000000C
__INLINE uint32_t fmc_cache_irqstat_get(void)
{
return FMC_CACHE_IRQSTAT_REG;
}
__INLINE void fmc_cache_irqstat_set(uint32_t value)
{
FMC_CACHE_IRQSTAT_REG = value;
}
// field definitions
#define MAN_INV_ERR1_BIT 0x00000002
#define MAN_INV_ERR1_POS 1
#define POW_ERR1_BIT 0x00000001
#define POW_ERR1_POS 0
#define MAN_INV_ERR1_RST 0x0
#define POW_ERR1_RST 0x0
__INLINE void fmc_cache_irqstat_pack(uint8_t man_inv_err1, uint8_t pow_err1)
{
ASSERT_ERR(((man_inv_err1 << 1) & ~0x00000002) == 0);
ASSERT_ERR(((pow_err1 << 0) & ~0x00000001) == 0);
FMC_CACHE_IRQSTAT_REG = (man_inv_err1 << 1) | (pow_err1 << 0);
}
__INLINE void fmc_cache_irqstat_unpack(uint8_t* man_inv_err1, uint8_t* pow_err1)
{
uint32_t localVal = FMC_CACHE_IRQSTAT_REG;
*man_inv_err1 = (localVal & 0x00000002) >> 1;
*pow_err1 = (localVal & 0x00000001) >> 0;
}
__INLINE uint8_t fmc_cache_irqstat__man_inv_err1__getf(void)
{
uint32_t localVal = FMC_CACHE_IRQSTAT_REG;
return ((localVal & 0x00000002) >> 1);
}
__INLINE void fmc_cache_irqstat__man_inv_err1__setf(uint8_t man_inv_err1)
{
ASSERT_ERR(((man_inv_err1 << 1) & ~0x00000002) == 0);
FMC_CACHE_IRQSTAT_REG = (FMC_CACHE_IRQSTAT_REG & ~0x00000002) | (man_inv_err1 << 1);
}
__INLINE uint8_t fmc_cache_irqstat__pow_err1__getf(void)
{
uint32_t localVal = FMC_CACHE_IRQSTAT_REG;
return ((localVal & 0x00000001) >> 0);
}
__INLINE void fmc_cache_irqstat__pow_err1__setf(uint8_t pow_err1)
{
ASSERT_ERR(((pow_err1 << 0) & ~0x00000001) == 0);
FMC_CACHE_IRQSTAT_REG = (FMC_CACHE_IRQSTAT_REG & ~0x00000001) | (pow_err1 << 0);
}
/**
* @brief FMC_CACHE_HWPARAMS register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 13 GEN_STAT_LOGIC 0
* 12 RESET_ALL_REGS 0
* 11:10 CACHE_WAY 0x0
* 09:05 CW 0x0
* 04:00 AW 0x0
* </pre>
*/
#define FMC_CACHE_HWPARAMS_REG (*(volatile uint32_t *)(0x52000010))
#define FMC_CACHE_HWPARAMS_ADDR 0x52000010
#define FMC_CACHE_HWPARAMS_OFFSET 0x00000010
__INLINE uint32_t fmc_cache_hwparams_get(void)
{
return FMC_CACHE_HWPARAMS_REG;
}
// field definitions
#define GEN_STAT_LOGIC_BIT 0x00002000
#define GEN_STAT_LOGIC_POS 13
#define RESET_ALL_REGS_BIT 0x00001000
#define RESET_ALL_REGS_POS 12
#define CACHE_WAY_MASK 0x00000C00
#define CACHE_WAY_LSB 10
#define CACHE_WAY_WIDTH 0x00000002
#define CW_MASK 0x000003E0
#define CW_LSB 5
#define CW_WIDTH 0x00000005
#define AW_MASK 0x0000001F
#define AW_LSB 0
#define AW_WIDTH 0x00000005
#define GEN_STAT_LOGIC_RST 0x0
#define RESET_ALL_REGS_RST 0x0
#define CACHE_WAY_RST 0x0
#define CW_RST 0x0
#define AW_RST 0x0
__INLINE void fmc_cache_hwparams_unpack(uint8_t* gen_stat_logic, uint8_t* reset_all_regs, uint8_t* cache_way, uint8_t* cw, uint8_t* aw)
{
uint32_t localVal = FMC_CACHE_HWPARAMS_REG;
*gen_stat_logic = (localVal & 0x00002000) >> 13;
*reset_all_regs = (localVal & 0x00001000) >> 12;
*cache_way = (localVal & 0x00000C00) >> 10;
*cw = (localVal & 0x000003E0) >> 5;
*aw = (localVal & 0x0000001F) >> 0;
}
__INLINE uint8_t fmc_cache_hwparams__gen_stat_logic__getf(void)
{
uint32_t localVal = FMC_CACHE_HWPARAMS_REG;
return ((localVal & 0x00002000) >> 13);
}
__INLINE uint8_t fmc_cache_hwparams__reset_all_regs__getf(void)
{
uint32_t localVal = FMC_CACHE_HWPARAMS_REG;
return ((localVal & 0x00001000) >> 12);
}
__INLINE uint8_t fmc_cache_hwparams__cache_way__getf(void)
{
uint32_t localVal = FMC_CACHE_HWPARAMS_REG;
return ((localVal & 0x00000C00) >> 10);
}
__INLINE uint8_t fmc_cache_hwparams__cw__getf(void)
{
uint32_t localVal = FMC_CACHE_HWPARAMS_REG;
return ((localVal & 0x000003E0) >> 5);
}
__INLINE uint8_t fmc_cache_hwparams__aw__getf(void)
{
uint32_t localVal = FMC_CACHE_HWPARAMS_REG;
return ((localVal & 0x0000001F) >> 0);
}
/**
* @brief FMC_CACHE_CSHR register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 31:00 CSHR 0x0
* </pre>
*/
#define FMC_CACHE_CSHR_REG (*(volatile uint32_t *)(0x52000014))
#define FMC_CACHE_CSHR_ADDR 0x52000014
#define FMC_CACHE_CSHR_OFFSET 0x00000014
__INLINE uint32_t fmc_cache_cshr_get(void)
{
return FMC_CACHE_CSHR_REG;
}
__INLINE void fmc_cache_cshr_set(uint32_t value)
{
FMC_CACHE_CSHR_REG = value;
}
// field definitions
#define CSHR_MASK 0xFFFFFFFF
#define CSHR_LSB 0
#define CSHR_WIDTH 0x00000020
#define CSHR_RST 0x0
__INLINE uint32_t fmc_cache_cshr__cshr__getf(void)
{
uint32_t localVal = FMC_CACHE_CSHR_REG;
ASSERT_ERR((localVal & ~0xFFFFFFFF) == 0);
return (localVal >> 0);
}
__INLINE void fmc_cache_cshr__cshr__setf(uint32_t cshr)
{
ASSERT_ERR(((cshr << 0) & ~0xFFFFFFFF) == 0);
FMC_CACHE_CSHR_REG = cshr << 0;
}
/**
* @brief FMC_CACHE_CSMR register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 31:00 CSMR 0x0
* </pre>
*/
#define FMC_CACHE_CSMR_REG (*(volatile uint32_t *)(0x52000018))
#define FMC_CACHE_CSMR_ADDR 0x52000018
#define FMC_CACHE_CSMR_OFFSET 0x00000018
__INLINE uint32_t fmc_cache_csmr_get(void)
{
return FMC_CACHE_CSMR_REG;
}
__INLINE void fmc_cache_csmr_set(uint32_t value)
{
FMC_CACHE_CSMR_REG = value;
}
// field definitions
#define CSMR_MASK 0xFFFFFFFF
#define CSMR_LSB 0
#define CSMR_WIDTH 0x00000020
#define CSMR_RST 0x0
__INLINE uint32_t fmc_cache_csmr__csmr__getf(void)
{
uint32_t localVal = FMC_CACHE_CSMR_REG;
ASSERT_ERR((localVal & ~0xFFFFFFFF) == 0);
return (localVal >> 0);
}
__INLINE void fmc_cache_csmr__csmr__setf(uint32_t csmr)
{
ASSERT_ERR(((csmr << 0) & ~0xFFFFFFFF) == 0);
FMC_CACHE_CSMR_REG = csmr << 0;
}
#endif // _XC_REG_FMC_CACHE_H_
@@ -0,0 +1,655 @@
#ifndef _XC_REG_GPIO_H_
#define _XC_REG_GPIO_H_
#include <stdint.h>
#define XC_REG_GPIO_BASE_ADDR 0x40001000
#define XC_REG_GPIO_DECODING_MASK 0x000003FF
#define GPIO_REG_SIZE 0x04
/**
* @brief GPIO_PORT_DR register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 31:16 DR_WE 0x0
* 15:00 DR 0x0
* </pre>
*/
#define GPIO_PORT_DR_REG(i) (*(volatile uint32_t *)(0x40001000 + i*GPIO_REG_SIZE))
#define GPIO_PORT_DR_ADDR(i) (0x40001000 + i*GPIO_REG_SIZE)
#define GPIO_PORT_DR_OFFSET 0x00000000
__INLINE uint32_t gpio_port_dr_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 1);
return GPIO_PORT_DR_REG(reg_idx);
}
__INLINE void gpio_port_dr_set(uint32_t reg_idx, uint32_t value)
{
ASSERT_ERR(reg_idx <= 1);
GPIO_PORT_DR_REG(reg_idx) = value;
}
// field definitions
#define DR_WE_MASK 0xFFFF0000
#define DR_WE_LSB 16
#define DR_WE_WIDTH 0x00000010
#define DR_MASK 0x0000FFFF
#define DR_LSB 0
#define DR_WIDTH 0x00000010
#define DR_WE_RST 0x0
#define DR_RST 0x0
__INLINE void gpio_port_dr_pack(uint32_t reg_idx, uint16_t drwe, uint16_t dr)
{
ASSERT_ERR(reg_idx <= 1);
ASSERT_ERR(((drwe << 16) & ~0xFFFF0000) == 0);
ASSERT_ERR(((dr << 0) & ~0x0000FFFF) == 0);
GPIO_PORT_DR_REG(reg_idx) = (drwe << 16) | (dr << 0);
}
__INLINE void gpio_port_dr_unpack(uint32_t reg_idx, uint16_t* drwe, uint16_t* dr)
{
ASSERT_ERR(reg_idx <= 1);
uint32_t localVal = GPIO_PORT_DR_REG(reg_idx);
*drwe = (localVal & 0xFFFF0000) >> 16;
*dr = (localVal & 0x0000FFFF) >> 0;
}
__INLINE void gpio_port_dr__dr_we__setf(uint32_t reg_idx, uint16_t drwe)
{
ASSERT_ERR(reg_idx <= 1);
ASSERT_ERR(((drwe << 16) & ~0xFFFF0000) == 0);
GPIO_PORT_DR_REG(reg_idx) = (GPIO_PORT_DR_REG(reg_idx) & ~0xFFFF0000) | (drwe << 16);
}
__INLINE uint16_t gpio_port_dr__dr__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 1);
uint32_t localVal = GPIO_PORT_DR_REG(reg_idx);
return ((localVal & 0x0000FFFF) >> 0);
}
__INLINE void gpio_port_dr__dr__setf(uint32_t reg_idx, uint16_t dr)
{
ASSERT_ERR(reg_idx <= 1);
ASSERT_ERR(((dr << 0) & ~0x0000FFFF) == 0);
GPIO_PORT_DR_REG(reg_idx) = (GPIO_PORT_DR_REG(reg_idx) & ~0x0000FFFF) | (dr << 0);
}
/**
* @brief GPIO_PORT_DDR register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 31:16 DDR_WE 0x0
* 15:00 DDR 0x0
* </pre>
*/
#define GPIO_PORT_DDR_REG(i) (*(volatile uint32_t *)(0x40001020 + i*GPIO_REG_SIZE))
#define GPIO_PORT_DDR_ADDR(i) (0x40001020 + i*GPIO_REG_SIZE)
#define GPIO_PORT_DDR_OFFSET 0x00000020
__INLINE uint32_t gpio_port_ddr_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 1);
return GPIO_PORT_DDR_REG(reg_idx);
}
__INLINE void gpio_port_ddr_set(uint32_t reg_idx, uint32_t value)
{
ASSERT_ERR(reg_idx <= 1);
GPIO_PORT_DDR_REG(reg_idx) = value;
}
// field definitions
#define DDR_WE_MASK 0xFFFF0000
#define DDR_WE_LSB 16
#define DDR_WE_WIDTH 0x00000010
#define DDR_MASK 0x0000FFFF
#define DDR_LSB 0
#define DDR_WIDTH 0x00000010
#define DDR_WE_RST 0x0
#define DDR_RST 0x0
__INLINE void gpio_port_ddr_pack(uint32_t reg_idx, uint16_t ddrwe, uint16_t ddr)
{
ASSERT_ERR(reg_idx <= 1);
ASSERT_ERR(((ddrwe << 16) & ~0xFFFF0000) == 0);
ASSERT_ERR(((ddr << 0) & ~0x0000FFFF) == 0);
GPIO_PORT_DDR_REG(reg_idx) = (ddrwe << 16) | (ddr << 0);
}
__INLINE void gpio_port_ddr_unpack(uint32_t reg_idx, uint16_t* ddrwe, uint16_t* ddr)
{
ASSERT_ERR(reg_idx <= 1);
uint32_t localVal = GPIO_PORT_DDR_REG(reg_idx);
*ddrwe = (localVal & 0xFFFF0000) >> 16;
*ddr = (localVal & 0x0000FFFF) >> 0;
}
__INLINE void gpio_port_ddr__ddr_we__setf(uint32_t reg_idx, uint16_t ddrwe)
{
ASSERT_ERR(reg_idx <= 1);
ASSERT_ERR(((ddrwe << 16) & ~0xFFFF0000) == 0);
GPIO_PORT_DDR_REG(reg_idx) = (GPIO_PORT_DDR_REG(reg_idx) & ~0xFFFF0000) | (ddrwe << 16);
}
__INLINE uint16_t gpio_port_ddr__ddr__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 1);
uint32_t localVal = GPIO_PORT_DDR_REG(reg_idx);
return ((localVal & 0x0000FFFF) >> 0);
}
__INLINE void gpio_port_ddr__ddr__setf(uint32_t reg_idx, uint16_t ddr)
{
ASSERT_ERR(reg_idx <= 1);
ASSERT_ERR(((ddr << 0) & ~0x0000FFFF) == 0);
GPIO_PORT_DDR_REG(reg_idx) = (GPIO_PORT_DDR_REG(reg_idx) & ~0x0000FFFF) | (ddr << 0);
}
/**
* @brief GPIO_EXT_PORT register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 31:00 DIN 0x0
* </pre>
*/
#define GPIO_EXT_PORT_REG(i) (*(volatile uint32_t *)(0x40001040 + i*GPIO_REG_SIZE))
#define GPIO_EXT_PORT_ADDR(i) (0x40001040 + i*GPIO_REG_SIZE)
#define GPIO_EXT_PORT_OFFSET 0x00000040
__INLINE uint32_t gpio_ext_port_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 1);
return GPIO_EXT_PORT_REG(reg_idx);
}
// field definitions
#define DIN_MASK 0xFFFFFFFF
#define DIN_LSB 0
#define DIN_WIDTH 0x00000020
#define DIN_RST 0x0
__INLINE uint32_t gpio_ext_port__din__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 1);
uint32_t localVal = GPIO_EXT_PORT_REG(reg_idx);
ASSERT_ERR((localVal & ~0xFFFFFFFF) == 0);
return (localVal >> 0);
}
/**
* @brief GPIO_INTR_CTRL register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 19:16 MODE_WE 0x0
* 15:13 MODE3 0x0
* 12 MODE_EN3 0
* 11:09 MODE2 0x0
* 08 MODE_EN2 0
* 07:05 MODE1 0x0
* 04 MODE_EN1 0
* 03:01 MODE0 0x0
* 00 MODE_EN0 0
* </pre>
*/
#define GPIO_INTR_CTRL_REG(i) (*(volatile uint32_t *)(0x40001100 + i*GPIO_REG_SIZE))
#define GPIO_INTR_CTRL_ADDR(i) (0x40001100 + i*GPIO_REG_SIZE)
#define GPIO_INTR_CTRL_OFFSET 0x00000100
__INLINE uint32_t gpio_intr_ctrl_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 7);
return GPIO_INTR_CTRL_REG(reg_idx);
}
__INLINE void gpio_intr_ctrl_set(uint32_t reg_idx, uint32_t value)
{
ASSERT_ERR(reg_idx <= 7);
GPIO_INTR_CTRL_REG(reg_idx) = value;
}
// field definitions
#define MODE_WE_MASK 0x000F0000
#define MODE_WE_LSB 16
#define MODE_WE_WIDTH 0x00000004
#define MODE3_MASK 0x0000E000
#define MODE3_LSB 13
#define MODE3_WIDTH 0x00000003
#define MODE_EN3_BIT 0x00001000
#define MODE_EN3_POS 12
#define MODE2_MASK 0x00000E00
#define MODE2_LSB 9
#define MODE2_WIDTH 0x00000003
#define MODE_EN2_BIT 0x00000100
#define MODE_EN2_POS 8
#define MODE1_MASK 0x000000E0
#define MODE1_LSB 5
#define MODE1_WIDTH 0x00000003
#define MODE_EN1_BIT 0x00000010
#define MODE_EN1_POS 4
#define MODE0_MASK 0x0000000E
#define MODE0_LSB 1
#define MODE0_WIDTH 0x00000003
#define MODE_EN0_BIT 0x00000001
#define MODE_EN0_POS 0
#define MODE_WE_RST 0x0
#define MODE3_RST 0x0
#define MODE_EN3_RST 0x0
#define MODE2_RST 0x0
#define MODE_EN2_RST 0x0
#define MODE1_RST 0x0
#define MODE_EN1_RST 0x0
#define MODE0_RST 0x0
#define MODE_EN0_RST 0x0
__INLINE void gpio_intr_ctrl_pack(uint32_t reg_idx, uint8_t modewe, uint8_t mode3, uint8_t modeen3, uint8_t mode2, uint8_t modeen2, uint8_t mode1, uint8_t modeen1, uint8_t mode0, uint8_t modeen0)
{
ASSERT_ERR(reg_idx <= 7);
ASSERT_ERR(((modewe << 16) & ~0x000F0000) == 0);
ASSERT_ERR(((mode3 << 13) & ~0x0000E000) == 0);
ASSERT_ERR(((modeen3 << 12) & ~0x00001000) == 0);
ASSERT_ERR(((mode2 << 9) & ~0x00000E00) == 0);
ASSERT_ERR(((modeen2 << 8) & ~0x00000100) == 0);
ASSERT_ERR(((mode1 << 5) & ~0x000000E0) == 0);
ASSERT_ERR(((modeen1 << 4) & ~0x00000010) == 0);
ASSERT_ERR(((mode0 << 1) & ~0x0000000E) == 0);
ASSERT_ERR(((modeen0 << 0) & ~0x00000001) == 0);
GPIO_INTR_CTRL_REG(reg_idx) = (modewe << 16) | (mode3 << 13) | (modeen3 << 12) | (mode2 << 9) | (modeen2 << 8) | (mode1 << 5) | (modeen1 << 4) | (mode0 << 1) | (modeen0 << 0);
}
__INLINE void gpio_intr_ctrl_unpack(uint32_t reg_idx, uint8_t* modewe, uint8_t* mode3, uint8_t* modeen3, uint8_t* mode2, uint8_t* modeen2, uint8_t* mode1, uint8_t* modeen1, uint8_t* mode0, uint8_t* modeen0)
{
ASSERT_ERR(reg_idx <= 7);
uint32_t localVal = GPIO_INTR_CTRL_REG(reg_idx);
*modewe = (localVal & 0x000F0000) >> 16;
*mode3 = (localVal & 0x0000E000) >> 13;
*modeen3 = (localVal & 0x00001000) >> 12;
*mode2 = (localVal & 0x00000E00) >> 9;
*modeen2 = (localVal & 0x00000100) >> 8;
*mode1 = (localVal & 0x000000E0) >> 5;
*modeen1 = (localVal & 0x00000010) >> 4;
*mode0 = (localVal & 0x0000000E) >> 1;
*modeen0 = (localVal & 0x00000001) >> 0;
}
__INLINE void gpio_intr_ctrl__mode_we__setf(uint32_t reg_idx, uint8_t modewe)
{
ASSERT_ERR(reg_idx <= 7);
ASSERT_ERR(((modewe << 16) & ~0x000F0000) == 0);
GPIO_INTR_CTRL_REG(reg_idx) = (GPIO_INTR_CTRL_REG(reg_idx) & ~0x000F0000) | (modewe << 16);
}
__INLINE uint8_t gpio_intr_ctrl__mode3__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 7);
uint32_t localVal = GPIO_INTR_CTRL_REG(reg_idx);
return ((localVal & 0x0000E000) >> 13);
}
__INLINE void gpio_intr_ctrl__mode3__setf(uint32_t reg_idx, uint8_t mode3)
{
ASSERT_ERR(reg_idx <= 7);
ASSERT_ERR(((mode3 << 13) & ~0x0000E000) == 0);
GPIO_INTR_CTRL_REG(reg_idx) = (GPIO_INTR_CTRL_REG(reg_idx) & ~0x0000E000) | (mode3 << 13);
}
__INLINE uint8_t gpio_intr_ctrl__mode_en3__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 7);
uint32_t localVal = GPIO_INTR_CTRL_REG(reg_idx);
return ((localVal & 0x00001000) >> 12);
}
__INLINE void gpio_intr_ctrl__mode_en3__setf(uint32_t reg_idx, uint8_t modeen3)
{
ASSERT_ERR(reg_idx <= 7);
ASSERT_ERR(((modeen3 << 12) & ~0x00001000) == 0);
GPIO_INTR_CTRL_REG(reg_idx) = (GPIO_INTR_CTRL_REG(reg_idx) & ~0x00001000) | (modeen3 << 12);
}
__INLINE uint8_t gpio_intr_ctrl__mode2__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 7);
uint32_t localVal = GPIO_INTR_CTRL_REG(reg_idx);
return ((localVal & 0x00000E00) >> 9);
}
__INLINE void gpio_intr_ctrl__mode2__setf(uint32_t reg_idx, uint8_t mode2)
{
ASSERT_ERR(reg_idx <= 7);
ASSERT_ERR(((mode2 << 9) & ~0x00000E00) == 0);
GPIO_INTR_CTRL_REG(reg_idx) = (GPIO_INTR_CTRL_REG(reg_idx) & ~0x00000E00) | (mode2 << 9);
}
__INLINE uint8_t gpio_intr_ctrl__mode_en2__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 7);
uint32_t localVal = GPIO_INTR_CTRL_REG(reg_idx);
return ((localVal & 0x00000100) >> 8);
}
__INLINE void gpio_intr_ctrl__mode_en2__setf(uint32_t reg_idx, uint8_t modeen2)
{
ASSERT_ERR(reg_idx <= 7);
ASSERT_ERR(((modeen2 << 8) & ~0x00000100) == 0);
GPIO_INTR_CTRL_REG(reg_idx) = (GPIO_INTR_CTRL_REG(reg_idx) & ~0x00000100) | (modeen2 << 8);
}
__INLINE uint8_t gpio_intr_ctrl__mode1__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 7);
uint32_t localVal = GPIO_INTR_CTRL_REG(reg_idx);
return ((localVal & 0x000000E0) >> 5);
}
__INLINE void gpio_intr_ctrl__mode1__setf(uint32_t reg_idx, uint8_t mode1)
{
ASSERT_ERR(reg_idx <= 7);
ASSERT_ERR(((mode1 << 5) & ~0x000000E0) == 0);
GPIO_INTR_CTRL_REG(reg_idx) = (GPIO_INTR_CTRL_REG(reg_idx) & ~0x000000E0) | (mode1 << 5);
}
__INLINE uint8_t gpio_intr_ctrl__mode_en1__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 7);
uint32_t localVal = GPIO_INTR_CTRL_REG(reg_idx);
return ((localVal & 0x00000010) >> 4);
}
__INLINE void gpio_intr_ctrl__mode_en1__setf(uint32_t reg_idx, uint8_t modeen1)
{
ASSERT_ERR(reg_idx <= 7);
ASSERT_ERR(((modeen1 << 4) & ~0x00000010) == 0);
GPIO_INTR_CTRL_REG(reg_idx) = (GPIO_INTR_CTRL_REG(reg_idx) & ~0x00000010) | (modeen1 << 4);
}
__INLINE uint8_t gpio_intr_ctrl__mode0__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 7);
uint32_t localVal = GPIO_INTR_CTRL_REG(reg_idx);
return ((localVal & 0x0000000E) >> 1);
}
__INLINE void gpio_intr_ctrl__mode0__setf(uint32_t reg_idx, uint8_t mode0)
{
ASSERT_ERR(reg_idx <= 7);
ASSERT_ERR(((mode0 << 1) & ~0x0000000E) == 0);
GPIO_INTR_CTRL_REG(reg_idx) = (GPIO_INTR_CTRL_REG(reg_idx) & ~0x0000000E) | (mode0 << 1);
}
__INLINE uint8_t gpio_intr_ctrl__mode_en0__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 7);
uint32_t localVal = GPIO_INTR_CTRL_REG(reg_idx);
return ((localVal & 0x00000001) >> 0);
}
__INLINE void gpio_intr_ctrl__mode_en0__setf(uint32_t reg_idx, uint8_t modeen0)
{
ASSERT_ERR(reg_idx <= 7);
ASSERT_ERR(((modeen0 << 0) & ~0x00000001) == 0);
GPIO_INTR_CTRL_REG(reg_idx) = (GPIO_INTR_CTRL_REG(reg_idx) & ~0x00000001) | (modeen0 << 0);
}
/**
* @brief GPIO_DEBOUNCE register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 31:16 DEBEN_WE 0x0
* 15:00 DEBEN 0x0
* </pre>
*/
#define GPIO_DEBOUNCE_REG(i) (*(volatile uint32_t *)(0x40001180 + i*GPIO_REG_SIZE))
#define GPIO_DEBOUNCE_ADDR(i) (0x40001180 + i*GPIO_REG_SIZE)
#define GPIO_DEBOUNCE_OFFSET 0x00000180
__INLINE uint32_t gpio_debounce_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 1);
return GPIO_DEBOUNCE_REG(reg_idx);
}
__INLINE void gpio_debounce_set(uint32_t reg_idx, uint32_t value)
{
ASSERT_ERR(reg_idx <= 1);
GPIO_DEBOUNCE_REG(reg_idx) = value;
}
// field definitions
#define DEBEN_WE_MASK 0xFFFF0000
#define DEBEN_WE_LSB 16
#define DEBEN_WE_WIDTH 0x00000010
#define DEBEN_MASK 0x0000FFFF
#define DEBEN_LSB 0
#define DEBEN_WIDTH 0x00000010
#define DEBEN_WE_RST 0x0
#define DEBEN_RST 0x0
__INLINE void gpio_debounce_pack(uint32_t reg_idx, uint16_t debenwe, uint16_t deben)
{
ASSERT_ERR(reg_idx <= 1);
ASSERT_ERR(((debenwe << 16) & ~0xFFFF0000) == 0);
ASSERT_ERR(((deben << 0) & ~0x0000FFFF) == 0);
GPIO_DEBOUNCE_REG(reg_idx) = (debenwe << 16) | (deben << 0);
}
__INLINE void gpio_debounce_unpack(uint32_t reg_idx, uint16_t* debenwe, uint16_t* deben)
{
ASSERT_ERR(reg_idx <= 1);
uint32_t localVal = GPIO_DEBOUNCE_REG(reg_idx);
*debenwe = (localVal & 0xFFFF0000) >> 16;
*deben = (localVal & 0x0000FFFF) >> 0;
}
__INLINE void gpio_debounce__deben_we__setf(uint32_t reg_idx, uint16_t debenwe)
{
ASSERT_ERR(reg_idx <= 1);
ASSERT_ERR(((debenwe << 16) & ~0xFFFF0000) == 0);
GPIO_DEBOUNCE_REG(reg_idx) = (GPIO_DEBOUNCE_REG(reg_idx) & ~0xFFFF0000) | (debenwe << 16);
}
__INLINE uint16_t gpio_debounce__deben__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 1);
uint32_t localVal = GPIO_DEBOUNCE_REG(reg_idx);
return ((localVal & 0x0000FFFF) >> 0);
}
__INLINE void gpio_debounce__deben__setf(uint32_t reg_idx, uint16_t deben)
{
ASSERT_ERR(reg_idx <= 1);
ASSERT_ERR(((deben << 0) & ~0x0000FFFF) == 0);
GPIO_DEBOUNCE_REG(reg_idx) = (GPIO_DEBOUNCE_REG(reg_idx) & ~0x0000FFFF) | (deben << 0);
}
/**
* @brief GPIO_INTR_RAW register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 31:00 RAW 0x0
* </pre>
*/
#define GPIO_INTR_RAW_REG (*(volatile uint32_t *)(0x400011A0))
#define GPIO_INTR_RAW_ADDR 0x400011A0
#define GPIO_INTR_RAW_OFFSET 0x000001A0
__INLINE uint32_t gpio_intr_raw_get(void)
{
return GPIO_INTR_RAW_REG;
}
// field definitions
#define RAW_MASK 0xFFFFFFFF
#define RAW_LSB 0
#define RAW_WIDTH 0x00000020
#define RAW_RST 0x0
__INLINE uint32_t gpio_intr_raw__raw__getf(void)
{
uint32_t localVal = GPIO_INTR_RAW_REG;
ASSERT_ERR((localVal & ~0xFFFFFFFF) == 0);
return (localVal >> 0);
}
/**
* @brief GPIO_INTR_CLR register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 31:00 CLR 0x0
* </pre>
*/
#define GPIO_INTR_CLR_REG(i) (*(volatile uint32_t *)(0x400011B0 + i*GPIO_REG_SIZE))
#define GPIO_INTR_CLR_ADDR(i) (0x400011B0 + i*GPIO_REG_SIZE)
#define GPIO_INTR_CLR_OFFSET 0x000001B0
__INLINE void gpio_intr_clr_set(uint32_t reg_idx, uint32_t value)
{
ASSERT_ERR(reg_idx <= 1);
GPIO_INTR_CLR_REG(reg_idx) = value;
}
// field definitions
#define CLR_MASK 0xFFFFFFFF
#define CLR_LSB 0
#define CLR_WIDTH 0x00000020
#define CLR_RST 0x0
__INLINE void gpio_intr_clr__clr__setf(uint32_t reg_idx, uint32_t clr)
{
ASSERT_ERR(reg_idx <= 1);
ASSERT_ERR(((clr << 0) & ~0xFFFFFFFF) == 0);
GPIO_INTR_CLR_REG(reg_idx) = clr << 0;
}
/**
* @brief GPIO_INTR_MASK_C register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 31:16 MASK_WE 0x0
* 15:00 MASK 0x0
* </pre>
*/
#define GPIO_INTR_MASK_C_REG(i) (*(volatile uint32_t *)(0x40001200 + i*GPIO_REG_SIZE))
#define GPIO_INTR_MASK_C_ADDR(i) (0x40001200 + i*GPIO_REG_SIZE)
#define GPIO_INTR_MASK_C_OFFSET 0x00000200
__INLINE uint32_t gpio_intr_mask_c_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 1);
return GPIO_INTR_MASK_C_REG(reg_idx);
}
__INLINE void gpio_intr_mask_c_set(uint32_t reg_idx, uint32_t value)
{
ASSERT_ERR(reg_idx <= 1);
GPIO_INTR_MASK_C_REG(reg_idx) = value;
}
// field definitions
#define MASK_WE_MASK 0xFFFF0000
#define MASK_WE_LSB 16
#define MASK_WE_WIDTH 0x00000010
#define MASK_MASK 0x0000FFFF
#define MASK_LSB 0
#define MASK_WIDTH 0x00000010
#define MASK_WE_RST 0x0
#define MASK_RST 0x0
__INLINE void gpio_intr_mask_c_pack(uint32_t reg_idx, uint16_t maskwe, uint16_t mask)
{
ASSERT_ERR(reg_idx <= 1);
ASSERT_ERR(((maskwe << 16) & ~0xFFFF0000) == 0);
ASSERT_ERR(((mask << 0) & ~0x0000FFFF) == 0);
GPIO_INTR_MASK_C_REG(reg_idx) = (maskwe << 16) | (mask << 0);
}
__INLINE void gpio_intr_mask_c_unpack(uint32_t reg_idx, uint16_t* maskwe, uint16_t* mask)
{
ASSERT_ERR(reg_idx <= 1);
uint32_t localVal = GPIO_INTR_MASK_C_REG(reg_idx);
*maskwe = (localVal & 0xFFFF0000) >> 16;
*mask = (localVal & 0x0000FFFF) >> 0;
}
__INLINE void gpio_intr_mask_c__mask_we__setf(uint32_t reg_idx, uint16_t maskwe)
{
ASSERT_ERR(reg_idx <= 1);
ASSERT_ERR(((maskwe << 16) & ~0xFFFF0000) == 0);
GPIO_INTR_MASK_C_REG(reg_idx) = (GPIO_INTR_MASK_C_REG(reg_idx) & ~0xFFFF0000) | (maskwe << 16);
}
__INLINE uint16_t gpio_intr_mask_c__mask__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 1);
uint32_t localVal = GPIO_INTR_MASK_C_REG(reg_idx);
return ((localVal & 0x0000FFFF) >> 0);
}
__INLINE void gpio_intr_mask_c__mask__setf(uint32_t reg_idx, uint16_t mask)
{
ASSERT_ERR(reg_idx <= 1);
ASSERT_ERR(((mask << 0) & ~0x0000FFFF) == 0);
GPIO_INTR_MASK_C_REG(reg_idx) = (GPIO_INTR_MASK_C_REG(reg_idx) & ~0x0000FFFF) | (mask << 0);
}
/**
* @brief GPIO_INTR_STATUS_C register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 31:00 STATUS 0x0
* </pre>
*/
#define GPIO_INTR_STATUS_C_REG(i) (*(volatile uint32_t *)(0x40001220 + i*GPIO_REG_SIZE))
#define GPIO_INTR_STATUS_C_ADDR(i) (0x40001220 + i*GPIO_REG_SIZE)
#define GPIO_INTR_STATUS_C_OFFSET 0x00000220
__INLINE uint32_t gpio_intr_status_c_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 1);
return GPIO_INTR_STATUS_C_REG(reg_idx);
}
// field definitions
#define STATUS_MASK 0xFFFFFFFF
#define STATUS_LSB 0
#define STATUS_WIDTH 0x00000020
#define STATUS_RST 0x0
__INLINE uint32_t gpio_intr_status_c__status__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 1);
uint32_t localVal = GPIO_INTR_STATUS_C_REG(reg_idx);
ASSERT_ERR((localVal & ~0xFFFFFFFF) == 0);
return (localVal >> 0);
}
#endif // _XC_REG_GPIO_H_
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,67 @@
/*!
* \file xc_reg_offset.h
*
* \brief The header of xc registers offset index
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
#ifndef _XC_REG_OFFSET_H_
#define _XC_REG_OFFSET_H_
#define AOTIMER0_IDX 0U
#define AOTIMER1_IDX 1U
// #define AOTIMER_OFFSET {0x00, 0x14}
#define TIMER0_IDX 0U
#define TIMER1_IDX 1U
#define TIMER2_IDX 2U
#define TIMER3_IDX 3U
#define PWM0_IDX 0U
#define PWM1_IDX 1U
#define PWM2_IDX 2U
#define PWM3_IDX 3U
#define PWM4_IDX 4U
#define PWM5_IDX 5U
#define UART0_IDX (uint8_t)0U
#define UART1_IDX (uint8_t)1U
#define UART2_IDX (uint8_t)2U
#define PWM_TIMER0_IDX 0U
#define PWM_TIMER1_IDX 1U
#define PWM_TIMER2_IDX 2U
#define PWM_TIMER3_IDX 3U
#define PWM_TIMER4_IDX 4U
#define PWM_TIMER5_IDX 5U
#if (USE_XIP == 0)
#define SPI0_IDX 0U
#endif
#define SPI1_IDX 1U
#define SPI2_IDX 2U
const static unsigned char aotimer_offset[2] = {0x00, 0x14};
const static unsigned char timer_offset[4] = {0x00, 0x14, 0x28, 0x3C};
const static unsigned short pwm_offset[6] = {0x00, 0x40, 0x400, 0x440, 0x800, 0x840};
const static unsigned short uart_offset[3] ={0x00, 0x1000, 0x1400};
const static unsigned short spi_offset[3] ={0x00, 0x1000, 0x1800};
//#include "xc6xxx.h"
#endif // _XC_REG_OFFSET_H_
@@ -0,0 +1,675 @@
#ifndef _XC_REG_PWM_H_
#define _XC_REG_PWM_H_
#include <stdint.h>
#define XC_REG_PWM_BASE_ADDR 0x40017000
#define XC_REG_PWM_DECODING_MASK 0x0000003F
/**
* @brief PWM_EN register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 06 pwm_en_all 0
* 05 sleep_en 0
* 04 sleep_incr 0
* 03 EN_SEL 0
* 02:01 MODE 0x0
* 00 EN 0
* </pre>
*/
#define PWM_EN_REG(i) (* ((volatile uint32_t *)(0x40017000 + pwm_offset[i])) )
#define PWM_EN_ADDR(i) (0x40017000 + pwm_offset[i])
#define PWM_EN_OFFSET 0x00000000
__INLINE uint32_t pwm_en_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
return PWM_EN_REG(reg_idx);
}
__INLINE void pwm_en_set(uint32_t reg_idx, uint32_t value)
{
ASSERT_ERR(reg_idx <= 5);
PWM_EN_REG(reg_idx) = value;
}
// field definitions
#define PWM_EN_ALL_BIT 0x00000040
#define PWM_EN_ALL_POS 6
#define SLEEP_EN_BIT 0x00000020
#define SLEEP_EN_POS 5
#define SLEEP_INCR_BIT 0x00000010
#define SLEEP_INCR_POS 4
#define EN_SEL_BIT 0x00000008
#define EN_SEL_POS 3
#define MODE_MASK 0x00000006
#define MODE_LSB 1
#define MODE_WIDTH 0x00000002
#define EN_BIT 0x00000001
#define EN_POS 0
#define PWM_EN_ALL_RST 0x0
#define SLEEP_EN_RST 0x0
#define SLEEP_INCR_RST 0x0
#define EN_SEL_RST 0x0
#define MODE_RST 0x0
#define EN_RST 0x0
__INLINE void pwm_en_pack(uint32_t reg_idx, uint8_t pwm_en_all, uint8_t sleep_en, uint8_t sleep_incr, uint8_t en_sel, uint8_t mode, uint8_t en)
{
ASSERT_ERR(reg_idx <= 5);
ASSERT_ERR(((pwm_en_all << 6) & ~0x00000040) == 0);
ASSERT_ERR(((sleep_en << 5) & ~0x00000020) == 0);
ASSERT_ERR(((sleep_incr << 4) & ~0x00000010) == 0);
ASSERT_ERR(((en_sel << 3) & ~0x00000008) == 0);
ASSERT_ERR(((mode << 1) & ~0x00000006) == 0);
ASSERT_ERR(((en << 0) & ~0x00000001) == 0);
PWM_EN_REG(reg_idx) = (pwm_en_all << 6) | (sleep_en << 5) | (sleep_incr << 4) | (en_sel << 3) | (mode << 1) | (en << 0);
}
__INLINE void pwm_en_unpack(uint32_t reg_idx, uint8_t* pwm_en_all, uint8_t* sleep_en, uint8_t* sleep_incr, uint8_t* en_sel, uint8_t* mode, uint8_t* en)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_EN_REG(reg_idx);
*pwm_en_all = (localVal & 0x00000040) >> 6;
*sleep_en = (localVal & 0x00000020) >> 5;
*sleep_incr = (localVal & 0x00000010) >> 4;
*en_sel = (localVal & 0x00000008) >> 3;
*mode = (localVal & 0x00000006) >> 1;
*en = (localVal & 0x00000001) >> 0;
}
__INLINE uint8_t pwm_en__pwm_en_all__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_EN_REG(reg_idx);
return ((localVal & 0x00000040) >> 6);
}
__INLINE void pwm_en__pwm_en_all__setf(uint32_t reg_idx, uint8_t pwm_en_all)
{
ASSERT_ERR(reg_idx <= 5);
ASSERT_ERR(((pwm_en_all << 6) & ~0x00000040) == 0);
PWM_EN_REG(reg_idx) = (PWM_EN_REG(reg_idx) & ~0x00000040) | (pwm_en_all << 6);
}
__INLINE uint8_t pwm_en__sleep_en__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_EN_REG(reg_idx);
return ((localVal & 0x00000020) >> 5);
}
__INLINE void pwm_en__sleep_en__setf(uint32_t reg_idx, uint8_t sleep_en)
{
ASSERT_ERR(reg_idx <= 5);
ASSERT_ERR(((sleep_en << 5) & ~0x00000020) == 0);
PWM_EN_REG(reg_idx) = (PWM_EN_REG(reg_idx) & ~0x00000020) | (sleep_en << 5);
}
__INLINE uint8_t pwm_en__sleep_incr__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_EN_REG(reg_idx);
return ((localVal & 0x00000010) >> 4);
}
__INLINE void pwm_en__sleep_incr__setf(uint32_t reg_idx, uint8_t sleep_incr)
{
ASSERT_ERR(reg_idx <= 5);
ASSERT_ERR(((sleep_incr << 4) & ~0x00000010) == 0);
PWM_EN_REG(reg_idx) = (PWM_EN_REG(reg_idx) & ~0x00000010) | (sleep_incr << 4);
}
__INLINE uint8_t pwm_en__en_sel__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_EN_REG(reg_idx);
return ((localVal & 0x00000008) >> 3);
}
__INLINE void pwm_en__en_sel__setf(uint32_t reg_idx, uint8_t en_sel)
{
ASSERT_ERR(reg_idx <= 5);
ASSERT_ERR(((en_sel << 3) & ~0x00000008) == 0);
PWM_EN_REG(reg_idx) = (PWM_EN_REG(reg_idx) & ~0x00000008) | (en_sel << 3);
}
__INLINE uint8_t pwm_en__mode__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_EN_REG(reg_idx);
return ((localVal & 0x00000006) >> 1);
}
__INLINE void pwm_en__mode__setf(uint32_t reg_idx, uint8_t mode)
{
ASSERT_ERR(reg_idx <= 5);
ASSERT_ERR(((mode << 1) & ~0x00000006) == 0);
PWM_EN_REG(reg_idx) = (PWM_EN_REG(reg_idx) & ~0x00000006) | (mode << 1);
}
__INLINE uint8_t pwm_en__en__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_EN_REG(reg_idx);
return ((localVal & 0x00000001) >> 0);
}
__INLINE void pwm_en__en__setf(uint32_t reg_idx, uint8_t en)
{
ASSERT_ERR(reg_idx <= 5);
ASSERT_ERR(((en << 0) & ~0x00000001) == 0);
PWM_EN_REG(reg_idx) = (PWM_EN_REG(reg_idx) & ~0x00000001) | (en << 0);
}
/**
* @brief PWM_UP register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 00 UPDATE 0
* </pre>
*/
#define PWM_UP_REG(i) (* ((volatile uint32_t *)(0x40017004 + pwm_offset[i])) )
#define PWM_UP_ADDR(i) (0x40017004 + pwm_offset[i])
#define PWM_UP_OFFSET 0x00000004
__INLINE uint32_t pwm_up_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
return PWM_UP_REG(reg_idx);
}
__INLINE void pwm_up_set(uint32_t reg_idx, uint32_t value)
{
ASSERT_ERR(reg_idx <= 5);
PWM_UP_REG(reg_idx) = value;
}
// field definitions
#define UPDATE_BIT 0x00000001
#define UPDATE_POS 0
#define UPDATE_RST 0x0
__INLINE uint8_t pwm_up__update__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_UP_REG(reg_idx);
ASSERT_ERR((localVal & ~0x00000001) == 0);
return (localVal >> 0);
}
__INLINE void pwm_up__update__setf(uint32_t reg_idx, uint8_t update)
{
ASSERT_ERR(reg_idx <= 5);
ASSERT_ERR(((update << 0) & ~0x00000001) == 0);
PWM_UP_REG(reg_idx) = update << 0;
}
/**
* @brief PWM_RST register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 00 RESET 0
* </pre>
*/
#define PWM_RST_REG(i) (* ((volatile uint32_t *)(0x40017008 + pwm_offset[i])) )
#define PWM_RST_ADDR(i) (0x40017008 + pwm_offset[i])
#define PWM_RST_OFFSET 0x00000008
__INLINE uint32_t pwm_rst_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
return PWM_RST_REG(reg_idx);
}
__INLINE void pwm_rst_set(uint32_t reg_idx, uint32_t value)
{
ASSERT_ERR(reg_idx <= 5);
PWM_RST_REG(reg_idx) = value;
}
// field definitions
#define RESET_BIT 0x00000001
#define RESET_POS 0
#define RESET_RST 0x0
__INLINE uint8_t pwm_rst__reset__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_RST_REG(reg_idx);
ASSERT_ERR((localVal & ~0x00000001) == 0);
return (localVal >> 0);
}
__INLINE void pwm_rst__reset__setf(uint32_t reg_idx, uint8_t reset)
{
ASSERT_ERR(reg_idx <= 5);
ASSERT_ERR(((reset << 0) & ~0x00000001) == 0);
PWM_RST_REG(reg_idx) = reset << 0;
}
/**
* @brief PWM_PERIOD register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 07:00 PERIOD 0x0
* </pre>
*/
#define PWM_PERIOD_REG(i) (* ((volatile uint32_t *)(0x4001700C + pwm_offset[i])) )
#define PWM_PERIOD_ADDR(i) (0x4001700C + pwm_offset[i])
#define PWM_PERIOD_OFFSET 0x0000000C
__INLINE uint32_t pwm_period_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
return PWM_PERIOD_REG(reg_idx);
}
__INLINE void pwm_period_set(uint32_t reg_idx, uint32_t value)
{
ASSERT_ERR(reg_idx <= 5);
PWM_PERIOD_REG(reg_idx) = value;
}
// field definitions
#define PERIOD_MASK 0x000000FF
#define PERIOD_LSB 0
#define PERIOD_WIDTH 0x00000008
#define PERIOD_RST 0x0
__INLINE uint8_t pwm_period__period__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_PERIOD_REG(reg_idx);
ASSERT_ERR((localVal & ~0x000000FF) == 0);
return (localVal >> 0);
}
__INLINE void pwm_period__period__setf(uint32_t reg_idx, uint8_t period)
{
ASSERT_ERR(reg_idx <= 5);
ASSERT_ERR(((period << 0) & ~0x000000FF) == 0);
PWM_PERIOD_REG(reg_idx) = period << 0;
}
/**
* @brief PWM_OCPY register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 31:16 OCPY_RATIO_CONFIG 0x0
* 15:00 OCPY_RATIO 0x0
* </pre>
*/
#define PWM_OCPY_REG(i) (* ((volatile uint32_t *)(0x40017010 + pwm_offset[i])) )
#define PWM_OCPY_ADDR(i) (0x40017010 + pwm_offset[i])
#define PWM_OCPY_OFFSET 0x00000010
__INLINE uint32_t pwm_ocpy_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
return PWM_OCPY_REG(reg_idx);
}
__INLINE void pwm_ocpy_set(uint32_t reg_idx, uint32_t value)
{
ASSERT_ERR(reg_idx <= 5);
PWM_OCPY_REG(reg_idx) = value;
}
// field definitions
#define OCPY_RATIO_CONFIG_MASK 0xFFFF0000
#define OCPY_RATIO_CONFIG_LSB 16
#define OCPY_RATIO_CONFIG_WIDTH 0x00000010
#define OCPY_RATIO_MASK 0x0000FFFF
#define OCPY_RATIO_LSB 0
#define OCPY_RATIO_WIDTH 0x00000010
#define OCPY_RATIO_CONFIG_RST 0x0
#define OCPY_RATIO_RST 0x0
__INLINE void pwm_ocpy_pack(uint32_t reg_idx, uint16_t ocpy_ratio_config, uint16_t ocpy_ratio)
{
ASSERT_ERR(reg_idx <= 5);
ASSERT_ERR(((ocpy_ratio_config << 16) & ~0xFFFF0000) == 0);
ASSERT_ERR(((ocpy_ratio << 0) & ~0x0000FFFF) == 0);
PWM_OCPY_REG(reg_idx) = (ocpy_ratio_config << 16) | (ocpy_ratio << 0);
}
__INLINE void pwm_ocpy_unpack(uint32_t reg_idx, uint16_t* ocpy_ratio_config, uint16_t* ocpy_ratio)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_OCPY_REG(reg_idx);
*ocpy_ratio_config = (localVal & 0xFFFF0000) >> 16;
*ocpy_ratio = (localVal & 0x0000FFFF) >> 0;
}
__INLINE uint16_t pwm_ocpy__ocpy_ratio_config__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_OCPY_REG(reg_idx);
return ((localVal & 0xFFFF0000) >> 16);
}
__INLINE void pwm_ocpy__ocpy_ratio_config__setf(uint32_t reg_idx, uint16_t ocpy_ratio_config)
{
ASSERT_ERR(reg_idx <= 5);
ASSERT_ERR(((ocpy_ratio_config << 16) & ~0xFFFF0000) == 0);
PWM_OCPY_REG(reg_idx) = (PWM_OCPY_REG(reg_idx) & ~0xFFFF0000) | (ocpy_ratio_config << 16);
}
__INLINE uint16_t pwm_ocpy__ocpy_ratio__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_OCPY_REG(reg_idx);
return ((localVal & 0x0000FFFF) >> 0);
}
__INLINE void pwm_ocpy__ocpy_ratio__setf(uint32_t reg_idx, uint16_t ocpy_ratio)
{
ASSERT_ERR(reg_idx <= 5);
ASSERT_ERR(((ocpy_ratio << 0) & ~0x0000FFFF) == 0);
PWM_OCPY_REG(reg_idx) = (PWM_OCPY_REG(reg_idx) & ~0x0000FFFF) | (ocpy_ratio << 0);
}
/**
* @brief PWM_COMPEN register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 00 PWMCOMPEN 0
* </pre>
*/
#define PWM_COMPEN_REG(i) (* ((volatile uint32_t *)(0x40017014 + pwm_offset[i])) )
#define PWM_COMPEN_ADDR(i) (0x40017014 + pwm_offset[i])
#define PWM_COMPEN_OFFSET 0x00000014
__INLINE uint32_t pwm_compen_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
return PWM_COMPEN_REG(reg_idx);
}
__INLINE void pwm_compen_set(uint32_t reg_idx, uint32_t value)
{
ASSERT_ERR(reg_idx <= 5);
PWM_COMPEN_REG(reg_idx) = value;
}
// field definitions
#define PWMCOMPEN_BIT 0x00000001
#define PWMCOMPEN_POS 0
#define PWMCOMPEN_RST 0x0
__INLINE uint8_t pwm_compen__pwmcompen__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_COMPEN_REG(reg_idx);
ASSERT_ERR((localVal & ~0x00000001) == 0);
return (localVal >> 0);
}
__INLINE void pwm_compen__pwmcompen__setf(uint32_t reg_idx, uint8_t pwmcompen)
{
ASSERT_ERR(reg_idx <= 5);
ASSERT_ERR(((pwmcompen << 0) & ~0x00000001) == 0);
PWM_COMPEN_REG(reg_idx) = pwmcompen << 0;
}
/**
* @brief PWM_COMPTIME register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 02:00 COMPTIME 0x0
* </pre>
*/
#define PWM_COMPTIME_REG(i) (* ((volatile uint32_t *)(0x40017018 + pwm_offset[i])) )
#define PWM_COMPTIME_ADDR(i) (0x40017018 + pwm_offset[i])
#define PWM_COMPTIME_OFFSET 0x00000018
__INLINE uint32_t pwm_comptime_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
return PWM_COMPTIME_REG(reg_idx);
}
__INLINE void pwm_comptime_set(uint32_t reg_idx, uint32_t value)
{
ASSERT_ERR(reg_idx <= 5);
PWM_COMPTIME_REG(reg_idx) = value;
}
// field definitions
#define COMPTIME_MASK 0x00000007
#define COMPTIME_LSB 0
#define COMPTIME_WIDTH 0x00000003
#define COMPTIME_RST 0x0
__INLINE uint8_t pwm_comptime__comptime__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_COMPTIME_REG(reg_idx);
ASSERT_ERR((localVal & ~0x0000003F) == 0);
return (localVal >> 0);
}
__INLINE void pwm_comptime__comptime__setf(uint32_t reg_idx, uint8_t comptime)
{
ASSERT_ERR(reg_idx <= 5);
ASSERT_ERR(((comptime << 0) & ~0x0000003F) == 0);
PWM_COMPTIME_REG(reg_idx) = comptime << 0;
}
/**
* @brief PWM_BREAK_CTL register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 19:17 PWM_BRK_ENABLE 0x0
* 16 PWM_BRK_SYNC 0
* 14:12 PWM_BRK_MASK 0x0
* 11:09 PWM_BRK_INV 0x0
* 08 BRK_MODE 0
* 07 BRK_DBC_EN 0
* 06:01 BRK_DBC_STEP 0x0
* 00 CLEAR 0
* </pre>
*/
#define PWM_BREAK_CTL_REG(i) (* ((volatile uint32_t *)(0x40017020 + pwm_offset[i])) )
#define PWM_BREAK_CTL_ADDR(i) (0x40017020 + pwm_offset[i])
#define PWM_BREAK_CTL_OFFSET 0x00000020
__INLINE uint32_t pwm_break_ctl_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
return PWM_BREAK_CTL_REG(reg_idx);
}
__INLINE void pwm_break_ctl_set(uint32_t reg_idx, uint32_t value)
{
ASSERT_ERR(reg_idx <= 5);
PWM_BREAK_CTL_REG(reg_idx) = value;
}
// field definitions
#define PWM_BRK_ENABLE_MASK 0x000E0000
#define PWM_BRK_ENABLE_LSB 17
#define PWM_BRK_ENABLE_WIDTH 0x00000003
#define PWM_BRK_SYNC_BIT 0x00010000
#define PWM_BRK_SYNC_POS 16
#define PWM_BRK_MASK_MASK 0x00007000
#define PWM_BRK_MASK_LSB 12
#define PWM_BRK_MASK_WIDTH 0x00000003
#define PWM_BRK_INV_MASK 0x00000E00
#define PWM_BRK_INV_LSB 9
#define PWM_BRK_INV_WIDTH 0x00000003
#define BRK_MODE_BIT 0x00000100
#define BRK_MODE_POS 8
#define BRK_DBC_EN_BIT 0x00000080
#define BRK_DBC_EN_POS 7
#define BRK_DBC_STEP_MASK 0x0000007E
#define BRK_DBC_STEP_LSB 1
#define BRK_DBC_STEP_WIDTH 0x00000006
#define BRK_CLEAR_BIT 0x00000001
#define BRK_CLEAR_POS 0
#define PWM_BRK_ENABLE_RST 0x0
#define PWM_BRK_SYNC_RST 0x0
#define PWM_BRK_MASK_RST 0x0
#define PWM_BRK_INV_RST 0x0
#define BRK_MODE_RST 0x0
#define BRK_DBC_EN_RST 0x0
#define BRK_DBC_STEP_RST 0x0
#define CLEAR_RST 0x0
__INLINE void pwm_break_ctl_pack(uint32_t reg_idx, uint8_t pwm_brk_enable, uint8_t pwm_brk_mask, uint8_t pwm_brk_inv, uint8_t brk_mode, uint8_t brk_dbc_en, uint8_t brk_dbc_step, uint8_t clear)
{
ASSERT_ERR(reg_idx <= 5);
ASSERT_ERR(((pwm_brk_enable << 17) & ~0x000E0000) == 0);
ASSERT_ERR(((pwm_brk_mask << 12) & ~0x00007000) == 0);
ASSERT_ERR(((pwm_brk_inv << 9) & ~0x00000E00) == 0);
ASSERT_ERR(((brk_mode << 8) & ~0x00000100) == 0);
ASSERT_ERR(((brk_dbc_en << 7) & ~0x00000080) == 0);
ASSERT_ERR(((brk_dbc_step << 1) & ~0x0000007E) == 0);
ASSERT_ERR(((clear << 0) & ~0x00000001) == 0);
PWM_BREAK_CTL_REG(reg_idx) = (pwm_brk_enable << 17) | (pwm_brk_mask << 12) | (pwm_brk_inv << 9) | (brk_mode << 8) | (brk_dbc_en << 7) | (brk_dbc_step << 1) | (clear << 0);
}
__INLINE void pwm_break_ctl_unpack(uint32_t reg_idx, uint8_t* pwm_brk_enable, uint8_t* pwm_brk_sync, uint8_t* pwm_brk_mask, uint8_t* pwm_brk_inv, uint8_t* brk_mode, uint8_t* brk_dbc_en, uint8_t* brk_dbc_step, uint8_t* clear)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_BREAK_CTL_REG(reg_idx);
*pwm_brk_enable = (localVal & 0x000E0000) >> 17;
*pwm_brk_sync = (localVal & 0x00010000) >> 16;
*pwm_brk_mask = (localVal & 0x00007000) >> 12;
*pwm_brk_inv = (localVal & 0x00000E00) >> 9;
*brk_mode = (localVal & 0x00000100) >> 8;
*brk_dbc_en = (localVal & 0x00000080) >> 7;
*brk_dbc_step = (localVal & 0x0000007E) >> 1;
*clear = (localVal & 0x00000001) >> 0;
}
__INLINE uint8_t pwm_break_ctl__pwm_brk_enable__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_BREAK_CTL_REG(reg_idx);
return ((localVal & 0x000E0000) >> 17);
}
__INLINE void pwm_break_ctl__pwm_brk_enable__setf(uint32_t reg_idx, uint8_t pwm_brk_enable)
{
ASSERT_ERR(reg_idx <= 5);
ASSERT_ERR(((pwm_brk_enable << 17) & ~0x000E0000) == 0);
PWM_BREAK_CTL_REG(reg_idx) = (PWM_BREAK_CTL_REG(reg_idx) & ~0x000E0000) | (pwm_brk_enable << 17);
}
__INLINE uint8_t pwm_break_ctl__pwm_brk_sync__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_BREAK_CTL_REG(reg_idx);
return ((localVal & 0x00010000) >> 16);
}
__INLINE uint8_t pwm_break_ctl__pwm_brk_mask__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_BREAK_CTL_REG(reg_idx);
return ((localVal & 0x00007000) >> 12);
}
__INLINE void pwm_break_ctl__pwm_brk_mask__setf(uint32_t reg_idx, uint8_t pwm_brk_mask)
{
ASSERT_ERR(reg_idx <= 5);
ASSERT_ERR(((pwm_brk_mask << 12) & ~0x00007000) == 0);
PWM_BREAK_CTL_REG(reg_idx) = (PWM_BREAK_CTL_REG(reg_idx) & ~0x00007000) | (pwm_brk_mask << 12);
}
__INLINE uint8_t pwm_break_ctl__pwm_brk_inv__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_BREAK_CTL_REG(reg_idx);
return ((localVal & 0x00000E00) >> 9);
}
__INLINE void pwm_break_ctl__pwm_brk_inv__setf(uint32_t reg_idx, uint8_t pwm_brk_inv)
{
ASSERT_ERR(reg_idx <= 5);
ASSERT_ERR(((pwm_brk_inv << 9) & ~0x00000E00) == 0);
PWM_BREAK_CTL_REG(reg_idx) = (PWM_BREAK_CTL_REG(reg_idx) & ~0x00000E00) | (pwm_brk_inv << 9);
}
__INLINE uint8_t pwm_break_ctl__brk_mode__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_BREAK_CTL_REG(reg_idx);
return ((localVal & 0x00000100) >> 8);
}
__INLINE void pwm_break_ctl__brk_mode__setf(uint32_t reg_idx, uint8_t brk_mode)
{
ASSERT_ERR(reg_idx <= 5);
ASSERT_ERR(((brk_mode << 8) & ~0x00000100) == 0);
PWM_BREAK_CTL_REG(reg_idx) = (PWM_BREAK_CTL_REG(reg_idx) & ~0x00000100) | (brk_mode << 8);
}
__INLINE uint8_t pwm_break_ctl__brk_dbc_en__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_BREAK_CTL_REG(reg_idx);
return ((localVal & 0x00000080) >> 7);
}
__INLINE void pwm_break_ctl__brk_dbc_en__setf(uint32_t reg_idx, uint8_t brk_dbc_en)
{
ASSERT_ERR(reg_idx <= 5);
ASSERT_ERR(((brk_dbc_en << 7) & ~0x00000080) == 0);
PWM_BREAK_CTL_REG(reg_idx) = (PWM_BREAK_CTL_REG(reg_idx) & ~0x00000080) | (brk_dbc_en << 7);
}
__INLINE uint8_t pwm_break_ctl__brk_dbc_step__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_BREAK_CTL_REG(reg_idx);
return ((localVal & 0x0000007E) >> 1);
}
__INLINE void pwm_break_ctl__brk_dbc_step__setf(uint32_t reg_idx, uint8_t brk_dbc_step)
{
ASSERT_ERR(reg_idx <= 5);
ASSERT_ERR(((brk_dbc_step << 1) & ~0x0000007E) == 0);
PWM_BREAK_CTL_REG(reg_idx) = (PWM_BREAK_CTL_REG(reg_idx) & ~0x0000007E) | (brk_dbc_step << 1);
}
__INLINE uint8_t pwm_break_ctl__clear__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_BREAK_CTL_REG(reg_idx);
return ((localVal & 0x00000001) >> 0);
}
__INLINE void pwm_break_ctl__clear__setf(uint32_t reg_idx, uint8_t clear)
{
ASSERT_ERR(reg_idx <= 5);
ASSERT_ERR(((clear << 0) & ~0x00000001) == 0);
PWM_BREAK_CTL_REG(reg_idx) = (PWM_BREAK_CTL_REG(reg_idx) & ~0x00000001) | (clear << 0);
}
#endif // _XC_REG_PWM_H_
@@ -0,0 +1,487 @@
#ifndef _XC_REG_PWM_COMN_H_
#define _XC_REG_PWM_COMN_H_
#include <stdint.h>
#define XC_REG_PWM_COMN_BASE_ADDR 0x40017C00
#define XC_REG_PWM_COMN_DECODING_MASK 0x0000003F
#define PWM_COMMON_REG_SIZE 0x04
/**
* @brief CAP_TIM_VAL register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 15:00 CAPTURE_VALUE 0x0
* </pre>
*/
#define CAP_TIM_VAL_REG(i) (* ((volatile uint32_t *)(0x40017C00 + i*PWM_COMMON_REG_SIZE)) )
#define CAP_TIM_VAL_ADDR(i) (0x40017C00 + i*PWM_COMMON_REG_SIZE)
#define CAP_TIM_VAL_OFFSET 0x00000000
__INLINE uint32_t cap_tim_val_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
return CAP_TIM_VAL_REG(reg_idx);
}
// field definitions
#define CAPTURE_VALUE_MASK 0x0000FFFF
#define CAPTURE_VALUE_LSB 0
#define CAPTURE_VALUE_WIDTH 0x00000010
#define CAPTURE_VALUE_RST 0x0
__INLINE uint16_t cap_tim_val__capture_value__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = CAP_TIM_VAL_REG(reg_idx);
ASSERT_ERR((localVal & ~0x0000FFFF) == 0);
return (localVal >> 0);
}
/**
* @brief PWM_CAP_TIM_INT register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 02 CAPTURE_UPD2 0
* 01 CAPTURE_UPD1 0
* 00 CAPTURE_UPD0 0
* </pre>
*/
#define PWM_CAP_TIM_INT_REG (*(volatile uint32_t *)(0x40017C0C))
#define PWM_CAP_TIM_INT_ADDR 0x40017C0C
#define PWM_CAP_TIM_INT_OFFSET 0x0000000C
__INLINE uint32_t pwm_cap_tim_int_get(void)
{
return PWM_CAP_TIM_INT_REG;
}
__INLINE void pwm_cap_tim_int_set(uint32_t value)
{
PWM_CAP_TIM_INT_REG = value;
}
// field definitions
#define CAPTURE_UPD2_BIT 0x00000004
#define CAPTURE_UPD2_POS 2
#define CAPTURE_UPD1_BIT 0x00000002
#define CAPTURE_UPD1_POS 1
#define CAPTURE_UPD0_BIT 0x00000001
#define CAPTURE_UPD0_POS 0
#define CAPTURE_UPD2_RST 0x0
#define CAPTURE_UPD1_RST 0x0
#define CAPTURE_UPD0_RST 0x0
__INLINE void pwm_cap_tim_int_pack(uint8_t capture_upd2, uint8_t capture_upd1, uint8_t capture_upd0)
{
ASSERT_ERR(((capture_upd2 << 2) & ~0x00000004) == 0);
ASSERT_ERR(((capture_upd1 << 1) & ~0x00000002) == 0);
ASSERT_ERR(((capture_upd0 << 0) & ~0x00000001) == 0);
PWM_CAP_TIM_INT_REG = (capture_upd2 << 2) | (capture_upd1 << 1) | (capture_upd0 << 0);
}
__INLINE void pwm_cap_tim_int_unpack(uint8_t* capture_upd2, uint8_t* capture_upd1, uint8_t* capture_upd0)
{
uint32_t localVal = PWM_CAP_TIM_INT_REG;
*capture_upd2 = (localVal & 0x00000004) >> 2;
*capture_upd1 = (localVal & 0x00000002) >> 1;
*capture_upd0 = (localVal & 0x00000001) >> 0;
}
__INLINE uint8_t pwm_cap_tim_int__capture_upd2__getf(void)
{
uint32_t localVal = PWM_CAP_TIM_INT_REG;
return ((localVal & 0x00000004) >> 2);
}
__INLINE void pwm_cap_tim_int__capture_upd2__setf(uint8_t capture_upd2)
{
ASSERT_ERR(((capture_upd2 << 2) & ~0x00000004) == 0);
PWM_CAP_TIM_INT_REG = (PWM_CAP_TIM_INT_REG & ~0x00000004) | (capture_upd2 << 2);
}
__INLINE uint8_t pwm_cap_tim_int__capture_upd1__getf(void)
{
uint32_t localVal = PWM_CAP_TIM_INT_REG;
return ((localVal & 0x00000002) >> 1);
}
__INLINE void pwm_cap_tim_int__capture_upd1__setf(uint8_t capture_upd1)
{
ASSERT_ERR(((capture_upd1 << 1) & ~0x00000002) == 0);
PWM_CAP_TIM_INT_REG = (PWM_CAP_TIM_INT_REG & ~0x00000002) | (capture_upd1 << 1);
}
__INLINE uint8_t pwm_cap_tim_int__capture_upd0__getf(void)
{
uint32_t localVal = PWM_CAP_TIM_INT_REG;
return ((localVal & 0x00000001) >> 0);
}
__INLINE void pwm_cap_tim_int__capture_upd0__setf(uint8_t capture_upd0)
{
ASSERT_ERR(((capture_upd0 << 0) & ~0x00000001) == 0);
PWM_CAP_TIM_INT_REG = (PWM_CAP_TIM_INT_REG & ~0x00000001) | (capture_upd0 << 0);
}
/**
* @brief PWM_CAP_TIM_INT_EN register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 02 capture_upd2_en 0
* 01 capture_upd1_en 0
* 00 capture_upd0_en 0
* </pre>
*/
#define PWM_CAP_TIM_INT_EN_REG (*(volatile uint32_t *)(0x40017C10))
#define PWM_CAP_TIM_INT_EN_ADDR 0x40017C10
#define PWM_CAP_TIM_INT_EN_OFFSET 0x00000010
__INLINE uint32_t pwm_cap_tim_int_en_get(void)
{
return PWM_CAP_TIM_INT_EN_REG;
}
__INLINE void pwm_cap_tim_int_en_set(uint32_t value)
{
PWM_CAP_TIM_INT_EN_REG = value;
}
// field definitions
#define CAPTURE_UPD_2_EN_BIT 0x00000004
#define CAPTURE_UPD_2_EN_POS 2
#define CAPTURE_UPD_1_EN_BIT 0x00000002
#define CAPTURE_UPD_1_EN_POS 1
#define CAPTURE_UPD_0_EN_BIT 0x00000001
#define CAPTURE_UPD_0_EN_POS 0
#define CAPTURE_UPD_2_EN_RST 0x0
#define CAPTURE_UPD_1_EN_RST 0x0
#define CAPTURE_UPD_0_EN_RST 0x0
__INLINE void pwm_cap_tim_int_en_pack(uint8_t capture_upd2_en, uint8_t capture_upd1_en, uint8_t capture_upd0_en)
{
ASSERT_ERR(((capture_upd2_en << 2) & ~0x00000004) == 0);
ASSERT_ERR(((capture_upd1_en << 1) & ~0x00000002) == 0);
ASSERT_ERR(((capture_upd0_en << 0) & ~0x00000001) == 0);
PWM_CAP_TIM_INT_EN_REG = (capture_upd2_en << 2) | (capture_upd1_en << 1) | (capture_upd0_en << 0);
}
__INLINE void pwm_cap_tim_int_en_unpack(uint8_t* capture_upd2_en, uint8_t* capture_upd1_en, uint8_t* capture_upd0_en)
{
uint32_t localVal = PWM_CAP_TIM_INT_EN_REG;
*capture_upd2_en = (localVal & 0x00000004) >> 2;
*capture_upd1_en = (localVal & 0x00000002) >> 1;
*capture_upd0_en = (localVal & 0x00000001) >> 0;
}
__INLINE uint8_t pwm_cap_tim_int_en__capture_upd_2_en__getf(void)
{
uint32_t localVal = PWM_CAP_TIM_INT_EN_REG;
return ((localVal & 0x00000004) >> 2);
}
__INLINE void pwm_cap_tim_int_en__capture_upd_2_en__setf(uint8_t capture_upd2_en)
{
ASSERT_ERR(((capture_upd2_en << 2) & ~0x00000004) == 0);
PWM_CAP_TIM_INT_EN_REG = (PWM_CAP_TIM_INT_EN_REG & ~0x00000004) | (capture_upd2_en << 2);
}
__INLINE uint8_t pwm_cap_tim_int_en__capture_upd_1_en__getf(void)
{
uint32_t localVal = PWM_CAP_TIM_INT_EN_REG;
return ((localVal & 0x00000002) >> 1);
}
__INLINE void pwm_cap_tim_int_en__capture_upd_1_en__setf(uint8_t capture_upd1_en)
{
ASSERT_ERR(((capture_upd1_en << 1) & ~0x00000002) == 0);
PWM_CAP_TIM_INT_EN_REG = (PWM_CAP_TIM_INT_EN_REG & ~0x00000002) | (capture_upd1_en << 1);
}
__INLINE uint8_t pwm_cap_tim_int_en__capture_upd_0_en__getf(void)
{
uint32_t localVal = PWM_CAP_TIM_INT_EN_REG;
return ((localVal & 0x00000001) >> 0);
}
__INLINE void pwm_cap_tim_int_en__capture_upd_0_en__setf(uint8_t capture_upd0_en)
{
ASSERT_ERR(((capture_upd0_en << 0) & ~0x00000001) == 0);
PWM_CAP_TIM_INT_EN_REG = (PWM_CAP_TIM_INT_EN_REG & ~0x00000001) | (capture_upd0_en << 0);
}
/**
* @brief PWM_CAP_TIM_INT_RAW register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 02 capture_upd2_raw 0
* 01 capture_upd1_raw 0
* 00 capture_upd0_raw 0
* </pre>
*/
#define PWM_CAP_TIM_INT_RAW_REG (*(volatile uint32_t *)(0x40017C14))
#define PWM_CAP_TIM_INT_RAW_ADDR 0x40017C14
#define PWM_CAP_TIM_INT_RAW_OFFSET 0x00000014
__INLINE uint32_t pwm_cap_tim_int_raw_get(void)
{
return PWM_CAP_TIM_INT_RAW_REG;
}
// field definitions
#define CAPTURE_UPD_2_RAW_BIT 0x00000004
#define CAPTURE_UPD_2_RAW_POS 2
#define CAPTURE_UPD_1_RAW_BIT 0x00000002
#define CAPTURE_UPD_1_RAW_POS 1
#define CAPTURE_UPD_0_RAW_BIT 0x00000001
#define CAPTURE_UPD_0_RAW_POS 0
#define CAPTURE_UPD_2_RAW_RST 0x0
#define CAPTURE_UPD_1_RAW_RST 0x0
#define CAPTURE_UPD_0_RAW_RST 0x0
__INLINE void pwm_cap_tim_int_raw_unpack(uint8_t* capture_upd2_raw, uint8_t* capture_upd1_raw, uint8_t* capture_upd0_raw)
{
uint32_t localVal = PWM_CAP_TIM_INT_RAW_REG;
*capture_upd2_raw = (localVal & 0x00000004) >> 2;
*capture_upd1_raw = (localVal & 0x00000002) >> 1;
*capture_upd0_raw = (localVal & 0x00000001) >> 0;
}
__INLINE uint8_t pwm_cap_tim_int_raw__capture_upd_2_raw__getf(void)
{
uint32_t localVal = PWM_CAP_TIM_INT_RAW_REG;
return ((localVal & 0x00000004) >> 2);
}
__INLINE uint8_t pwm_cap_tim_int_raw__capture_upd_1_raw__getf(void)
{
uint32_t localVal = PWM_CAP_TIM_INT_RAW_REG;
return ((localVal & 0x00000002) >> 1);
}
__INLINE uint8_t pwm_cap_tim_int_raw__capture_upd_0_raw__getf(void)
{
uint32_t localVal = PWM_CAP_TIM_INT_RAW_REG;
return ((localVal & 0x00000001) >> 0);
}
/**
* @brief CAP_TIM_CTL register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 23:19 CLK_DIV_VAL 0x0
* 18:16 CAPTURE_SIG_SEL 0x0
* 14 DBC_EN 0
* 13:08 DBC_STEP 0x0
* 05:04 CAPTURE_MODE 0x0
* 03:02 CAPTURE_PSC 0x0
* 01 capture_enable 0
* 00 COMMON_CNT_ENABLE 0
* </pre>
*/
#define CAP_TIM_CTL_REG(i) (* ((volatile uint32_t *)(0x40017C18 + i*PWM_COMMON_REG_SIZE)) )
#define CAP_TIM_CTL_ADDR(i) (0x40017C18 + i*PWM_COMMON_REG_SIZE)
#define CAP_TIM_CTL_OFFSET 0x00000018
__INLINE uint32_t cap_tim_ctl_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
return CAP_TIM_CTL_REG(reg_idx);
}
__INLINE void cap_tim_ctl_set(uint32_t reg_idx, uint32_t value)
{
ASSERT_ERR(reg_idx <= 2);
CAP_TIM_CTL_REG(reg_idx) = value;
}
// field definitions
#define CLK_DIV_VAL_MASK 0x00F80000
#define CLK_DIV_VAL_LSB 19
#define CLK_DIV_VAL_WIDTH 0x00000005
#define CAPTURE_SIG_SEL_MASK 0x00070000
#define CAPTURE_SIG_SEL_LSB 16
#define CAPTURE_SIG_SEL_WIDTH 0x00000003
#define DBC_EN_BIT 0x00004000
#define DBC_EN_POS 14
#define DBC_STEP_MASK 0x00003F00
#define DBC_STEP_LSB 8
#define DBC_STEP_WIDTH 0x00000006
#define CAPTURE_MODE_MASK 0x00000030
#define CAPTURE_MODE_LSB 4
#define CAPTURE_MODE_WIDTH 0x00000002
#define CAPTURE_PSC_MASK 0x0000000C
#define CAPTURE_PSC_LSB 2
#define CAPTURE_PSC_WIDTH 0x00000002
#define CAPTURE_ENABLE_BIT 0x00000002
#define CAPTURE_ENABLE_POS 1
#define COMMON_CNT_ENABLE_BIT 0x00000001
#define COMMON_CNT_ENABLE_POS 0
#define CLK_DIV_VAL_RST 0x0
#define CAPTURE_SIG_SEL_RST 0x0
#define DBC_EN_RST 0x0
#define DBC_STEP_RST 0x0
#define CAPTURE_MODE_RST 0x0
#define CAPTURE_PSC_RST 0x0
#define CAPTURE_ENABLE_RST 0x0
#define COMMON_CNT_ENABLE_RST 0x0
__INLINE void cap_tim_ctl_pack(uint32_t reg_idx, uint8_t clk_div_val, uint8_t capture_sig_sel, uint8_t dbc_en, uint8_t dbc_step, uint8_t capture_mode, uint8_t capture_psc, uint8_t capture_enable, uint8_t common_cnt_enable)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((clk_div_val << 19) & ~0x00F80000) == 0);
ASSERT_ERR(((capture_sig_sel << 16) & ~0x00070000) == 0);
ASSERT_ERR(((dbc_en << 14) & ~0x00004000) == 0);
ASSERT_ERR(((dbc_step << 8) & ~0x00003F00) == 0);
ASSERT_ERR(((capture_mode << 4) & ~0x00000030) == 0);
ASSERT_ERR(((capture_psc << 2) & ~0x0000000C) == 0);
ASSERT_ERR(((capture_enable << 1) & ~0x00000002) == 0);
ASSERT_ERR(((common_cnt_enable << 0) & ~0x00000001) == 0);
CAP_TIM_CTL_REG(reg_idx) = (clk_div_val << 19) | (capture_sig_sel << 16) | (dbc_en << 14) | (dbc_step << 8) | (capture_mode << 4) | (capture_psc << 2) | (capture_enable << 1) | (common_cnt_enable << 0);
}
__INLINE void cap_tim_ctl_unpack(uint32_t reg_idx, uint8_t* clk_div_val, uint8_t* capture_sig_sel, uint8_t* dbc_en, uint8_t* dbc_step, uint8_t* capture_mode, uint8_t* capture_psc, uint8_t* capture_enable, uint8_t* common_cnt_enable)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = CAP_TIM_CTL_REG(reg_idx);
*clk_div_val = (localVal & 0x00F80000) >> 19;
*capture_sig_sel = (localVal & 0x00070000) >> 16;
*dbc_en = (localVal & 0x00004000) >> 14;
*dbc_step = (localVal & 0x00003F00) >> 8;
*capture_mode = (localVal & 0x00000030) >> 4;
*capture_psc = (localVal & 0x0000000C) >> 2;
*capture_enable = (localVal & 0x00000002) >> 1;
*common_cnt_enable = (localVal & 0x00000001) >> 0;
}
__INLINE uint8_t cap_tim_ctl__clk_div_val__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = CAP_TIM_CTL_REG(reg_idx);
return ((localVal & 0x00F80000) >> 19);
}
__INLINE void cap_tim_ctl__clk_div_val__setf(uint32_t reg_idx, uint8_t clk_div_val)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((clk_div_val << 19) & ~0x00F80000) == 0);
CAP_TIM_CTL_REG(reg_idx) = (CAP_TIM_CTL_REG(reg_idx) & ~0x00F80000) | (clk_div_val << 19);
}
__INLINE uint8_t cap_tim_ctl__capture_sig_sel__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = CAP_TIM_CTL_REG(reg_idx);
return ((localVal & 0x00070000) >> 16);
}
__INLINE void cap_tim_ctl__capture_sig_sel__setf(uint32_t reg_idx, uint8_t capture_sig_sel)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((capture_sig_sel << 16) & ~0x00070000) == 0);
CAP_TIM_CTL_REG(reg_idx) = (CAP_TIM_CTL_REG(reg_idx) & ~0x00070000) | (capture_sig_sel << 16);
}
__INLINE uint8_t cap_tim_ctl__dbc_en__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = CAP_TIM_CTL_REG(reg_idx);
return ((localVal & 0x00004000) >> 14);
}
__INLINE void cap_tim_ctl__dbc_en__setf(uint32_t reg_idx, uint8_t dbc_en)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((dbc_en << 14) & ~0x00004000) == 0);
CAP_TIM_CTL_REG(reg_idx) = (CAP_TIM_CTL_REG(reg_idx) & ~0x00004000) | (dbc_en << 14);
}
__INLINE uint8_t cap_tim_ctl__dbc_step__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = CAP_TIM_CTL_REG(reg_idx);
return ((localVal & 0x00003F00) >> 8);
}
__INLINE void cap_tim_ctl__dbc_step__setf(uint32_t reg_idx, uint8_t dbc_step)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((dbc_step << 8) & ~0x00003F00) == 0);
CAP_TIM_CTL_REG(reg_idx) = (CAP_TIM_CTL_REG(reg_idx) & ~0x00003F00) | (dbc_step << 8);
}
__INLINE uint8_t cap_tim_ctl__capture_mode__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = CAP_TIM_CTL_REG(reg_idx);
return ((localVal & 0x00000030) >> 4);
}
__INLINE void cap_tim_ctl__capture_mode__setf(uint32_t reg_idx, uint8_t capture_mode)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((capture_mode << 4) & ~0x00000030) == 0);
CAP_TIM_CTL_REG(reg_idx) = (CAP_TIM_CTL_REG(reg_idx) & ~0x00000030) | (capture_mode << 4);
}
__INLINE uint8_t cap_tim_ctl__capture_psc__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = CAP_TIM_CTL_REG(reg_idx);
return ((localVal & 0x0000000C) >> 2);
}
__INLINE void cap_tim_ctl__capture_psc__setf(uint32_t reg_idx, uint8_t capture_psc)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((capture_psc << 2) & ~0x0000000C) == 0);
CAP_TIM_CTL_REG(reg_idx) = (CAP_TIM_CTL_REG(reg_idx) & ~0x0000000C) | (capture_psc << 2);
}
__INLINE uint8_t cap_tim_ctl__capture_enable__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = CAP_TIM_CTL_REG(reg_idx);
return ((localVal & 0x00000002) >> 1);
}
__INLINE void cap_tim_ctl__capture_enable__setf(uint32_t reg_idx, uint8_t capture_enable)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((capture_enable << 1) & ~0x00000002) == 0);
CAP_TIM_CTL_REG(reg_idx) = (CAP_TIM_CTL_REG(reg_idx) & ~0x00000002) | (capture_enable << 1);
}
__INLINE uint8_t cap_tim_ctl__common_cnt_enable__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = CAP_TIM_CTL_REG(reg_idx);
return ((localVal & 0x00000001) >> 0);
}
__INLINE void cap_tim_ctl__common_cnt_enable__setf(uint32_t reg_idx, uint8_t common_cnt_enable)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((common_cnt_enable << 0) & ~0x00000001) == 0);
CAP_TIM_CTL_REG(reg_idx) = (CAP_TIM_CTL_REG(reg_idx) & ~0x00000001) | (common_cnt_enable << 0);
}
#endif // _XC_REG_PWM_COMN_H_
@@ -0,0 +1,453 @@
#ifndef _XC_REG_PWM_TIMER_H_
#define _XC_REG_PWM_TIMER_H_
#include <stdint.h>
#include "xc_reg_offset.h"
#define XC_REG_PWM_TIMER_BASE_ADDR 0x40017D00
#define XC_REG_PWM_TIMER_DECODING_MASK 0x000000FF
#define PWM_TIMER_REG_SIZE 0x14
#define PWM_LOAD_CNT2_REG_SIZE 0x04
/**
* @brief PWM_TIMER_LOADCOUNT register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 15:00 TIMER_LC 0x0
* </pre>
*/
#define PWM_TIMER_LOADCOUNT_REG(i) (* ((volatile uint32_t *)(0x40017D00 + i*PWM_TIMER_REG_SIZE)) )
#define PWM_TIMER_LOADCOUNT_ADDR(i) (0x40017D00 + i*PWM_TIMER_REG_SIZE)
#define PWM_TIMER_LOADCOUNT_OFFSET 0x00000000
__INLINE uint32_t pwm_timer_loadcount_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
return PWM_TIMER_LOADCOUNT_REG(reg_idx);
}
__INLINE void pwm_timer_loadcount_set(uint32_t reg_idx, uint32_t value)
{
ASSERT_ERR(reg_idx <= 5);
PWM_TIMER_LOADCOUNT_REG(reg_idx) = value;
}
// field definitions
#define TIMER_LC_MASK 0x0000FFFF
#define TIMER_LC_LSB 0
#define TIMER_LC_WIDTH 0x00000010
#define TIMER_LC_RST 0x0
__INLINE uint16_t pwm_timer_loadcount__timer_lc__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_TIMER_LOADCOUNT_REG(reg_idx);
ASSERT_ERR((localVal & ~0x0000FFFF) == 0);
return (localVal >> 0);
}
__INLINE void pwm_timer_loadcount__timer_lc__setf(uint32_t reg_idx, uint16_t timer_lc)
{
ASSERT_ERR(reg_idx <= 5);
ASSERT_ERR(((timer_lc << 0) & ~0x0000FFFF) == 0);
PWM_TIMER_LOADCOUNT_REG(reg_idx) = timer_lc << 0;
}
/**
* @brief PWM_TIMER_CURRENTVAL register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 15:00 TIMER_CV 0x0
* </pre>
*/
#define PWM_TIMER_CURRENTVAL_REG(i) (* ((volatile uint32_t *)(0x40017D04 + i*PWM_TIMER_REG_SIZE)) )
#define PWM_TIMER_CURRENTVAL_ADDR(i) (0x40017D04 + i*PWM_TIMER_REG_SIZE)
#define PWM_TIMER_CURRENTVAL_OFFSET 0x00000004
__INLINE uint32_t pwm_timer_currentval_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
return PWM_TIMER_CURRENTVAL_REG(reg_idx);
}
// field definitions
#define TIMER_CV_MASK 0x0000FFFF
#define TIMER_CV_LSB 0
#define TIMER_CV_WIDTH 0x00000010
#define TIMER_CV_RST 0x0
__INLINE uint16_t pwm_timer_currentval__timer_cv__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_TIMER_CURRENTVAL_REG(reg_idx);
ASSERT_ERR((localVal & ~0x0000FFFF) == 0);
return (localVal >> 0);
}
/**
* @brief PWM_TIMER_CONTROLREG register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 04 TIMER_ON10OPWM_EN 0
* 03 TIMER_PWM 0
* 02 TIMER_INT_MASK 0
* 01 TIMER_MODE 0
* 00 TIMER_EN 0
* </pre>
*/
#define PWM_TIMER_CONTROLREG_REG(i) (* ((volatile uint32_t *)(0x40017D08 + i*PWM_TIMER_REG_SIZE)) )
#define PWM_TIMER_CONTROLREG_ADDR(i) (0x40017D08 + i*PWM_TIMER_REG_SIZE)
#define PWM_TIMER_CONTROLREG_OFFSET 0x00000008
__INLINE uint32_t pwm_timer_controlreg_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
return PWM_TIMER_CONTROLREG_REG(reg_idx);
}
__INLINE void pwm_timer_controlreg_set(uint32_t reg_idx, uint32_t value)
{
ASSERT_ERR(reg_idx <= 5);
PWM_TIMER_CONTROLREG_REG(reg_idx) = value;
}
// field definitions
#define TIMER_ON10OPWM_EN_BIT 0x00000010
#define TIMER_ON10OPWM_EN_POS 4
#define TIMER_PWM_BIT 0x00000008
#define TIMER_PWM_POS 3
#define TIMER_INT_MASK_BIT 0x00000004
#define TIMER_INT_MASK_POS 2
#define TIMER_MODE_BIT 0x00000002
#define TIMER_MODE_POS 1
#define TIMER_EN_BIT 0x00000001
#define TIMER_EN_POS 0
#define TIMER_ON10OPWM_EN_RST 0x0
#define TIMER_PWM_RST 0x0
#define TIMER_INT_MASK_RST 0x0
#define TIMER_MODE_RST 0x0
#define TIMER_EN_RST 0x0
__INLINE void pwm_timer_controlreg_pack(uint32_t reg_idx, uint8_t timer_int_mask, uint8_t timer_mode, uint8_t timer_en)
{
ASSERT_ERR(reg_idx <= 5);
ASSERT_ERR(((timer_int_mask << 2) & ~0x00000004) == 0);
ASSERT_ERR(((timer_mode << 1) & ~0x00000002) == 0);
ASSERT_ERR(((timer_en << 0) & ~0x00000001) == 0);
PWM_TIMER_CONTROLREG_REG(reg_idx) = (timer_int_mask << 2) | (timer_mode << 1) | (timer_en << 0);
}
__INLINE void pwm_timer_controlreg_unpack(uint32_t reg_idx, uint8_t* timer_on10opwm_en, uint8_t* timer_pwm, uint8_t* timer_int_mask, uint8_t* timer_mode, uint8_t* timer_en)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_TIMER_CONTROLREG_REG(reg_idx);
*timer_on10opwm_en = (localVal & 0x00000010) >> 4;
*timer_pwm = (localVal & 0x00000008) >> 3;
*timer_int_mask = (localVal & 0x00000004) >> 2;
*timer_mode = (localVal & 0x00000002) >> 1;
*timer_en = (localVal & 0x00000001) >> 0;
}
__INLINE uint8_t pwm_timer_controlreg__timer_on10opwm_en__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_TIMER_CONTROLREG_REG(reg_idx);
return ((localVal & 0x00000010) >> 4);
}
__INLINE uint8_t pwm_timer_controlreg__timer_pwm__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_TIMER_CONTROLREG_REG(reg_idx);
return ((localVal & 0x00000008) >> 3);
}
__INLINE uint8_t pwm_timer_controlreg__timer_int_mask__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_TIMER_CONTROLREG_REG(reg_idx);
return ((localVal & 0x00000004) >> 2);
}
__INLINE void pwm_timer_controlreg__timer_int_mask__setf(uint32_t reg_idx, uint8_t timer_int_mask)
{
ASSERT_ERR(reg_idx <= 5);
ASSERT_ERR(((timer_int_mask << 2) & ~0x00000004) == 0);
PWM_TIMER_CONTROLREG_REG(reg_idx) = (PWM_TIMER_CONTROLREG_REG(reg_idx) & ~0x00000004) | (timer_int_mask << 2);
}
__INLINE uint8_t pwm_timer_controlreg__timer_mode__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_TIMER_CONTROLREG_REG(reg_idx);
return ((localVal & 0x00000002) >> 1);
}
__INLINE void pwm_timer_controlreg__timer_mode__setf(uint32_t reg_idx, uint8_t timer_mode)
{
ASSERT_ERR(reg_idx <= 5);
ASSERT_ERR(((timer_mode << 1) & ~0x00000002) == 0);
PWM_TIMER_CONTROLREG_REG(reg_idx) = (PWM_TIMER_CONTROLREG_REG(reg_idx) & ~0x00000002) | (timer_mode << 1);
}
__INLINE uint8_t pwm_timer_controlreg__timer_en__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_TIMER_CONTROLREG_REG(reg_idx);
return ((localVal & 0x00000001) >> 0);
}
__INLINE void pwm_timer_controlreg__timer_en__setf(uint32_t reg_idx, uint8_t timer_en)
{
ASSERT_ERR(reg_idx <= 5);
ASSERT_ERR(((timer_en << 0) & ~0x00000001) == 0);
PWM_TIMER_CONTROLREG_REG(reg_idx) = (PWM_TIMER_CONTROLREG_REG(reg_idx) & ~0x00000001) | (timer_en << 0);
}
/**
* @brief PWM_TIMER_EOI register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 00 Timer_EOI 0
* </pre>
*/
#define PWM_TIMER_EOI_REG(i) (* ((volatile uint32_t *)(0x40017D0C + i*PWM_TIMER_REG_SIZE)) )
#define PWM_TIMER_EOI_ADDR(i) (0x40017D0C + i*PWM_TIMER_REG_SIZE)
#define PWM_TIMER_EOI_OFFSET 0x0000000C
__INLINE uint32_t pwm_timer_eoi_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
return PWM_TIMER_EOI_REG(reg_idx);
}
// field definitions
#define TIMER_EOI_BIT 0x00000001
#define TIMER_EOI_POS 0
#define TIMER_EOI_RST 0x0
__INLINE uint8_t pwm_timer_eoi__timer_eoi__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_TIMER_EOI_REG(reg_idx);
ASSERT_ERR((localVal & ~0x00000001) == 0);
return (localVal >> 0);
}
/**
* @brief PWM_TIMER_INTSTAT register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 00 Timer_IS 0
* </pre>
*/
#define PWM_TIMER_INTSTAT_REG(i) (* ((volatile uint32_t *)(0x40017D10 + i*PWM_TIMER_REG_SIZE)) )
#define PWM_TIMER_INTSTAT_ADDR(i) (0x40017D10 + i*PWM_TIMER_REG_SIZE)
#define PWM_TIMER_INTSTAT_OFFSET 0x00000010
__INLINE uint32_t pwm_timer_intstat_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
return PWM_TIMER_INTSTAT_REG(reg_idx);
}
// field definitions
#define TIMER_IS_BIT 0x00000001
#define TIMER_IS_POS 0
#define TIMER_IS_RST 0x0
__INLINE uint8_t pwm_timer_intstat__timer_is__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_TIMER_INTSTAT_REG(reg_idx);
ASSERT_ERR((localVal & ~0x00000001) == 0);
return (localVal >> 0);
}
/**
* @brief PWM_TIMER_A_TIS register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 05:00 Timers_IS 0x0
* </pre>
*/
#define PWM_TIMER_A_TIS_REG (*(volatile uint32_t *)(0x40017DA0))
#define PWM_TIMER_A_TIS_ADDR 0x40017DA0
#define PWM_TIMER_A_TIS_OFFSET 0x000000A0
__INLINE uint32_t pwm_timer_a_tis_get(void)
{
return PWM_TIMER_A_TIS_REG;
}
// field definitions
#define TIMERS_IS_MASK 0x0000003F
#define TIMERS_IS_LSB 0
#define TIMERS_IS_WIDTH 0x00000006
#define TIMERS_IS_RST 0x0
__INLINE uint8_t pwm_timer_a_tis__timers_is__getf(void)
{
uint32_t localVal = PWM_TIMER_A_TIS_REG;
ASSERT_ERR((localVal & ~0x0000003F) == 0);
return (localVal >> 0);
}
/**
* @brief PWM_TIMER_A_TEOI register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 05:00 TIMERS_EOI 0x0
* </pre>
*/
#define PWM_TIMER_A_TEOI_REG (*(volatile uint32_t *)(0x40017DA4))
#define PWM_TIMER_A_TEOI_ADDR 0x40017DA4
#define PWM_TIMER_A_TEOI_OFFSET 0x000000A4
__INLINE uint32_t pwm_timer_a_teoi_get(void)
{
return PWM_TIMER_A_TEOI_REG;
}
// field definitions
#define TIMERS_EOI_MASK 0x0000003F
#define TIMERS_EOI_LSB 0
#define TIMERS_EOI_WIDTH 0x00000006
#define TIMERS_EOI_RST 0x0
__INLINE uint8_t pwm_timer_a_teoi__timers_eoi__getf(void)
{
uint32_t localVal = PWM_TIMER_A_TEOI_REG;
ASSERT_ERR((localVal & ~0x0000003F) == 0);
return (localVal >> 0);
}
/**
* @brief PWM_TIMER_A_TRIS register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 05:00 TIMERS_RIS 0x0
* </pre>
*/
#define PWM_TIMER_A_TRIS_REG (*(volatile uint32_t *)(0x40017DA8))
#define PWM_TIMER_A_TRIS_ADDR 0x40017DA8
#define PWM_TIMER_A_TRIS_OFFSET 0x000000A8
__INLINE uint32_t pwm_timer_a_tris_get(void)
{
return PWM_TIMER_A_TRIS_REG;
}
// field definitions
#define TIMERS_RIS_MASK 0x0000003F
#define TIMERS_RIS_LSB 0
#define TIMERS_RIS_WIDTH 0x00000006
#define TIMERS_RIS_RST 0x0
__INLINE uint8_t pwm_timer_a_tris__timers_ris__getf(void)
{
uint32_t localVal = PWM_TIMER_A_TRIS_REG;
ASSERT_ERR((localVal & ~0x0000003F) == 0);
return (localVal >> 0);
}
/**
* @brief PWM_TIMER_TCOMP register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 31:00 TIMERS_COMP 0x0
* </pre>
*/
#define PWM_TIMER_TCOMP_REG (*(volatile uint32_t *)(0x40017DAC))
#define PWM_TIMER_TCOMP_ADDR 0x40017DAC
#define PWM_TIMER_TCOMP_OFFSET 0x000000AC
__INLINE uint32_t pwm_timer_tcomp_get(void)
{
return PWM_TIMER_TCOMP_REG;
}
// field definitions
#define TIMERS_COMP_MASK 0xFFFFFFFF
#define TIMERS_COMP_LSB 0
#define TIMERS_COMP_WIDTH 0x00000020
#define TIMERS_COMP_RST 0x0
__INLINE uint32_t pwm_timer_tcomp__timers_comp__getf(void)
{
uint32_t localVal = PWM_TIMER_TCOMP_REG;
ASSERT_ERR((localVal & ~0xFFFFFFFF) == 0);
return (localVal >> 0);
}
/**
* @brief PWM_TIMER_LOADCOUNT2 register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 11:00 TIMER_LC2 0x0
* </pre>
*/
#define PWM_TIMER_LOADCOUNT2_REG(i) (* ((volatile uint32_t *)(0x40017DB0 + i*PWM_LOAD_CNT2_REG_SIZE)) )
#define PWM_TIMER_LOADCOUNT2_ADDR(i) (0x40017DB0 + i*PWM_LOAD_CNT2_REG_SIZE)
#define PWM_TIMER_LOADCOUNT2_OFFSET 0x000000B0
__INLINE uint32_t pwm_timer_loadcount2_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
return PWM_TIMER_LOADCOUNT2_REG(reg_idx);
}
__INLINE void pwm_timer_loadcount2_set(uint32_t reg_idx, uint32_t value)
{
ASSERT_ERR(reg_idx <= 5);
PWM_TIMER_LOADCOUNT2_REG(reg_idx) = value;
}
// field definitions
#define TIMER_LC2_MASK 0x00000FFF
#define TIMER_LC2_LSB 0
#define TIMER_LC2_WIDTH 0x0000000C
#define TIMER_LC2_RST 0x0
__INLINE uint16_t pwm_timer_loadcount2__timer_lc2__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 5);
uint32_t localVal = PWM_TIMER_LOADCOUNT2_REG(reg_idx);
ASSERT_ERR((localVal & ~0x00000FFF) == 0);
return (localVal >> 0);
}
__INLINE void pwm_timer_loadcount2__timer_lc2__setf(uint32_t reg_idx, uint16_t timer_lc2)
{
ASSERT_ERR(reg_idx <= 5);
ASSERT_ERR(((timer_lc2 << 0) & ~0x00000FFF) == 0);
PWM_TIMER_LOADCOUNT2_REG(reg_idx) = timer_lc2 << 0;
}
#endif // _XC_REG_PWM_TIMER_H_
@@ -0,0 +1,665 @@
#ifndef _XC_REG_QDEC_H_
#define _XC_REG_QDEC_H_
#include <stdint.h>
#include "xc_reg_offset.h"
#define XC_REG_QDEC_BASE_ADDR 0x40016000
#define XC_REG_QDEC_DECODING_MASK 0x0000003F
/**
* @brief QDEC_CTL register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 06 DB_FILTER_EN 0
* 05 SINGLE_SAMPLE_RST_EN 0
* 04 AUTO_CLR_EN 0
* 03 SOFT_CLR 0
* 02 SOFT_RST 0
* 01 QDEC_START 0
* 00 QDEC_EN 0
* </pre>
*/
#define QDEC_CTL_REG (*(volatile uint32_t *)(0x40016000))
#define QDEC_CTL_ADDR 0x40016000
#define QDEC_CTL_OFFSET 0x00000000
__INLINE uint32_t qdec_ctl_get(void)
{
return QDEC_CTL_REG;
}
__INLINE void qdec_ctl_set(uint32_t value)
{
QDEC_CTL_REG = value;
}
// field definitions
#define DB_FILTER_EN_BIT 0x00000040
#define DB_FILTER_EN_POS 6
#define SINGLE_SAMPLE_RST_EN_BIT 0x00000020
#define SINGLE_SAMPLE_RST_EN_POS 5
#define AUTO_CLR_EN_BIT 0x00000010
#define AUTO_CLR_EN_POS 4
#define SOFT_CLR_BIT 0x00000008
#define SOFT_CLR_POS 3
#define SOFT_RST_BIT 0x00000004
#define SOFT_RST_POS 2
#define QDEC_START_BIT 0x00000002
#define QDEC_START_POS 1
#define QDEC_EN_BIT 0x00000001
#define QDEC_EN_POS 0
#define DB_FILTER_EN_RST 0x0
#define SINGLE_SAMPLE_RST_EN_RST 0x0
#define AUTO_CLR_EN_RST 0x0
#define SOFT_CLR_RST 0x0
#define SOFT_RST_RST 0x0
#define QDEC_START_RST 0x0
#define QDEC_EN_RST 0x0
__INLINE void qdec_ctl_pack(uint8_t db_filter_en, uint8_t single_sample_rst_en, uint8_t auto_clr_en, uint8_t soft_clr, uint8_t soft_rst, uint8_t qdec_start, uint8_t qdec_en)
{
ASSERT_ERR(((db_filter_en << 6) & ~0x00000040) == 0);
ASSERT_ERR(((single_sample_rst_en << 5) & ~0x00000020) == 0);
ASSERT_ERR(((auto_clr_en << 4) & ~0x00000010) == 0);
ASSERT_ERR(((soft_clr << 3) & ~0x00000008) == 0);
ASSERT_ERR(((soft_rst << 2) & ~0x00000004) == 0);
ASSERT_ERR(((qdec_start << 1) & ~0x00000002) == 0);
ASSERT_ERR(((qdec_en << 0) & ~0x00000001) == 0);
QDEC_CTL_REG = (db_filter_en << 6) | (single_sample_rst_en << 5) | (auto_clr_en << 4) | (soft_clr << 3) | (soft_rst << 2) | (qdec_start << 1) | (qdec_en << 0);
}
__INLINE void qdec_ctl_unpack(uint8_t* db_filter_en, uint8_t* single_sample_rst_en, uint8_t* auto_clr_en, uint8_t* soft_clr, uint8_t* soft_rst, uint8_t* qdec_start, uint8_t* qdec_en)
{
uint32_t localVal = QDEC_CTL_REG;
*db_filter_en = (localVal & 0x00000040) >> 6;
*single_sample_rst_en = (localVal & 0x00000020) >> 5;
*auto_clr_en = (localVal & 0x00000010) >> 4;
*soft_clr = (localVal & 0x00000008) >> 3;
*soft_rst = (localVal & 0x00000004) >> 2;
*qdec_start = (localVal & 0x00000002) >> 1;
*qdec_en = (localVal & 0x00000001) >> 0;
}
__INLINE uint8_t qdec_ctl__db_filter_en__getf(void)
{
uint32_t localVal = QDEC_CTL_REG;
return ((localVal & 0x00000040) >> 6);
}
__INLINE void qdec_ctl__db_filter_en__setf(uint8_t db_filter_en)
{
ASSERT_ERR(((db_filter_en << 6) & ~0x00000040) == 0);
QDEC_CTL_REG = (QDEC_CTL_REG & ~0x00000040) | (db_filter_en << 6);
}
__INLINE uint8_t qdec_ctl__single_sample_rst_en__getf(void)
{
uint32_t localVal = QDEC_CTL_REG;
return ((localVal & 0x00000020) >> 5);
}
__INLINE void qdec_ctl__single_sample_rst_en__setf(uint8_t single_sample_rst_en)
{
ASSERT_ERR(((single_sample_rst_en << 5) & ~0x00000020) == 0);
QDEC_CTL_REG = (QDEC_CTL_REG & ~0x00000020) | (single_sample_rst_en << 5);
}
__INLINE uint8_t qdec_ctl__auto_clr_en__getf(void)
{
uint32_t localVal = QDEC_CTL_REG;
return ((localVal & 0x00000010) >> 4);
}
__INLINE void qdec_ctl__auto_clr_en__setf(uint8_t auto_clr_en)
{
ASSERT_ERR(((auto_clr_en << 4) & ~0x00000010) == 0);
QDEC_CTL_REG = (QDEC_CTL_REG & ~0x00000010) | (auto_clr_en << 4);
}
__INLINE uint8_t qdec_ctl__soft_clr__getf(void)
{
uint32_t localVal = QDEC_CTL_REG;
return ((localVal & 0x00000008) >> 3);
}
__INLINE void qdec_ctl__soft_clr__setf(uint8_t soft_clr)
{
ASSERT_ERR(((soft_clr << 3) & ~0x00000008) == 0);
QDEC_CTL_REG = (QDEC_CTL_REG & ~0x00000008) | (soft_clr << 3);
}
__INLINE uint8_t qdec_ctl__soft_rst__getf(void)
{
uint32_t localVal = QDEC_CTL_REG;
return ((localVal & 0x00000004) >> 2);
}
__INLINE void qdec_ctl__soft_rst__setf(uint8_t soft_rst)
{
ASSERT_ERR(((soft_rst << 2) & ~0x00000004) == 0);
QDEC_CTL_REG = (QDEC_CTL_REG & ~0x00000004) | (soft_rst << 2);
}
__INLINE uint8_t qdec_ctl__qdec_start__getf(void)
{
uint32_t localVal = QDEC_CTL_REG;
return ((localVal & 0x00000002) >> 1);
}
__INLINE void qdec_ctl__qdec_start__setf(uint8_t qdec_start)
{
ASSERT_ERR(((qdec_start << 1) & ~0x00000002) == 0);
QDEC_CTL_REG = (QDEC_CTL_REG & ~0x00000002) | (qdec_start << 1);
}
__INLINE uint8_t qdec_ctl__qdec_en__getf(void)
{
uint32_t localVal = QDEC_CTL_REG;
return ((localVal & 0x00000001) >> 0);
}
__INLINE void qdec_ctl__qdec_en__setf(uint8_t qdec_en)
{
ASSERT_ERR(((qdec_en << 0) & ~0x00000001) == 0);
QDEC_CTL_REG = (QDEC_CTL_REG & ~0x00000001) | (qdec_en << 0);
}
/**
* @brief QDEC_SAMP_CTL register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 19:16 DB_SAMP_DIV 0x0
* 11:08 QDEC_PTS 0x0
* 04:00 QDEC_DIVIDE 0x0
* </pre>
*/
#define QDEC_SAMP_CTL_REG (*(volatile uint32_t *)(0x40016004))
#define QDEC_SAMP_CTL_ADDR 0x40016004
#define QDEC_SAMP_CTL_OFFSET 0x00000004
__INLINE uint32_t qdec_samp_ctl_get(void)
{
return QDEC_SAMP_CTL_REG;
}
__INLINE void qdec_samp_ctl_set(uint32_t value)
{
QDEC_SAMP_CTL_REG = value;
}
// field definitions
#define DB_SAMP_DIV_MASK 0x000F0000
#define DB_SAMP_DIV_LSB 16
#define DB_SAMP_DIV_WIDTH 0x00000004
#define QDEC_PTS_MASK 0x00000F00
#define QDEC_PTS_LSB 8
#define QDEC_PTS_WIDTH 0x00000004
#define QDEC_DIVIDE_MASK 0x0000001F
#define QDEC_DIVIDE_LSB 0
#define QDEC_DIVIDE_WIDTH 0x00000005
#define DB_SAMP_DIV_RST 0x0
#define QDEC_PTS_RST 0x0
#define QDEC_DIVIDE_RST 0x0
__INLINE void qdec_samp_ctl_pack(uint8_t db_samp_div, uint8_t qdec_pts, uint8_t qdec_divide)
{
ASSERT_ERR(((db_samp_div << 16) & ~0x000F0000) == 0);
ASSERT_ERR(((qdec_pts << 8) & ~0x00000F00) == 0);
ASSERT_ERR(((qdec_divide << 0) & ~0x0000001F) == 0);
QDEC_SAMP_CTL_REG = (db_samp_div << 16) | (qdec_pts << 8) | (qdec_divide << 0);
}
__INLINE void qdec_samp_ctl_unpack(uint8_t* db_samp_div, uint8_t* qdec_pts, uint8_t* qdec_divide)
{
uint32_t localVal = QDEC_SAMP_CTL_REG;
*db_samp_div = (localVal & 0x000F0000) >> 16;
*qdec_pts = (localVal & 0x00000F00) >> 8;
*qdec_divide = (localVal & 0x0000001F) >> 0;
}
__INLINE uint8_t qdec_samp_ctl__db_samp_div__getf(void)
{
uint32_t localVal = QDEC_SAMP_CTL_REG;
return ((localVal & 0x000F0000) >> 16);
}
__INLINE void qdec_samp_ctl__db_samp_div__setf(uint8_t db_samp_div)
{
ASSERT_ERR(((db_samp_div << 16) & ~0x000F0000) == 0);
QDEC_SAMP_CTL_REG = (QDEC_SAMP_CTL_REG & ~0x000F0000) | (db_samp_div << 16);
}
__INLINE uint8_t qdec_samp_ctl__qdec_pts__getf(void)
{
uint32_t localVal = QDEC_SAMP_CTL_REG;
return ((localVal & 0x00000F00) >> 8);
}
__INLINE void qdec_samp_ctl__qdec_pts__setf(uint8_t qdec_pts)
{
ASSERT_ERR(((qdec_pts << 8) & ~0x00000F00) == 0);
QDEC_SAMP_CTL_REG = (QDEC_SAMP_CTL_REG & ~0x00000F00) | (qdec_pts << 8);
}
__INLINE uint8_t qdec_samp_ctl__qdec_divide__getf(void)
{
uint32_t localVal = QDEC_SAMP_CTL_REG;
return ((localVal & 0x0000001F) >> 0);
}
__INLINE void qdec_samp_ctl__qdec_divide__setf(uint8_t qdec_divide)
{
ASSERT_ERR(((qdec_divide << 0) & ~0x0000001F) == 0);
QDEC_SAMP_CTL_REG = (QDEC_SAMP_CTL_REG & ~0x0000001F) | (qdec_divide << 0);
}
/**
* @brief QDEC_SAMPLE register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 01:00 QDEC_SAMPLE 0x0
* </pre>
*/
#define QDEC_SAMPLE_REG (*(volatile uint32_t *)(0x40016008))
#define QDEC_SAMPLE_ADDR 0x40016008
#define QDEC_SAMPLE_OFFSET 0x00000008
__INLINE uint32_t qdec_sample_get(void)
{
return QDEC_SAMPLE_REG;
}
// field definitions
#define QDEC_SAMPLE_MASK 0x00000003
#define QDEC_SAMPLE_LSB 0
#define QDEC_SAMPLE_WIDTH 0x00000002
#define QDEC_SAMPLE_RST 0x0
__INLINE uint8_t qdec_sample__getf(void)
{
uint32_t localVal = QDEC_SAMPLE_REG;
ASSERT_ERR((localVal & ~0x00000003) == 0);
return (localVal >> 0);
}
/**
* @brief QDEC_ACC register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 10:00 ACC 0x0
* </pre>
*/
#define QDEC_ACC_REG (*(volatile uint32_t *)(0x4001600C))
#define QDEC_ACC_ADDR 0x4001600C
#define QDEC_ACC_OFFSET 0x0000000C
__INLINE uint32_t qdec_acc_get(void)
{
return QDEC_ACC_REG;
}
// field definitions
#define ACC_MASK 0x000007FF
#define ACC_LSB 0
#define ACC_WIDTH 0x0000000B
#define ACC_RST 0x0
__INLINE uint16_t qdec_acc__acc__getf(void)
{
uint32_t localVal = QDEC_ACC_REG;
ASSERT_ERR((localVal & ~0x000007FF) == 0);
return (localVal >> 0);
}
/**
* @brief QDEC_ACC_R register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 10:00 ACC_R 0x0
* </pre>
*/
#define QDEC_ACC_R_REG (*(volatile uint32_t *)(0x40016010))
#define QDEC_ACC_R_ADDR 0x40016010
#define QDEC_ACC_R_OFFSET 0x00000010
__INLINE uint32_t qdec_acc_r_get(void)
{
return QDEC_ACC_R_REG;
}
// field definitions
#define ACC_R_MASK 0x000007FF
#define ACC_R_LSB 0
#define ACC_R_WIDTH 0x0000000B
#define ACC_R_RST 0x0
__INLINE uint16_t qdec_acc_r__acc_r__getf(void)
{
uint32_t localVal = QDEC_ACC_R_REG;
ASSERT_ERR((localVal & ~0x000007FF) == 0);
return (localVal >> 0);
}
/**
* @brief QDEC_DB register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 03:00 DB 0x0
* </pre>
*/
#define QDEC_DB_REG (*(volatile uint32_t *)(0x40016014))
#define QDEC_DB_ADDR 0x40016014
#define QDEC_DB_OFFSET 0x00000014
__INLINE uint32_t qdec_db_get(void)
{
return QDEC_DB_REG;
}
// field definitions
#define DB_MASK 0x0000000F
#define DB_LSB 0
#define DB_WIDTH 0x00000004
#define DB_RST 0x0
__INLINE uint8_t qdec_db__db__getf(void)
{
uint32_t localVal = QDEC_DB_REG;
ASSERT_ERR((localVal & ~0x0000000F) == 0);
return (localVal >> 0);
}
/**
* @brief QDEC_DB_R register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 03:00 DB_R 0x0
* </pre>
*/
#define QDEC_DB_R_REG (*(volatile uint32_t *)(0x40016018))
#define QDEC_DB_R_ADDR 0x40016018
#define QDEC_DB_R_OFFSET 0x00000018
__INLINE uint32_t qdec_db_r_get(void)
{
return QDEC_DB_R_REG;
}
// field definitions
#define DB_R_MASK 0x0000000F
#define DB_R_LSB 0
#define DB_R_WIDTH 0x00000004
#define DB_R_RST 0x0
__INLINE uint8_t qdec_db_r__db_r__getf(void)
{
uint32_t localVal = QDEC_DB_R_REG;
ASSERT_ERR((localVal & ~0x0000000F) == 0);
return (localVal >> 0);
}
/**
* @brief QDEC_INT register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 03 DB_OF_RAW 0
* 02 ACC_OF_RAW 0
* 01 SAMPLE_END_RAW 0
* 00 SINGLE_SAMPLE_RAW 0
* </pre>
*/
#define QDEC_INT_REG (*(volatile uint32_t *)(0x4001601C))
#define QDEC_INT_ADDR 0x4001601C
#define QDEC_INT_OFFSET 0x0000001C
__INLINE uint32_t qdec_int_get(void)
{
return QDEC_INT_REG;
}
__INLINE void qdec_int_set(uint32_t value)
{
QDEC_INT_REG = value;
}
// field definitions
#define DB_OF_RAW_BIT 0x00000008
#define DB_OF_RAW_POS 3
#define ACC_OF_RAW_BIT 0x00000004
#define ACC_OF_RAW_POS 2
#define SAMPLE_END_RAW_BIT 0x00000002
#define SAMPLE_END_RAW_POS 1
#define SINGLE_SAMPLE_RAW_BIT 0x00000001
#define SINGLE_SAMPLE_RAW_POS 0
#define DB_OF_RAW_RST 0x0
#define ACC_OF_RAW_RST 0x0
#define SAMPLE_END_RAW_RST 0x0
#define SINGLE_SAMPLE_RAW_RST 0x0
__INLINE void qdec_int_pack(uint8_t db_of_raw, uint8_t acc_of_raw, uint8_t sample_end_raw, uint8_t single_sample_raw)
{
ASSERT_ERR(((db_of_raw << 3) & ~0x00000008) == 0);
ASSERT_ERR(((acc_of_raw << 2) & ~0x00000004) == 0);
ASSERT_ERR(((sample_end_raw << 1) & ~0x00000002) == 0);
ASSERT_ERR(((single_sample_raw << 0) & ~0x00000001) == 0);
QDEC_INT_REG = (db_of_raw << 3) | (acc_of_raw << 2) | (sample_end_raw << 1) | (single_sample_raw << 0);
}
__INLINE void qdec_int_unpack(uint8_t* db_of_raw, uint8_t* acc_of_raw, uint8_t* sample_end_raw, uint8_t* single_sample_raw)
{
uint32_t localVal = QDEC_INT_REG;
*db_of_raw = (localVal & 0x00000008) >> 3;
*acc_of_raw = (localVal & 0x00000004) >> 2;
*sample_end_raw = (localVal & 0x00000002) >> 1;
*single_sample_raw = (localVal & 0x00000001) >> 0;
}
__INLINE uint8_t qdec_int__db_of_raw__getf(void)
{
uint32_t localVal = QDEC_INT_REG;
return ((localVal & 0x00000008) >> 3);
}
__INLINE void qdec_int__db_of_raw__setf(uint8_t db_of_raw)
{
ASSERT_ERR(((db_of_raw << 3) & ~0x00000008) == 0);
QDEC_INT_REG = (QDEC_INT_REG & ~0x00000008) | (db_of_raw << 3);
}
__INLINE uint8_t qdec_int__acc_of_raw__getf(void)
{
uint32_t localVal = QDEC_INT_REG;
return ((localVal & 0x00000004) >> 2);
}
__INLINE void qdec_int__acc_of_raw__setf(uint8_t acc_of_raw)
{
ASSERT_ERR(((acc_of_raw << 2) & ~0x00000004) == 0);
QDEC_INT_REG = (QDEC_INT_REG & ~0x00000004) | (acc_of_raw << 2);
}
__INLINE uint8_t qdec_int__sample_end_raw__getf(void)
{
uint32_t localVal = QDEC_INT_REG;
return ((localVal & 0x00000002) >> 1);
}
__INLINE void qdec_int__sample_end_raw__setf(uint8_t sample_end_raw)
{
ASSERT_ERR(((sample_end_raw << 1) & ~0x00000002) == 0);
QDEC_INT_REG = (QDEC_INT_REG & ~0x00000002) | (sample_end_raw << 1);
}
__INLINE uint8_t qdec_int__single_sample_raw__getf(void)
{
uint32_t localVal = QDEC_INT_REG;
return ((localVal & 0x00000001) >> 0);
}
__INLINE void qdec_int__single_sample_raw__setf(uint8_t single_sample_raw)
{
ASSERT_ERR(((single_sample_raw << 0) & ~0x00000001) == 0);
QDEC_INT_REG = (QDEC_INT_REG & ~0x00000001) | (single_sample_raw << 0);
}
/**
* @brief QDEC_INT_MSK register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 03 DB_OF_MSK 0
* 02 ACC_OF_MSK 0
* 01 SAMPLE_END_MSK 0
* 00 SINGLE_SAMPLE_MSK 0
* </pre>
*/
#define QDEC_INT_MSK_REG (*(volatile uint32_t *)(0x40016020))
#define QDEC_INT_MSK_ADDR 0x40016020
#define QDEC_INT_MSK_OFFSET 0x00000020
__INLINE uint32_t qdec_int_msk_get(void)
{
return QDEC_INT_MSK_REG;
}
__INLINE void qdec_int_msk_set(uint32_t value)
{
QDEC_INT_MSK_REG = value;
}
// field definitions
#define DB_OF_MSK_BIT 0x00000008
#define DB_OF_MSK_POS 3
#define ACC_OF_MSK_BIT 0x00000004
#define ACC_OF_MSK_POS 2
#define SAMPLE_END_MSK_BIT 0x00000002
#define SAMPLE_END_MSK_POS 1
#define SINGLE_SAMPLE_MSK_BIT 0x00000001
#define SINGLE_SAMPLE_MSK_POS 0
#define DB_OF_MSK_RST 0x0
#define ACC_OF_MSK_RST 0x0
#define SAMPLE_END_MSK_RST 0x0
#define SINGLE_SAMPLE_MSK_RST 0x0
__INLINE void qdec_int_msk_pack(uint8_t db_of_msk, uint8_t acc_of_msk, uint8_t sample_end_msk, uint8_t single_sample_msk)
{
ASSERT_ERR(((db_of_msk << 3) & ~0x00000008) == 0);
ASSERT_ERR(((acc_of_msk << 2) & ~0x00000004) == 0);
ASSERT_ERR(((sample_end_msk << 1) & ~0x00000002) == 0);
ASSERT_ERR(((single_sample_msk << 0) & ~0x00000001) == 0);
QDEC_INT_MSK_REG = (db_of_msk << 3) | (acc_of_msk << 2) | (sample_end_msk << 1) | (single_sample_msk << 0);
}
__INLINE void qdec_int_msk_unpack(uint8_t* db_of_msk, uint8_t* acc_of_msk, uint8_t* sample_end_msk, uint8_t* single_sample_msk)
{
uint32_t localVal = QDEC_INT_MSK_REG;
*db_of_msk = (localVal & 0x00000008) >> 3;
*acc_of_msk = (localVal & 0x00000004) >> 2;
*sample_end_msk = (localVal & 0x00000002) >> 1;
*single_sample_msk = (localVal & 0x00000001) >> 0;
}
__INLINE uint8_t qdec_int_msk__db_of_msk__getf(void)
{
uint32_t localVal = QDEC_INT_MSK_REG;
return ((localVal & 0x00000008) >> 3);
}
__INLINE void qdec_int_msk__db_of_msk__setf(uint8_t db_of_msk)
{
ASSERT_ERR(((db_of_msk << 3) & ~0x00000008) == 0);
QDEC_INT_MSK_REG = (QDEC_INT_MSK_REG & ~0x00000008) | (db_of_msk << 3);
}
__INLINE uint8_t qdec_int_msk__acc_of_msk__getf(void)
{
uint32_t localVal = QDEC_INT_MSK_REG;
return ((localVal & 0x00000004) >> 2);
}
__INLINE void qdec_int_msk__acc_of_msk__setf(uint8_t acc_of_msk)
{
ASSERT_ERR(((acc_of_msk << 2) & ~0x00000004) == 0);
QDEC_INT_MSK_REG = (QDEC_INT_MSK_REG & ~0x00000004) | (acc_of_msk << 2);
}
__INLINE uint8_t qdec_int_msk__sample_end_msk__getf(void)
{
uint32_t localVal = QDEC_INT_MSK_REG;
return ((localVal & 0x00000002) >> 1);
}
__INLINE void qdec_int_msk__sample_end_msk__setf(uint8_t sample_end_msk)
{
ASSERT_ERR(((sample_end_msk << 1) & ~0x00000002) == 0);
QDEC_INT_MSK_REG = (QDEC_INT_MSK_REG & ~0x00000002) | (sample_end_msk << 1);
}
__INLINE uint8_t qdec_int_msk__single_sample_msk__getf(void)
{
uint32_t localVal = QDEC_INT_MSK_REG;
return ((localVal & 0x00000001) >> 0);
}
__INLINE void qdec_int_msk__single_sample_msk__setf(uint8_t single_sample_msk)
{
ASSERT_ERR(((single_sample_msk << 0) & ~0x00000001) == 0);
QDEC_INT_MSK_REG = (QDEC_INT_MSK_REG & ~0x00000001) | (single_sample_msk << 0);
}
/**
* @brief QDEC_STAT register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 00 QDEC_BUSY 0
* </pre>
*/
#define QDEC_STAT_REG (*(volatile uint32_t *)(0x40016024))
#define QDEC_STAT_ADDR 0x40016024
#define QDEC_STAT_OFFSET 0x00000024
__INLINE uint32_t qdec_stat_get(void)
{
return QDEC_STAT_REG;
}
// field definitions
#define QDEC_BUSY_BIT 0x00000001
#define QDEC_BUSY_POS 0
#define QDEC_BUSY_RST 0x0
__INLINE uint8_t qdec_stat__qdec_busy__getf(void)
{
uint32_t localVal = QDEC_STAT_REG;
ASSERT_ERR((localVal & ~0x00000001) == 0);
return (localVal >> 0);
}
#endif // _XC_REG_QDEC_H_
@@ -0,0 +1,483 @@
#ifndef _XC_REG_RF_H_
#define _XC_REG_RF_H_
#include <stdint.h>
#define XC_REG_RF_BASE_ADDR 0x53021000
#define XC_REG_RF_DECODING_MASK 0x000000FF
/**
* @brief RF_ANA26 register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 15 clk_bbpll_en 0
* 14 clk_bbpll_rstn 0
* 13 bbpll_en 0
* 12 bbpll_core64m_en 0
* 11 bbpll_rc16m_sel 0
* 10:09 bbpll_bufmsel 0x1
* 08:06 bbpll_res 0x2
* 05:00 bbpll_loopdiv 0x4
* </pre>
*/
#define RF_ANA26_REG (*(volatile uint32_t *)(0x53021068))
#define RF_ANA26_ADDR 0x53021068
#define RF_ANA26_OFFSET 0x00000068
__INLINE uint16_t rf_ana26_get(void)
{
return RF_ANA26_REG;
}
__INLINE void rf_ana26_set(uint16_t value)
{
RF_ANA26_REG = value;
}
// field definitions
#define CLK_BBPLL_EN_BIT 0x00008000
#define CLK_BBPLL_EN_POS 15
#define CLK_BBPLL_RSTN_BIT 0x00004000
#define CLK_BBPLL_RSTN_POS 14
#define BBPLL_EN_BIT 0x00002000
#define BBPLL_EN_POS 13
#define BBPLL_CORE_64M_EN_BIT 0x00001000
#define BBPLL_CORE_64M_EN_POS 12
#define BBPLL_RC_16M_SEL_BIT 0x00000800
#define BBPLL_RC_16M_SEL_POS 11
#define BBPLL_BUFMSEL_MASK 0x00000600
#define BBPLL_BUFMSEL_LSB 9
#define BBPLL_BUFMSEL_WIDTH 0x00000002
#define BBPLL_RES_MASK 0x000001C0
#define BBPLL_RES_LSB 6
#define BBPLL_RES_WIDTH 0x00000003
#define BBPLL_LOOPDIV_MASK 0x0000003F
#define BBPLL_LOOPDIV_LSB 0
#define BBPLL_LOOPDIV_WIDTH 0x00000006
#define CLK_BBPLL_EN_RST 0x0
#define CLK_BBPLL_RSTN_RST 0x0
#define BBPLL_EN_RST 0x0
#define BBPLL_CORE_64M_EN_RST 0x0
#define BBPLL_RC_16M_SEL_RST 0x0
#define BBPLL_BUFMSEL_RST 0x1
#define BBPLL_RES_RST 0x2
#define BBPLL_LOOPDIV_RST 0x4
__INLINE void rf_ana26_pack(uint8_t clk_bbpll_en, uint8_t clk_bbpll_rstn, uint8_t bbpll_en, uint8_t bbpll_core64m_en, uint8_t bbpll_rc16m_sel, uint8_t bbpll_bufmsel, uint8_t bbpll_res, uint8_t bbpll_loopdiv)
{
ASSERT_ERR(((clk_bbpll_en << 15) & ~0x00008000) == 0);
ASSERT_ERR(((clk_bbpll_rstn << 14) & ~0x00004000) == 0);
ASSERT_ERR(((bbpll_en << 13) & ~0x00002000) == 0);
ASSERT_ERR(((bbpll_core64m_en << 12) & ~0x00001000) == 0);
ASSERT_ERR(((bbpll_rc16m_sel << 11) & ~0x00000800) == 0);
ASSERT_ERR(((bbpll_bufmsel << 9) & ~0x00000600) == 0);
ASSERT_ERR(((bbpll_res << 6) & ~0x000001C0) == 0);
ASSERT_ERR(((bbpll_loopdiv << 0) & ~0x0000003F) == 0);
RF_ANA26_REG = (clk_bbpll_en << 15) | (clk_bbpll_rstn << 14) | (bbpll_en << 13) | (bbpll_core64m_en << 12) | (bbpll_rc16m_sel << 11) | (bbpll_bufmsel << 9) | (bbpll_res << 6) | (bbpll_loopdiv << 0);
}
__INLINE void rf_ana26_unpack(uint8_t* clk_bbpll_en, uint8_t* clk_bbpll_rstn, uint8_t* bbpll_en, uint8_t* bbpll_core64m_en, uint8_t* bbpll_rc16m_sel, uint8_t* bbpll_bufmsel, uint8_t* bbpll_res, uint8_t* bbpll_loopdiv)
{
uint32_t localVal = RF_ANA26_REG;
*clk_bbpll_en = (localVal & 0x00008000) >> 15;
*clk_bbpll_rstn = (localVal & 0x00004000) >> 14;
*bbpll_en = (localVal & 0x00002000) >> 13;
*bbpll_core64m_en = (localVal & 0x00001000) >> 12;
*bbpll_rc16m_sel = (localVal & 0x00000800) >> 11;
*bbpll_bufmsel = (localVal & 0x00000600) >> 9;
*bbpll_res = (localVal & 0x000001C0) >> 6;
*bbpll_loopdiv = (localVal & 0x0000003F) >> 0;
}
__INLINE uint8_t rf_ana26__clk_bbpll_en__getf(void)
{
uint32_t localVal = RF_ANA26_REG;
return ((localVal & 0x00008000) >> 15);
}
__INLINE void rf_ana26__clk_bbpll_en__setf(uint8_t clk_bbpll_en)
{
ASSERT_ERR(((clk_bbpll_en << 15) & ~0x00008000) == 0);
RF_ANA26_REG = (RF_ANA26_REG & ~0x00008000) | (clk_bbpll_en << 15);
}
__INLINE uint8_t rf_ana26__clk_bbpll_rstn__getf(void)
{
uint32_t localVal = RF_ANA26_REG;
return ((localVal & 0x00004000) >> 14);
}
__INLINE void rf_ana26__clk_bbpll_rstn__setf(uint8_t clk_bbpll_rstn)
{
ASSERT_ERR(((clk_bbpll_rstn << 14) & ~0x00004000) == 0);
RF_ANA26_REG = (RF_ANA26_REG & ~0x00004000) | (clk_bbpll_rstn << 14);
}
__INLINE uint8_t rf_ana26__bbpll_en__getf(void)
{
uint32_t localVal = RF_ANA26_REG;
return ((localVal & 0x00002000) >> 13);
}
__INLINE void rf_ana26__bbpll_en__setf(uint8_t bbpll_en)
{
ASSERT_ERR(((bbpll_en << 13) & ~0x00002000) == 0);
RF_ANA26_REG = (RF_ANA26_REG & ~0x00002000) | (bbpll_en << 13);
}
__INLINE uint8_t rf_ana26__bbpll_core_64m_en__getf(void)
{
uint32_t localVal = RF_ANA26_REG;
return ((localVal & 0x00001000) >> 12);
}
__INLINE void rf_ana26__bbpll_core_64m_en__setf(uint8_t bbpll_core64m_en)
{
ASSERT_ERR(((bbpll_core64m_en << 12) & ~0x00001000) == 0);
RF_ANA26_REG = (RF_ANA26_REG & ~0x00001000) | (bbpll_core64m_en << 12);
}
__INLINE uint8_t rf_ana26__bbpll_rc_16m_sel__getf(void)
{
uint32_t localVal = RF_ANA26_REG;
return ((localVal & 0x00000800) >> 11);
}
__INLINE void rf_ana26__bbpll_rc_16m_sel__setf(uint8_t bbpll_rc16m_sel)
{
ASSERT_ERR(((bbpll_rc16m_sel << 11) & ~0x00000800) == 0);
RF_ANA26_REG = (RF_ANA26_REG & ~0x00000800) | (bbpll_rc16m_sel << 11);
}
__INLINE uint8_t rf_ana26__bbpll_bufmsel__getf(void)
{
uint32_t localVal = RF_ANA26_REG;
return ((localVal & 0x00000600) >> 9);
}
__INLINE void rf_ana26__bbpll_bufmsel__setf(uint8_t bbpll_bufmsel)
{
ASSERT_ERR(((bbpll_bufmsel << 9) & ~0x00000600) == 0);
RF_ANA26_REG = (RF_ANA26_REG & ~0x00000600) | (bbpll_bufmsel << 9);
}
__INLINE uint8_t rf_ana26__bbpll_res__getf(void)
{
uint32_t localVal = RF_ANA26_REG;
return ((localVal & 0x000001C0) >> 6);
}
__INLINE void rf_ana26__bbpll_res__setf(uint8_t bbpll_res)
{
ASSERT_ERR(((bbpll_res << 6) & ~0x000001C0) == 0);
RF_ANA26_REG = (RF_ANA26_REG & ~0x000001C0) | (bbpll_res << 6);
}
__INLINE uint8_t rf_ana26__bbpll_loopdiv__getf(void)
{
uint32_t localVal = RF_ANA26_REG;
return ((localVal & 0x0000003F) >> 0);
}
__INLINE void rf_ana26__bbpll_loopdiv__setf(uint8_t bbpll_loopdiv)
{
ASSERT_ERR(((bbpll_loopdiv << 0) & ~0x0000003F) == 0);
RF_ANA26_REG = (RF_ANA26_REG & ~0x0000003F) | (bbpll_loopdiv << 0);
}
/**
* @brief RF_ANA27 register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 15:13 bbpll_dvddres 0x4
* 12:10 bbpll_icp 0x3
* 07 bbpll16m_sel 0
* 01 bbpll_core96m_en 0
* 00 spi_sx_afc_rstn 0
* </pre>
*/
#define RF_ANA27_REG (*(volatile uint32_t *)(0x5302106C))
#define RF_ANA27_ADDR 0x5302106C
#define RF_ANA27_OFFSET 0x0000006C
__INLINE uint16_t rf_ana27_get(void)
{
return RF_ANA27_REG;
}
__INLINE void rf_ana27_set(uint16_t value)
{
RF_ANA27_REG = value;
}
// field definitions
#define BBPLL_DVDDRES_MASK 0x0000E000
#define BBPLL_DVDDRES_LSB 13
#define BBPLL_DVDDRES_WIDTH 0x00000003
#define BBPLL_ICP_MASK 0x00001C00
#define BBPLL_ICP_LSB 10
#define BBPLL_ICP_WIDTH 0x00000003
#define BBPLL_16M_SEL_BIT 0x00000080
#define BBPLL_16M_SEL_POS 7
#define BBPLL_CORE_96M_EN_BIT 0x00000002
#define BBPLL_CORE_96M_EN_POS 1
#define SPI_SX_AFC_RSTN_BIT 0x00000001
#define SPI_SX_AFC_RSTN_POS 0
#define BBPLL_DVDDRES_RST 0x4
#define BBPLL_ICP_RST 0x3
#define BBPLL_16M_SEL_RST 0x0
#define BBPLL_CORE_96M_EN_RST 0x0
#define SPI_SX_AFC_RSTN_RST 0x0
__INLINE void rf_ana27_pack(uint8_t bbpll_dvddres, uint8_t bbpll_icp, uint8_t bbpll16m_sel, uint8_t bbpll_core96m_en, uint8_t spi_sx_afc_rstn)
{
ASSERT_ERR(((bbpll_dvddres << 13) & ~0x0000E000) == 0);
ASSERT_ERR(((bbpll_icp << 10) & ~0x00001C00) == 0);
ASSERT_ERR(((bbpll16m_sel << 7) & ~0x00000080) == 0);
ASSERT_ERR(((bbpll_core96m_en << 1) & ~0x00000002) == 0);
ASSERT_ERR(((spi_sx_afc_rstn << 0) & ~0x00000001) == 0);
RF_ANA27_REG = (bbpll_dvddres << 13) | (bbpll_icp << 10) | (bbpll16m_sel << 7) | (bbpll_core96m_en << 1) | (spi_sx_afc_rstn << 0);
}
__INLINE void rf_ana27_unpack(uint8_t* bbpll_dvddres, uint8_t* bbpll_icp, uint8_t* bbpll16m_sel, uint8_t* bbpll_core96m_en, uint8_t* spi_sx_afc_rstn)
{
uint32_t localVal = RF_ANA27_REG;
*bbpll_dvddres = (localVal & 0x0000E000) >> 13;
*bbpll_icp = (localVal & 0x00001C00) >> 10;
*bbpll16m_sel = (localVal & 0x00000080) >> 7;
*bbpll_core96m_en = (localVal & 0x00000002) >> 1;
*spi_sx_afc_rstn = (localVal & 0x00000001) >> 0;
}
__INLINE uint8_t rf_ana27__bbpll_dvddres__getf(void)
{
uint32_t localVal = RF_ANA27_REG;
return ((localVal & 0x0000E000) >> 13);
}
__INLINE void rf_ana27__bbpll_dvddres__setf(uint8_t bbpll_dvddres)
{
ASSERT_ERR(((bbpll_dvddres << 13) & ~0x0000E000) == 0);
RF_ANA27_REG = (RF_ANA27_REG & ~0x0000E000) | (bbpll_dvddres << 13);
}
__INLINE uint8_t rf_ana27__bbpll_icp__getf(void)
{
uint32_t localVal = RF_ANA27_REG;
return ((localVal & 0x00001C00) >> 10);
}
__INLINE void rf_ana27__bbpll_icp__setf(uint8_t bbpll_icp)
{
ASSERT_ERR(((bbpll_icp << 10) & ~0x00001C00) == 0);
RF_ANA27_REG = (RF_ANA27_REG & ~0x00001C00) | (bbpll_icp << 10);
}
__INLINE uint8_t rf_ana27__bbpll_16m_sel__getf(void)
{
uint32_t localVal = RF_ANA27_REG;
return ((localVal & 0x00000080) >> 7);
}
__INLINE void rf_ana27__bbpll_16m_sel__setf(uint8_t bbpll16m_sel)
{
ASSERT_ERR(((bbpll16m_sel << 7) & ~0x00000080) == 0);
RF_ANA27_REG = (RF_ANA27_REG & ~0x00000080) | (bbpll16m_sel << 7);
}
__INLINE uint8_t rf_ana27__bbpll_core_96m_en__getf(void)
{
uint32_t localVal = RF_ANA27_REG;
return ((localVal & 0x00000002) >> 1);
}
__INLINE void rf_ana27__bbpll_core_96m_en__setf(uint8_t bbpll_core96m_en)
{
ASSERT_ERR(((bbpll_core96m_en << 1) & ~0x00000002) == 0);
RF_ANA27_REG = (RF_ANA27_REG & ~0x00000002) | (bbpll_core96m_en << 1);
}
__INLINE uint8_t rf_ana27__spi_sx_afc_rstn__getf(void)
{
uint32_t localVal = RF_ANA27_REG;
return ((localVal & 0x00000001) >> 0);
}
__INLINE void rf_ana27__spi_sx_afc_rstn__setf(uint8_t spi_sx_afc_rstn)
{
ASSERT_ERR(((spi_sx_afc_rstn << 0) & ~0x00000001) == 0);
RF_ANA27_REG = (RF_ANA27_REG & ~0x00000001) | (spi_sx_afc_rstn << 0);
}
/**
* @brief BT_RF_PM_REG register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 15 bt_en_pm_fc_soft 0
* 14 bt_en_pm 0
* 13:06 ch_cnt_delay 0x80
* 05 da_ism_rstn_soften 0
* 04 da_ism_dac_rstn_soft 0
* 03 da_ism_sx_dsm_resetn_soft 0
* 02 da_ism_sx_afc_resetn_soft 0
* </pre>
*/
#define BT_RF_PM_REG_REG (*(volatile uint32_t *)(0x530210B0))
#define BT_RF_PM_REG_ADDR 0x530210B0
#define BT_RF_PM_REG_OFFSET 0x000000B0
__INLINE uint16_t bt_rf_pm_reg_get(void)
{
return BT_RF_PM_REG_REG;
}
__INLINE void bt_rf_pm_reg_set(uint16_t value)
{
BT_RF_PM_REG_REG = value;
}
// field definitions
#define BT_EN_PM_FC_SOFT_BIT 0x00008000
#define BT_EN_PM_FC_SOFT_POS 15
#define BT_EN_PM_BIT 0x00004000
#define BT_EN_PM_POS 14
#define CH_CNT_DELAY_MASK 0x00003FC0
#define CH_CNT_DELAY_LSB 6
#define CH_CNT_DELAY_WIDTH 0x00000008
#define DA_ISM_RSTN_SOFTEN_BIT 0x00000020
#define DA_ISM_RSTN_SOFTEN_POS 5
#define DA_ISM_DAC_RSTN_SOFT_BIT 0x00000010
#define DA_ISM_DAC_RSTN_SOFT_POS 4
#define DA_ISM_SX_DSM_RESETN_SOFT_BIT 0x00000008
#define DA_ISM_SX_DSM_RESETN_SOFT_POS 3
#define DA_ISM_SX_AFC_RESETN_SOFT_BIT 0x00000004
#define DA_ISM_SX_AFC_RESETN_SOFT_POS 2
#define BT_EN_PM_FC_SOFT_RST 0x0
#define BT_EN_PM_RST 0x0
#define CH_CNT_DELAY_RST 0x80
#define DA_ISM_RSTN_SOFTEN_RST 0x0
#define DA_ISM_DAC_RSTN_SOFT_RST 0x0
#define DA_ISM_SX_DSM_RESETN_SOFT_RST 0x0
#define DA_ISM_SX_AFC_RESETN_SOFT_RST 0x0
__INLINE void bt_rf_pm_reg_pack(uint8_t bt_en_pm_fc_soft, uint8_t bt_en_pm, uint8_t ch_cnt_delay, uint8_t da_ism_rstn_soften, uint8_t da_ism_dac_rstn_soft, uint8_t da_ism_sx_dsm_resetn_soft, uint8_t da_ism_sx_afc_resetn_soft)
{
ASSERT_ERR(((bt_en_pm_fc_soft << 15) & ~0x00008000) == 0);
ASSERT_ERR(((bt_en_pm << 14) & ~0x00004000) == 0);
ASSERT_ERR(((ch_cnt_delay << 6) & ~0x00003FC0) == 0);
ASSERT_ERR(((da_ism_rstn_soften << 5) & ~0x00000020) == 0);
ASSERT_ERR(((da_ism_dac_rstn_soft << 4) & ~0x00000010) == 0);
ASSERT_ERR(((da_ism_sx_dsm_resetn_soft << 3) & ~0x00000008) == 0);
ASSERT_ERR(((da_ism_sx_afc_resetn_soft << 2) & ~0x00000004) == 0);
BT_RF_PM_REG_REG = (bt_en_pm_fc_soft << 15) | (bt_en_pm << 14) | (ch_cnt_delay << 6) | (da_ism_rstn_soften << 5) | (da_ism_dac_rstn_soft << 4) | (da_ism_sx_dsm_resetn_soft << 3) | (da_ism_sx_afc_resetn_soft << 2);
}
__INLINE void bt_rf_pm_reg_unpack(uint8_t* bt_en_pm_fc_soft, uint8_t* bt_en_pm, uint8_t* ch_cnt_delay, uint8_t* da_ism_rstn_soften, uint8_t* da_ism_dac_rstn_soft, uint8_t* da_ism_sx_dsm_resetn_soft, uint8_t* da_ism_sx_afc_resetn_soft)
{
uint32_t localVal = BT_RF_PM_REG_REG;
*bt_en_pm_fc_soft = (localVal & 0x00008000) >> 15;
*bt_en_pm = (localVal & 0x00004000) >> 14;
*ch_cnt_delay = (localVal & 0x00003FC0) >> 6;
*da_ism_rstn_soften = (localVal & 0x00000020) >> 5;
*da_ism_dac_rstn_soft = (localVal & 0x00000010) >> 4;
*da_ism_sx_dsm_resetn_soft = (localVal & 0x00000008) >> 3;
*da_ism_sx_afc_resetn_soft = (localVal & 0x00000004) >> 2;
}
__INLINE uint8_t bt_rf_pm_reg__bt_en_pm_fc_soft__getf(void)
{
uint32_t localVal = BT_RF_PM_REG_REG;
return ((localVal & 0x00008000) >> 15);
}
__INLINE void bt_rf_pm_reg__bt_en_pm_fc_soft__setf(uint8_t bt_en_pm_fc_soft)
{
ASSERT_ERR(((bt_en_pm_fc_soft << 15) & ~0x00008000) == 0);
BT_RF_PM_REG_REG = (BT_RF_PM_REG_REG & ~0x00008000) | (bt_en_pm_fc_soft << 15);
}
__INLINE uint8_t bt_rf_pm_reg__bt_en_pm__getf(void)
{
uint32_t localVal = BT_RF_PM_REG_REG;
return ((localVal & 0x00004000) >> 14);
}
__INLINE void bt_rf_pm_reg__bt_en_pm__setf(uint8_t bt_en_pm)
{
ASSERT_ERR(((bt_en_pm << 14) & ~0x00004000) == 0);
BT_RF_PM_REG_REG = (BT_RF_PM_REG_REG & ~0x00004000) | (bt_en_pm << 14);
}
__INLINE uint8_t bt_rf_pm_reg__ch_cnt_delay__getf(void)
{
uint32_t localVal = BT_RF_PM_REG_REG;
return ((localVal & 0x00003FC0) >> 6);
}
__INLINE void bt_rf_pm_reg__ch_cnt_delay__setf(uint8_t ch_cnt_delay)
{
ASSERT_ERR(((ch_cnt_delay << 6) & ~0x00003FC0) == 0);
BT_RF_PM_REG_REG = (BT_RF_PM_REG_REG & ~0x00003FC0) | (ch_cnt_delay << 6);
}
__INLINE uint8_t bt_rf_pm_reg__da_ism_rstn_soften__getf(void)
{
uint32_t localVal = BT_RF_PM_REG_REG;
return ((localVal & 0x00000020) >> 5);
}
__INLINE void bt_rf_pm_reg__da_ism_rstn_soften__setf(uint8_t da_ism_rstn_soften)
{
ASSERT_ERR(((da_ism_rstn_soften << 5) & ~0x00000020) == 0);
BT_RF_PM_REG_REG = (BT_RF_PM_REG_REG & ~0x00000020) | (da_ism_rstn_soften << 5);
}
__INLINE uint8_t bt_rf_pm_reg__da_ism_dac_rstn_soft__getf(void)
{
uint32_t localVal = BT_RF_PM_REG_REG;
return ((localVal & 0x00000010) >> 4);
}
__INLINE void bt_rf_pm_reg__da_ism_dac_rstn_soft__setf(uint8_t da_ism_dac_rstn_soft)
{
ASSERT_ERR(((da_ism_dac_rstn_soft << 4) & ~0x00000010) == 0);
BT_RF_PM_REG_REG = (BT_RF_PM_REG_REG & ~0x00000010) | (da_ism_dac_rstn_soft << 4);
}
__INLINE uint8_t bt_rf_pm_reg__da_ism_sx_dsm_resetn_soft__getf(void)
{
uint32_t localVal = BT_RF_PM_REG_REG;
return ((localVal & 0x00000008) >> 3);
}
__INLINE void bt_rf_pm_reg__da_ism_sx_dsm_resetn_soft__setf(uint8_t da_ism_sx_dsm_resetn_soft)
{
ASSERT_ERR(((da_ism_sx_dsm_resetn_soft << 3) & ~0x00000008) == 0);
BT_RF_PM_REG_REG = (BT_RF_PM_REG_REG & ~0x00000008) | (da_ism_sx_dsm_resetn_soft << 3);
}
__INLINE uint8_t bt_rf_pm_reg__da_ism_sx_afc_resetn_soft__getf(void)
{
uint32_t localVal = BT_RF_PM_REG_REG;
return ((localVal & 0x00000004) >> 2);
}
__INLINE void bt_rf_pm_reg__da_ism_sx_afc_resetn_soft__setf(uint8_t da_ism_sx_afc_resetn_soft)
{
ASSERT_ERR(((da_ism_sx_afc_resetn_soft << 2) & ~0x00000004) == 0);
BT_RF_PM_REG_REG = (BT_RF_PM_REG_REG & ~0x00000004) | (da_ism_sx_afc_resetn_soft << 2);
}
#endif // _XC_REG_RF_H_
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,207 @@
#ifndef _XC_REG_TIMER_H_
#define _XC_REG_TIMER_H_
#include <stdint.h>
#define XC_REG_TIMER_BASE_ADDR 0x40003000
#define XC_REG_TIMER_DECODING_MASK 0x0000001F
/**
* @brief TIMER_TLC register definition
*/
#define TIMER_TLC_REG(i) (*(volatile uint32_t *)(0x40003000 + timer_offset[i]))
#define TIMER_TLC_ADDR(i) (0x40003000 + timer_offset[i])
#define TIMER_TLC_OFFSET 0x00000000
__INLINE uint32_t timer_tlc_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 3);
return TIMER_TLC_REG(reg_idx);
}
__INLINE void timer_tlc_set(uint32_t reg_idx, uint32_t value)
{
ASSERT_ERR(reg_idx <= 3);
TIMER_TLC_REG(reg_idx) = value;
}
/**
* @brief TIMER_TCV register definition
*/
#define TIMER_TCV_REG(i) (*(volatile uint32_t *)(0x40003004 + timer_offset[i]))
#define TIMER_TCV_ADDR(i) (0x40003004 + timer_offset[i])
#define TIMER_TCV_OFFSET 0x00000004
__INLINE uint32_t timer_tcv_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 3);
return TIMER_TCV_REG(reg_idx);
}
/**
* @brief TIMER_TCR register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 02 TIM 0
* 01 TMS 0
* 00 TES 0
* </pre>
*/
#define TIMER_TCR_REG(i) (*(volatile uint32_t *)(0x40003008 + timer_offset[i]))
#define TIMER_TCR_ADDR(i) (0x40003008 + timer_offset[i])
#define TIMER_TCR_OFFSET 0x00000008
__INLINE uint32_t timer_tcr_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 3);
return TIMER_TCR_REG(reg_idx);
}
__INLINE void timer_tcr_set(uint32_t reg_idx, uint32_t value)
{
ASSERT_ERR(reg_idx <= 3);
TIMER_TCR_REG(reg_idx) = value;
}
// field definitions
#define TIM_BIT 0x00000004
#define TIM_POS 2
#define TMS_BIT 0x00000002
#define TMS_POS 1
#define TES_BIT 0x00000001
#define TES_POS 0
#define TIM_RST 0x0
#define TMS_RST 0x0
#define TES_RST 0x0
__INLINE void timer_tcr_pack(uint32_t reg_idx, uint8_t tim, uint8_t tms, uint8_t tes)
{
ASSERT_ERR(reg_idx <= 3);
ASSERT_ERR(((tim << 2) & ~0x00000004) == 0);
ASSERT_ERR(((tms << 1) & ~0x00000002) == 0);
ASSERT_ERR(((tes << 0) & ~0x00000001) == 0);
TIMER_TCR_REG(reg_idx) = (tim << 2) | (tms << 1) | (tes << 0);
}
__INLINE void timer_tcr_unpack(uint32_t reg_idx, uint8_t* tim, uint8_t* tms, uint8_t* tes)
{
ASSERT_ERR(reg_idx <= 3);
uint32_t localVal = TIMER_TCR_REG(reg_idx);
*tim = (localVal & 0x00000004) >> 2;
*tms = (localVal & 0x00000002) >> 1;
*tes = (localVal & 0x00000001) >> 0;
}
__INLINE uint8_t timer_tcr__tim__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 3);
uint32_t localVal = TIMER_TCR_REG(reg_idx);
return ((localVal & 0x00000004) >> 2);
}
__INLINE void timer_tcr__tim__setf(uint32_t reg_idx, uint8_t tim)
{
ASSERT_ERR(reg_idx <= 3);
ASSERT_ERR(((tim << 2) & ~0x00000004) == 0);
TIMER_TCR_REG(reg_idx) = (TIMER_TCR_REG(reg_idx) & ~0x00000004) | (tim << 2);
}
__INLINE uint8_t timer_tcr__tms__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 3);
uint32_t localVal = TIMER_TCR_REG(reg_idx);
return ((localVal & 0x00000002) >> 1);
}
__INLINE void timer_tcr__tms__setf(uint32_t reg_idx, uint8_t tms)
{
ASSERT_ERR(reg_idx <= 3);
ASSERT_ERR(((tms << 1) & ~0x00000002) == 0);
TIMER_TCR_REG(reg_idx) = (TIMER_TCR_REG(reg_idx) & ~0x00000002) | (tms << 1);
}
__INLINE uint8_t timer_tcr__tes__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 3);
uint32_t localVal = TIMER_TCR_REG(reg_idx);
return ((localVal & 0x00000001) >> 0);
}
__INLINE void timer_tcr__tes__setf(uint32_t reg_idx, uint8_t tes)
{
ASSERT_ERR(reg_idx <= 3);
ASSERT_ERR(((tes << 0) & ~0x00000001) == 0);
TIMER_TCR_REG(reg_idx) = (TIMER_TCR_REG(reg_idx) & ~0x00000001) | (tes << 0);
}
/**
* @brief TIMER_TIC register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 00 INTR 0
* </pre>
*/
#define TIMER_TIC_REG(i) (*(volatile uint32_t *)(0x4000300C + timer_offset[i]))
#define TIMER_TIC_ADDR(i) (0x4000300C + timer_offset[i])
#define TIMER_TIC_OFFSET 0x0000000C
__INLINE uint32_t timer_tic_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 3);
return TIMER_TIC_REG(reg_idx);
}
// field definitions
#define INTR_BIT 0x00000001
#define INTR_POS 0
#define INTR_RST 0x0
__INLINE uint8_t timer_tic__intr__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 3);
uint32_t localVal = TIMER_TIC_REG(reg_idx);
ASSERT_ERR((localVal & ~0x00000001) == 0);
return (localVal >> 0);
}
/**
* @brief TIMER_TIS register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 00 STAT 0
* </pre>
*/
#define TIMER_TIS_REG(i) (*(volatile uint32_t *)(0x40003010 + timer_offset[i]))
#define TIMER_TIS_ADDR(i) (0x40003010 + timer_offset[i])
#define TIMER_TIS_OFFSET 0x00000010
__INLINE uint32_t timer_tis_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 3);
return TIMER_TIS_REG(reg_idx);
}
// field definitions
#define STAT_BIT 0x00000001
#define STAT_POS 0
#define STAT_RST 0x0
__INLINE uint8_t timer_tis__stat__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 3);
uint32_t localVal = TIMER_TIS_REG(reg_idx);
ASSERT_ERR((localVal & ~0x00000001) == 0);
return (localVal >> 0);
}
#endif // _XC_REG_TIMER_H_
@@ -0,0 +1,883 @@
#ifndef _XC_REG_UART_H_
#define _XC_REG_UART_H_
#include <stdint.h>
#include "xc_reg_offset.h"
#define XC_REG_UART_BASE_ADDR 0x40010000
#define XC_REG_UART_DECODING_MASK 0x000000FF
/**
* @brief UART_RBR register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 07:00 RBR 0x0
* </pre>
*/
#define UART_RBR_REG(i) (* ((volatile uint32_t *)(0x40010000 + uart_offset[i])) )
#define UART_RBR_ADDR(i) (0x40010000 + uart_offset[i])
#define UART_RBR_OFFSET 0x00000000
__INLINE uint32_t uart_rbr_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
return UART_RBR_REG(reg_idx);
}
// field definitions
#define RBR_MASK 0x000000FF
#define RBR_LSB 0
#define RBR_WIDTH 0x00000008
#define RBR_RST 0x0
__INLINE uint8_t uart_rbr__rbr__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_RBR_REG(reg_idx);
ASSERT_ERR((localVal & ~0x000000FF) == 0);
return (localVal >> 0);
}
/**
* @brief UART_THR register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 07:00 THR 0x0
* </pre>
*/
#define UART_THR_REG(i) (* ((volatile uint32_t *)(0x40010000 + uart_offset[i])) )
#define UART_THR_ADDR(i) (0x40010000 + uart_offset[i])
#define UART_THR_OFFSET 0x00000000
__INLINE void uart_thr_set(uint32_t reg_idx, uint32_t value)
{
ASSERT_ERR(reg_idx <= 2);
UART_THR_REG(reg_idx) = value;
}
// field definitions
#define THR_MASK 0x000000FF
#define THR_LSB 0
#define THR_WIDTH 0x00000008
#define THR_RST 0x0
__INLINE void uart_thr__thr__setf(uint32_t reg_idx, uint8_t thr)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((thr << 0) & ~0x000000FF) == 0);
UART_THR_REG(reg_idx) = thr << 0;
}
/**
* @brief UART_DLL register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 07:00 DLL 0x0
* </pre>
*/
#define UART_DLL_REG(i) (* ((volatile uint32_t *)(0x40010000 + uart_offset[i])) )
#define UART_DLL_ADDR(i) (0x40010000 + uart_offset[i])
#define UART_DLL_OFFSET 0x00000000
__INLINE uint32_t uart_dll_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
return UART_DLL_REG(reg_idx);
}
__INLINE void uart_dll_set(uint32_t reg_idx, uint32_t value)
{
ASSERT_ERR(reg_idx <= 2);
UART_DLL_REG(reg_idx) = value;
}
// field definitions
#define DLL_MASK 0x000000FF
#define DLL_LSB 0
#define DLL_WIDTH 0x00000008
#define DLL_RST 0x0
__INLINE uint8_t uart_dll__dll__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_DLL_REG(reg_idx);
ASSERT_ERR((localVal & ~0x000000FF) == 0);
return (localVal >> 0);
}
__INLINE void uart_dll__dll__setf(uint32_t reg_idx, uint8_t dll)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((dll << 0) & ~0x000000FF) == 0);
UART_DLL_REG(reg_idx) = dll << 0;
}
/**
* @brief UART_IER register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 07 PTIME 0
* 03 EMSI 0
* 02 ETSI 0
* 01 ETHEI 0
* 00 ERDAI 0
* </pre>
*/
#define UART_IER_REG(i) (* ((volatile uint32_t *)(0x40010004 + uart_offset[i])) )
#define UART_IER_ADDR(i) (0x40010004 + uart_offset[i])
#define UART_IER_OFFSET 0x00000004
__INLINE uint32_t uart_ier_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
return UART_IER_REG(reg_idx);
}
__INLINE void uart_ier_set(uint32_t reg_idx, uint32_t value)
{
ASSERT_ERR(reg_idx <= 2);
UART_IER_REG(reg_idx) = value;
}
// field definitions
#define PTIME_BIT 0x00000080
#define PTIME_POS 7
#define EMSI_BIT 0x00000008
#define EMSI_POS 3
#define ETSI_BIT 0x00000004
#define ETSI_POS 2
#define ETHEI_BIT 0x00000002
#define ETHEI_POS 1
#define ERDAI_BIT 0x00000001
#define ERDAI_POS 0
#define PTIME_RST 0x0
#define EMSI_RST 0x0
#define ETSI_RST 0x0
#define ETHEI_RST 0x0
#define ERDAI_RST 0x0
__INLINE void uart_ier_pack(uint32_t reg_idx, uint8_t ptime, uint8_t emsi, uint8_t etsi, uint8_t ethei, uint8_t erdai)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((ptime << 7) & ~0x00000080) == 0);
ASSERT_ERR(((emsi << 3) & ~0x00000008) == 0);
ASSERT_ERR(((etsi << 2) & ~0x00000004) == 0);
ASSERT_ERR(((ethei << 1) & ~0x00000002) == 0);
ASSERT_ERR(((erdai << 0) & ~0x00000001) == 0);
UART_IER_REG(reg_idx) = (ptime << 7) | (emsi << 3) | (etsi << 2) | (ethei << 1) | (erdai << 0);
}
__INLINE void uart_ier_unpack(uint32_t reg_idx, uint8_t* ptime, uint8_t* emsi, uint8_t* etsi, uint8_t* ethei, uint8_t* erdai)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_IER_REG(reg_idx);
*ptime = (localVal & 0x00000080) >> 7;
*emsi = (localVal & 0x00000008) >> 3;
*etsi = (localVal & 0x00000004) >> 2;
*ethei = (localVal & 0x00000002) >> 1;
*erdai = (localVal & 0x00000001) >> 0;
}
__INLINE uint8_t uart_ier__ptime__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_IER_REG(reg_idx);
return ((localVal & 0x00000080) >> 7);
}
__INLINE void uart_ier__ptime__setf(uint32_t reg_idx, uint8_t ptime)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((ptime << 7) & ~0x00000080) == 0);
UART_IER_REG(reg_idx) = (UART_IER_REG(reg_idx) & ~0x00000080) | (ptime << 7);
}
__INLINE uint8_t uart_ier__emsi__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_IER_REG(reg_idx);
return ((localVal & 0x00000008) >> 3);
}
__INLINE void uart_ier__emsi__setf(uint32_t reg_idx, uint8_t emsi)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((emsi << 3) & ~0x00000008) == 0);
UART_IER_REG(reg_idx) = (UART_IER_REG(reg_idx) & ~0x00000008) | (emsi << 3);
}
__INLINE uint8_t uart_ier__etsi__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_IER_REG(reg_idx);
return ((localVal & 0x00000004) >> 2);
}
__INLINE void uart_ier__etsi__setf(uint32_t reg_idx, uint8_t etsi)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((etsi << 2) & ~0x00000004) == 0);
UART_IER_REG(reg_idx) = (UART_IER_REG(reg_idx) & ~0x00000004) | (etsi << 2);
}
__INLINE uint8_t uart_ier__ethei__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_IER_REG(reg_idx);
return ((localVal & 0x00000002) >> 1);
}
__INLINE void uart_ier__ethei__setf(uint32_t reg_idx, uint8_t ethei)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((ethei << 1) & ~0x00000002) == 0);
UART_IER_REG(reg_idx) = (UART_IER_REG(reg_idx) & ~0x00000002) | (ethei << 1);
}
__INLINE uint8_t uart_ier__erdai__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_IER_REG(reg_idx);
return ((localVal & 0x00000001) >> 0);
}
__INLINE void uart_ier__erdai__setf(uint32_t reg_idx, uint8_t erdai)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((erdai << 0) & ~0x00000001) == 0);
UART_IER_REG(reg_idx) = (UART_IER_REG(reg_idx) & ~0x00000001) | (erdai << 0);
}
/**
* @brief UART_DLH register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 07:00 DLH 0x0
* </pre>
*/
#define UART_DLH_REG(i) (* ((volatile uint32_t *)(0x40010004 + uart_offset[i])) )
#define UART_DLH_ADDR(i) (0x40010004 + uart_offset[i])
#define UART_DLH_OFFSET 0x00000004
__INLINE uint32_t uart_dlh_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
return UART_DLH_REG(reg_idx);
}
__INLINE void uart_dlh_set(uint32_t reg_idx, uint32_t value)
{
ASSERT_ERR(reg_idx <= 2);
UART_DLH_REG(reg_idx) = value;
}
// field definitions
#define DLH_MASK 0x000000FF
#define DLH_LSB 0
#define DLH_WIDTH 0x00000008
#define DLH_RST 0x0
__INLINE uint8_t uart_dlh__dlh__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_DLH_REG(reg_idx);
ASSERT_ERR((localVal & ~0x000000FF) == 0);
return (localVal >> 0);
}
__INLINE void uart_dlh__dlh__setf(uint32_t reg_idx, uint8_t dlh)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((dlh << 0) & ~0x000000FF) == 0);
UART_DLH_REG(reg_idx) = dlh << 0;
}
/**
* @brief UART_IIR register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 07:06 FS 0x0
* 03:00 IID 0x0
* </pre>
*/
#define UART_IIR_REG(i) (* ((volatile uint32_t *)(0x40010008 + uart_offset[i])) )
#define UART_IIR_ADDR(i) (0x40010008 + uart_offset[i])
#define UART_IIR_OFFSET 0x00000008
__INLINE uint32_t uart_iir_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
return UART_IIR_REG(reg_idx);
}
// field definitions
#define FS_MASK 0x000000C0
#define FS_LSB 6
#define FS_WIDTH 0x00000002
#define IID_MASK 0x0000000F
#define IID_LSB 0
#define IID_WIDTH 0x00000004
#define FS_RST 0x0
#define IID_RST 0x0
__INLINE void uart_iir_unpack(uint32_t reg_idx, uint8_t* fs, uint8_t* iid)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_IIR_REG(reg_idx);
*fs = (localVal & 0x000000C0) >> 6;
*iid = (localVal & 0x0000000F) >> 0;
}
__INLINE uint8_t uart_iir__fs__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_IIR_REG(reg_idx);
return ((localVal & 0x000000C0) >> 6);
}
__INLINE uint8_t uart_iir__iid__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_IIR_REG(reg_idx);
return ((localVal & 0x0000000F) >> 0);
}
/**
* @brief UART_FCR register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 07:06 RCVR_Trigger 0x0
* 05:04 TX_Empty_Trigger 0x0
* 02 XMIT_FIFO_Reset 0
* 01 RCVR_FIFO_Reset 0
* 00 FIFO_ENABLE 0
* </pre>
*/
#define UART_FCR_REG(i) (* ((volatile uint32_t *)(0x40010008 + uart_offset[i])) )
#define UART_FCR_ADDR(i) (0x40010008 + uart_offset[i])
#define UART_FCR_OFFSET 0x00000008
__INLINE void uart_fcr_set(uint32_t reg_idx, uint32_t value)
{
ASSERT_ERR(reg_idx <= 2);
UART_FCR_REG(reg_idx) = value;
}
// field definitions
#define RCVR__TRIGGER_MASK 0x000000C0
#define RCVR__TRIGGER_LSB 6
#define RCVR__TRIGGER_WIDTH 0x00000002
#define TX__EMPTY__TRIGGER_MASK 0x00000030
#define TX__EMPTY__TRIGGER_LSB 4
#define TX__EMPTY__TRIGGER_WIDTH 0x00000002
#define XMIT_FIFO__RESET_BIT 0x00000004
#define XMIT_FIFO__RESET_POS 2
#define RCVR_FIFO__RESET_BIT 0x00000002
#define RCVR_FIFO__RESET_POS 1
#define FIFO_ENABLE_BIT 0x00000001
#define FIFO_ENABLE_POS 0
#define RCVR__TRIGGER_RST 0x0
#define TX__EMPTY__TRIGGER_RST 0x0
#define XMIT_FIFO__RESET_RST 0x0
#define RCVR_FIFO__RESET_RST 0x0
#define FIFO_ENABLE_RST 0x0
__INLINE void uart_fcr_pack(uint32_t reg_idx, uint8_t rcvr_trigger, uint8_t tx_empty_trigger, uint8_t xmit_fifo_reset, uint8_t rcvr_fifo_reset, uint8_t fifo_enable)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((rcvr_trigger << 6) & ~0x000000C0) == 0);
ASSERT_ERR(((tx_empty_trigger << 4) & ~0x00000030) == 0);
ASSERT_ERR(((xmit_fifo_reset << 2) & ~0x00000004) == 0);
ASSERT_ERR(((rcvr_fifo_reset << 1) & ~0x00000002) == 0);
ASSERT_ERR(((fifo_enable << 0) & ~0x00000001) == 0);
UART_FCR_REG(reg_idx) = (rcvr_trigger << 6) | (tx_empty_trigger << 4) | (xmit_fifo_reset << 2) | (rcvr_fifo_reset << 1) | (fifo_enable << 0);
}
__INLINE void uart_fcr__rcvr__trigger__setf(uint32_t reg_idx, uint8_t rcvr_trigger)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((rcvr_trigger << 6) & ~0x000000C0) == 0);
UART_FCR_REG(reg_idx) = (UART_FCR_REG(reg_idx) & ~0x000000C0) | (rcvr_trigger << 6);
}
__INLINE void uart_fcr__tx__empty__trigger__setf(uint32_t reg_idx, uint8_t tx_empty_trigger)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((tx_empty_trigger << 4) & ~0x00000030) == 0);
UART_FCR_REG(reg_idx) = (UART_FCR_REG(reg_idx) & ~0x00000030) | (tx_empty_trigger << 4);
}
__INLINE void uart_fcr__xmit_fifo__reset__setf(uint32_t reg_idx, uint8_t xmit_fifo_reset)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((xmit_fifo_reset << 2) & ~0x00000004) == 0);
UART_FCR_REG(reg_idx) = (UART_FCR_REG(reg_idx) & ~0x00000004) | (xmit_fifo_reset << 2);
}
__INLINE void uart_fcr__rcvr_fifo__reset__setf(uint32_t reg_idx, uint8_t rcvr_fifo_reset)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((rcvr_fifo_reset << 1) & ~0x00000002) == 0);
UART_FCR_REG(reg_idx) = (UART_FCR_REG(reg_idx) & ~0x00000002) | (rcvr_fifo_reset << 1);
}
__INLINE void uart_fcr__fifo_enable__setf(uint32_t reg_idx, uint8_t fifo_enable)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((fifo_enable << 0) & ~0x00000001) == 0);
UART_FCR_REG(reg_idx) = (UART_FCR_REG(reg_idx) & ~0x00000001) | (fifo_enable << 0);
}
/**
* @brief UART_TCR register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 07 DLAB 0
* 06 Brk 0
* 04 EPS 0
* 03 PEN 0
* 02 STOP 0
* 01:00 CLS 0x0
* </pre>
*/
#define UART_TCR_REG(i) (* ((volatile uint32_t *)(0x4001000C + uart_offset[i])) )
#define UART_TCR_ADDR(i) (0x4001000C + uart_offset[i])
#define UART_TCR_OFFSET 0x0000000C
__INLINE uint32_t uart_tcr_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
return UART_TCR_REG(reg_idx);
}
__INLINE void uart_tcr_set(uint32_t reg_idx, uint32_t value)
{
ASSERT_ERR(reg_idx <= 2);
UART_TCR_REG(reg_idx) = value;
}
// field definitions
#define DLAB_BIT 0x00000080
#define DLAB_POS 7
#define BRK_BIT 0x00000040
#define BRK_POS 6
#define EPS_BIT 0x00000010
#define EPS_POS 4
#define PEN_BIT 0x00000008
#define PEN_POS 3
#define STOP_BIT 0x00000004
#define STOP_POS 2
#define CLS_MASK 0x00000003
#define CLS_LSB 0
#define CLS_WIDTH 0x00000002
#define DLAB_RST 0x0
#define BRK_RST 0x0
#define EPS_RST 0x0
#define PEN_RST 0x0
#define STOP_RST 0x0
#define CLS_RST 0x0
__INLINE void uart_tcr_pack(uint32_t reg_idx, uint8_t dlab, uint8_t brk, uint8_t eps, uint8_t pen, uint8_t stop, uint8_t cls)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((dlab << 7) & ~0x00000080) == 0);
ASSERT_ERR(((brk << 6) & ~0x00000040) == 0);
ASSERT_ERR(((eps << 4) & ~0x00000010) == 0);
ASSERT_ERR(((pen << 3) & ~0x00000008) == 0);
ASSERT_ERR(((stop << 2) & ~0x00000004) == 0);
ASSERT_ERR(((cls << 0) & ~0x00000003) == 0);
UART_TCR_REG(reg_idx) = (dlab << 7) | (brk << 6) | (eps << 4) | (pen << 3) | (stop << 2) | (cls << 0);
}
__INLINE void uart_tcr_unpack(uint32_t reg_idx, uint8_t* dlab, uint8_t* brk, uint8_t* eps, uint8_t* pen, uint8_t* stop, uint8_t* cls)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_TCR_REG(reg_idx);
*dlab = (localVal & 0x00000080) >> 7;
*brk = (localVal & 0x00000040) >> 6;
*eps = (localVal & 0x00000010) >> 4;
*pen = (localVal & 0x00000008) >> 3;
*stop = (localVal & 0x00000004) >> 2;
*cls = (localVal & 0x00000003) >> 0;
}
__INLINE uint8_t uart_tcr__dlab__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_TCR_REG(reg_idx);
return ((localVal & 0x00000080) >> 7);
}
__INLINE void uart_tcr__dlab__setf(uint32_t reg_idx, uint8_t dlab)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((dlab << 7) & ~0x00000080) == 0);
UART_TCR_REG(reg_idx) = (UART_TCR_REG(reg_idx) & ~0x00000080) | (dlab << 7);
}
__INLINE uint8_t uart_tcr__brk__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_TCR_REG(reg_idx);
return ((localVal & 0x00000040) >> 6);
}
__INLINE void uart_tcr__brk__setf(uint32_t reg_idx, uint8_t brk)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((brk << 6) & ~0x00000040) == 0);
UART_TCR_REG(reg_idx) = (UART_TCR_REG(reg_idx) & ~0x00000040) | (brk << 6);
}
__INLINE uint8_t uart_tcr__eps__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_TCR_REG(reg_idx);
return ((localVal & 0x00000010) >> 4);
}
__INLINE void uart_tcr__eps__setf(uint32_t reg_idx, uint8_t eps)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((eps << 4) & ~0x00000010) == 0);
UART_TCR_REG(reg_idx) = (UART_TCR_REG(reg_idx) & ~0x00000010) | (eps << 4);
}
__INLINE uint8_t uart_tcr__pen__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_TCR_REG(reg_idx);
return ((localVal & 0x00000008) >> 3);
}
__INLINE void uart_tcr__pen__setf(uint32_t reg_idx, uint8_t pen)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((pen << 3) & ~0x00000008) == 0);
UART_TCR_REG(reg_idx) = (UART_TCR_REG(reg_idx) & ~0x00000008) | (pen << 3);
}
__INLINE uint8_t uart_tcr__stop__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_TCR_REG(reg_idx);
return ((localVal & 0x00000004) >> 2);
}
__INLINE void uart_tcr__stop__setf(uint32_t reg_idx, uint8_t stop)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((stop << 2) & ~0x00000004) == 0);
UART_TCR_REG(reg_idx) = (UART_TCR_REG(reg_idx) & ~0x00000004) | (stop << 2);
}
__INLINE uint8_t uart_tcr__cls__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_TCR_REG(reg_idx);
return ((localVal & 0x00000003) >> 0);
}
__INLINE void uart_tcr__cls__setf(uint32_t reg_idx, uint8_t cls)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((cls << 0) & ~0x00000003) == 0);
UART_TCR_REG(reg_idx) = (UART_TCR_REG(reg_idx) & ~0x00000003) | (cls << 0);
}
/**
* @brief UART_MCR register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 05 AFCE 0
* 00 RTS 0
* </pre>
*/
#define UART_MCR_REG(i) (* ((volatile uint32_t *)(0x40010010 + uart_offset[i])) )
#define UART_MCR_ADDR(i) (0x40010010 + uart_offset[i])
#define UART_MCR_OFFSET 0x00000010
__INLINE uint32_t uart_mcr_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
return UART_MCR_REG(reg_idx);
}
__INLINE void uart_mcr_set(uint32_t reg_idx, uint32_t value)
{
ASSERT_ERR(reg_idx <= 2);
UART_MCR_REG(reg_idx) = value;
}
// field definitions
#define AFCE_BIT 0x00000020
#define AFCE_POS 5
#define RTS_BIT 0x00000001
#define RTS_POS 0
#define AFCE_RST 0x0
#define RTS_RST 0x0
__INLINE void uart_mcr_pack(uint32_t reg_idx, uint8_t afce, uint8_t rts)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((afce << 5) & ~0x00000020) == 0);
ASSERT_ERR(((rts << 0) & ~0x00000001) == 0);
UART_MCR_REG(reg_idx) = (afce << 5) | (rts << 0);
}
__INLINE void uart_mcr_unpack(uint32_t reg_idx, uint8_t* afce, uint8_t* rts)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_MCR_REG(reg_idx);
*afce = (localVal & 0x00000020) >> 5;
*rts = (localVal & 0x00000001) >> 0;
}
__INLINE uint8_t uart_mcr__afce__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_MCR_REG(reg_idx);
return ((localVal & 0x00000020) >> 5);
}
__INLINE void uart_mcr__afce__setf(uint32_t reg_idx, uint8_t afce)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((afce << 5) & ~0x00000020) == 0);
UART_MCR_REG(reg_idx) = (UART_MCR_REG(reg_idx) & ~0x00000020) | (afce << 5);
}
__INLINE uint8_t uart_mcr__rts__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_MCR_REG(reg_idx);
return ((localVal & 0x00000001) >> 0);
}
__INLINE void uart_mcr__rts__setf(uint32_t reg_idx, uint8_t rts)
{
ASSERT_ERR(reg_idx <= 2);
ASSERT_ERR(((rts << 0) & ~0x00000001) == 0);
UART_MCR_REG(reg_idx) = (UART_MCR_REG(reg_idx) & ~0x00000001) | (rts << 0);
}
/**
* @brief UART_TSR register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 07 RX_FIFO_ERROR 0
* 05 THRE 0
* 04 BI 0
* 03 FE 0
* 02 PE 0
* 01 OE 0
* 00 DR 0
* </pre>
*/
#define UART_TSR_REG(i) (* ((volatile uint32_t *)(0x40010014 + uart_offset[i])) )
#define UART_TSR_ADDR(i) (0x40010014 + uart_offset[i])
#define UART_TSR_OFFSET 0x00000014
__INLINE uint32_t uart_tsr_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
return UART_TSR_REG(reg_idx);
}
// field definitions
#define RX_FIFO_ERROR_BIT 0x00000080
#define RX_FIFO_ERROR_POS 7
#define THRE_BIT 0x00000020
#define THRE_POS 5
#define BI_BIT 0x00000010
#define BI_POS 4
#define FE_BIT 0x00000008
#define FE_POS 3
#define PE_BIT 0x00000004
#define PE_POS 2
#define OE_BIT 0x00000002
#define OE_POS 1
#define DR_BIT 0x00000001
#define DR_POS 0
#define RX_FIFO_ERROR_RST 0x0
#define THRE_RST 0x0
#define BI_RST 0x0
#define FE_RST 0x0
#define PE_RST 0x0
#define OE_RST 0x0
#define DR_RST 0x0
__INLINE void uart_tsr_unpack(uint32_t reg_idx, uint8_t* rx_fifo_error, uint8_t* thre, uint8_t* bi, uint8_t* fe, uint8_t* pe, uint8_t* oe, uint8_t* dr)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_TSR_REG(reg_idx);
*rx_fifo_error = (localVal & 0x00000080) >> 7;
*thre = (localVal & 0x00000020) >> 5;
*bi = (localVal & 0x00000010) >> 4;
*fe = (localVal & 0x00000008) >> 3;
*pe = (localVal & 0x00000004) >> 2;
*oe = (localVal & 0x00000002) >> 1;
*dr = (localVal & 0x00000001) >> 0;
}
__INLINE uint8_t uart_tsr__rx_fifo_error__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_TSR_REG(reg_idx);
return ((localVal & 0x00000080) >> 7);
}
__INLINE uint8_t uart_tsr__thre__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_TSR_REG(reg_idx);
return ((localVal & 0x00000020) >> 5);
}
__INLINE uint8_t uart_tsr__bi__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_TSR_REG(reg_idx);
return ((localVal & 0x00000010) >> 4);
}
__INLINE uint8_t uart_tsr__fe__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_TSR_REG(reg_idx);
return ((localVal & 0x00000008) >> 3);
}
__INLINE uint8_t uart_tsr__pe__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_TSR_REG(reg_idx);
return ((localVal & 0x00000004) >> 2);
}
__INLINE uint8_t uart_tsr__oe__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_TSR_REG(reg_idx);
return ((localVal & 0x00000002) >> 1);
}
__INLINE uint8_t uart_tsr__dr__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_TSR_REG(reg_idx);
return ((localVal & 0x00000001) >> 0);
}
/**
* @brief UART_MSR register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 04 CTS 0
* 00 DCTS 0
* </pre>
*/
#define UART_MSR_REG(i) (* ((volatile uint32_t *)(0x40010018 + uart_offset[i])) )
#define UART_MSR_ADDR(i) (0x40010018 + uart_offset[i])
#define UART_MSR_OFFSET 0x00000018
__INLINE uint32_t uart_msr_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
return UART_MSR_REG(reg_idx);
}
// field definitions
#define CTS_BIT 0x00000010
#define CTS_POS 4
#define DCTS_BIT 0x00000001
#define DCTS_POS 0
#define CTS_RST 0x0
#define DCTS_RST 0x0
__INLINE void uart_msr_unpack(uint32_t reg_idx, uint8_t* cts, uint8_t* dcts)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_MSR_REG(reg_idx);
*cts = (localVal & 0x00000010) >> 4;
*dcts = (localVal & 0x00000001) >> 0;
}
__INLINE uint8_t uart_msr__cts__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_MSR_REG(reg_idx);
return ((localVal & 0x00000010) >> 4);
}
__INLINE uint8_t uart_msr__dcts__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_MSR_REG(reg_idx);
return ((localVal & 0x00000001) >> 0);
}
/**
* @brief UART_USR register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 00 BUSY 0
* </pre>
*/
#define UART_USR_REG(i) (* ((volatile uint32_t *)(0x4001007C + uart_offset[i])) )
#define UART_USR_ADDR(i) (0x4001007C + uart_offset[i])
#define UART_USR_OFFSET 0x0000007C
__INLINE uint32_t uart_usr_get(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
return UART_USR_REG(reg_idx);
}
// field definitions
#define BUSY_BIT 0x00000001
#define BUSY_POS 0
#define BUSY_RST 0x0
__INLINE uint8_t uart_usr__busy__getf(uint32_t reg_idx)
{
ASSERT_ERR(reg_idx <= 2);
uint32_t localVal = UART_USR_REG(reg_idx);
ASSERT_ERR((localVal & ~0x00000001) == 0);
return (localVal >> 0);
}
#endif // _XC_REG_UART_H_
@@ -0,0 +1,270 @@
#ifndef _XC_REG_WDT_H_
#define _XC_REG_WDT_H_
#include <stdint.h>
#define XC_REG_WDT_BASE_ADDR 0x40004000
#define XC_REG_WDT_DECODING_MASK 0x0000001F
/**
* @brief WDT_CR register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 04:02 WDT_RPL 0x0
* 01 WDT_RMOD 0
* 00 WDT_EN 0
* </pre>
*/
#define WDT_CR_REG (*(volatile uint32_t *)(0x40004000))
#define WDT_CR_ADDR 0x40004000
#define WDT_CR_OFFSET 0x00000000
__INLINE uint32_t wdt_cr_get(void)
{
return WDT_CR_REG;
}
__INLINE void wdt_cr_set(uint32_t value)
{
WDT_CR_REG = value;
}
// field definitions
#define WDT_RPL_MASK 0x0000001C
#define WDT_RPL_LSB 2
#define WDT_RPL_WIDTH 0x00000003
#define WDT_RMOD_BIT 0x00000002
#define WDT_RMOD_POS 1
#define WDT_EN_BIT 0x00000001
#define WDT_EN_POS 0
#define WDT_RPL_RST 0x0
#define WDT_RMOD_RST 0x0
#define WDT_EN_RST 0x0
__INLINE void wdt_cr_pack(uint8_t wdt_rpl, uint8_t wdt_rmod, uint8_t wdt_en)
{
ASSERT_ERR(((wdt_rpl << 2) & ~0x0000001C) == 0);
ASSERT_ERR(((wdt_rmod << 1) & ~0x00000002) == 0);
ASSERT_ERR(((wdt_en << 0) & ~0x00000001) == 0);
WDT_CR_REG = (wdt_rpl << 2) | (wdt_rmod << 1) | (wdt_en << 0);
}
__INLINE void wdt_cr_unpack(uint8_t* wdt_rpl, uint8_t* wdt_rmod, uint8_t* wdt_en)
{
uint32_t localVal = WDT_CR_REG;
*wdt_rpl = (localVal & 0x0000001C) >> 2;
*wdt_rmod = (localVal & 0x00000002) >> 1;
*wdt_en = (localVal & 0x00000001) >> 0;
}
__INLINE uint8_t wdt_cr__wdt_rpl__getf(void)
{
uint32_t localVal = WDT_CR_REG;
return ((localVal & 0x0000001C) >> 2);
}
__INLINE void wdt_cr__wdt_rpl__setf(uint8_t wdt_rpl)
{
ASSERT_ERR(((wdt_rpl << 2) & ~0x0000001C) == 0);
WDT_CR_REG = (WDT_CR_REG & ~0x0000001C) | (wdt_rpl << 2);
}
__INLINE uint8_t wdt_cr__wdt_rmod__getf(void)
{
uint32_t localVal = WDT_CR_REG;
return ((localVal & 0x00000002) >> 1);
}
__INLINE void wdt_cr__wdt_rmod__setf(uint8_t wdt_rmod)
{
ASSERT_ERR(((wdt_rmod << 1) & ~0x00000002) == 0);
WDT_CR_REG = (WDT_CR_REG & ~0x00000002) | (wdt_rmod << 1);
}
__INLINE uint8_t wdt_cr__wdt_en__getf(void)
{
uint32_t localVal = WDT_CR_REG;
return ((localVal & 0x00000001) >> 0);
}
__INLINE void wdt_cr__wdt_en__setf(uint8_t wdt_en)
{
ASSERT_ERR(((wdt_en << 0) & ~0x00000001) == 0);
WDT_CR_REG = (WDT_CR_REG & ~0x00000001) | (wdt_en << 0);
}
/**
* @brief WDT_TORR register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 03:00 WDT_TOP 0x0
* </pre>
*/
#define WDT_TORR_REG (*(volatile uint32_t *)(0x40004004))
#define WDT_TORR_ADDR 0x40004004
#define WDT_TORR_OFFSET 0x00000004
__INLINE uint32_t wdt_torr_get(void)
{
return WDT_TORR_REG;
}
__INLINE void wdt_torr_set(uint32_t value)
{
WDT_TORR_REG = value;
}
// field definitions
#define WDT_TOP_MASK 0x0000000F
#define WDT_TOP_LSB 0
#define WDT_TOP_WIDTH 0x00000004
#define WDT_TOP_RST 0x0
__INLINE uint8_t wdt_torr__wdt_top__getf(void)
{
uint32_t localVal = WDT_TORR_REG;
ASSERT_ERR((localVal & ~0x0000000F) == 0);
return (localVal >> 0);
}
__INLINE void wdt_torr__wdt_top__setf(uint8_t wdt_top)
{
ASSERT_ERR(((wdt_top << 0) & ~0x0000000F) == 0);
WDT_TORR_REG = wdt_top << 0;
}
/**
* @brief WDT_CCVR register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 31:00 WDT_CCVR 0x0
* </pre>
*/
#define WDT_CCVR_REG (*(volatile uint32_t *)(0x40004008))
#define WDT_CCVR_ADDR 0x40004008
#define WDT_CCVR_OFFSET 0x00000008
__INLINE uint32_t wdt_ccvr_get(void)
{
return WDT_CCVR_REG;
}
__INLINE void wdt_ccvr_set(uint32_t value)
{
WDT_CCVR_REG = value;
}
// field definitions
#define WDT_CCVR_MASK 0xFFFFFFFF
#define WDT_CCVR_LSB 0
#define WDT_CCVR_WIDTH 0x00000020
#define WDT_CCVR_RST 0x0
__INLINE uint32_t wdt_ccvr__getf(void)
{
uint32_t localVal = WDT_CCVR_REG;
ASSERT_ERR((localVal & ~0xFFFFFFFF) == 0);
return (localVal >> 0);
}
/**
* @brief WDT_CRR register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 07:00 WDT_CRR 0x0
* </pre>
*/
#define WDT_CRR_REG (*(volatile uint32_t *)(0x4000400C))
#define WDT_CRR_ADDR 0x4000400C
#define WDT_CRR_OFFSET 0x0000000C
__INLINE void wdt_crr_set(uint32_t value)
{
WDT_CRR_REG = value;
}
// field definitions
#define WDT_CRR_MASK 0x000000FF
#define WDT_CRR_LSB 0
#define WDT_CRR_WIDTH 0x00000008
#define WDT_CRR_RST 0x0
__INLINE void wdt_crr__setf(uint8_t wdt_crr)
{
ASSERT_ERR(((wdt_crr << 0) & ~0x000000FF) == 0);
WDT_CRR_REG = wdt_crr << 0;
}
/**
* @brief WDT_STAT register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 00 WDT_STAT 0
* </pre>
*/
#define WDT_STAT_REG (*(volatile uint32_t *)(0x40004010))
#define WDT_STAT_ADDR 0x40004010
#define WDT_STAT_OFFSET 0x00000010
__INLINE uint32_t wdt_stat_get(void)
{
return WDT_STAT_REG;
}
// field definitions
#define WDT_STAT_BIT 0x00000001
#define WDT_STAT_POS 0
#define WDT_STAT_RST 0x0
__INLINE uint8_t wdt_stat__getf(void)
{
uint32_t localVal = WDT_STAT_REG;
ASSERT_ERR((localVal & ~0x00000001) == 0);
return (localVal >> 0);
}
/**
* @brief WDT_ICR register definition
* <pre>
* Bits Field Name Reset Value
* ----- ------------------ -----------
* 00 WDT_ICR 0
* </pre>
*/
#define WDT_ICR_REG (*(volatile uint32_t *)(0x40004014))
#define WDT_ICR_ADDR 0x40004014
#define WDT_ICR_OFFSET 0x00000014
__INLINE uint32_t wdt_icr_get(void)
{
return WDT_ICR_REG;
}
// field definitions
#define WDT_ICR_BIT 0x00000001
#define WDT_ICR_POS 0
#define WDT_ICR_RST 0x0
__INLINE uint8_t wdt_icr__getf(void)
{
uint32_t localVal = WDT_ICR_REG;
ASSERT_ERR((localVal & ~0x00000001) == 0);
return (localVal >> 0);
}
#endif // _XC_REG_WDT_H_
@@ -0,0 +1,222 @@
/**************************************************************************//**
* @file core_cm0.c
* @brief CMSIS Cortex-M0 Core Peripheral Access Layer Source File
* @version V2.00
* @date 10. September 2010
*
* @note
* Copyright (C) 2009-2010 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#include <stdint.h>
/* define compiler specific symbols */
#if defined(__CC_ARM)
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
#elif defined(__ICCARM__)
#define __ASM __asm /*!< asm keyword for IAR Compiler */
#define __INLINE \
inline /*!< inline keyword for IAR Compiler. Only avaiable in High \
optimization mode! */
#elif defined(__GNUC__)
#define __ASM __asm /*!< asm keyword for GNU Compiler */
#define __INLINE inline /*!< inline keyword for GNU Compiler */
#elif defined(__TASKING__)
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
#endif
/* ########################## Core Instruction Access
* ######################### */
#if defined(__CC_ARM) /*------------------ RealView Compiler \
----------------*/
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
#if (__ARMCC_VERSION < 400677)
__ASM uint32_t __REV16(uint32_t value) { rev16 r0, r0 bx lr }
#endif /* __ARMCC_VERSION */
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign
extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
#if (__ARMCC_VERSION < 400677)
__ASM int32_t __REVSH(int32_t value) { revsh r0, r0 bx lr }
#endif /* __ARMCC_VERSION */
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
#if (__ARMCC_VERSION < 400000)
__ASM void __CLREX(void) { clrex }
#endif /* __ARMCC_VERSION */
#elif (defined( \
__ICCARM__)) /*---------------- ICC Compiler ---------------------*/
/* obsolete */
#elif (defined( \
__GNUC__)) /*------------------ GNU Compiler ---------------------*/
/* obsolete */
#elif (defined( \
__TASKING__)) /*--------------- TASKING Compiler -----------------*/
/* obsolete */
#endif
/* ########################### Core Function Access
* ########################### */
#if defined(__CC_ARM) /*------------------ RealView Compiler \
----------------*/
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_CONTROL(void) { mrs r0, control bx lr }
#endif /* __ARMCC_VERSION */
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
#if (__ARMCC_VERSION < 400000)
__ASM void __set_CONTROL(uint32_t control) { msr control, r0 bx lr }
#endif /* __ARMCC_VERSION */
/** \brief Get ISPR Register
This function returns the content of the ISPR Register.
\return ISPR Register value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_IPSR(void) { mrs r0, ipsr bx lr }
#endif /* __ARMCC_VERSION */
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_APSR(void) { mrs r0, apsr bx lr }
#endif /* __ARMCC_VERSION */
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_xPSR(void) { mrs r0, xpsr bx lr }
#endif /* __ARMCC_VERSION */
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_PSP(void) { mrs r0, psp bx lr }
#endif /* __ARMCC_VERSION */
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
#if (__ARMCC_VERSION < 400000)
__ASM void __set_PSP(uint32_t topOfProcStack) { msr psp, r0 bx lr }
#endif /* __ARMCC_VERSION */
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_MSP(void) { mrs r0, msp bx lr }
#endif /* __ARMCC_VERSION */
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
#if (__ARMCC_VERSION < 400000)
__ASM void __set_MSP(uint32_t mainStackPointer) { msr msp, r0 bx lr }
#endif /* __ARMCC_VERSION */
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the
Priority Mask Register.
\return Priority Mask value
*/
#if (__ARMCC_VERSION < 400000)
__ASM uint32_t __get_PRIMASK(void) { mrs r0, primask bx lr }
#endif /* __ARMCC_VERSION */
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
#if (__ARMCC_VERSION < 400000)
__ASM void __set_PRIMASK(uint32_t priMask) { msr primask, r0 bx lr }
#endif /* __ARMCC_VERSION */
#elif (defined( \
__ICCARM__)) /*---------------- ICC Compiler ---------------------*/
/* obsolete */
#elif (defined( \
__GNUC__)) /*------------------ GNU Compiler ---------------------*/
/* obsolete */
#elif (defined( \
__TASKING__)) /*--------------- TASKING Compiler -----------------*/
/* obsolete */
#endif
@@ -0,0 +1,703 @@
/**************************************************************************//**
* @file core_cm0.h
* @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File
* @version V2.01
* @date 06. December 2010
*
* @note
* Copyright (C) 2009-2010 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __CORE_CM0_H_GENERIC
#define __CORE_CM0_H_GENERIC
/** \mainpage CMSIS Cortex-M0
This documentation describes the CMSIS Cortex-M Core Peripheral Access Layer.
It consists of:
- Cortex-M Core Register Definitions
- Cortex-M functions
- Cortex-M instructions
The CMSIS Cortex-M0 Core Peripheral Access Layer contains C and assembly functions that ease
access to the Cortex-M Core
*/
/** \defgroup CMSIS_LintCinfiguration CMSIS Lint Configuration
List of Lint messages which will be suppressed and not shown:
- not yet checked
.
Note: To re-enable a Message, insert a space before 'lint' *
*/
/*******************************************************************************
* CMSIS definitions
******************************************************************************/
/** \defgroup CMSIS_core_definitions CMSIS Core Definitions
This file defines all structures and symbols for CMSIS core:
- CMSIS version number
- Cortex-M core
- Cortex-M core Revision Number
@{
*/
/* CMSIS CM0 definitions */
#define __CM0_CMSIS_VERSION_MAIN (0x02) /*!< [31:16] CMSIS HAL main version */
#define __CM0_CMSIS_VERSION_SUB (0x00) /*!< [15:0] CMSIS HAL sub version */
#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16) | __CM0_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */
#define __CORTEX_M (0x00) /*!< Cortex core */
#if defined ( __CC_ARM )
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __forceinline /*!< inline keyword for ARM Compiler */
#elif defined ( __ICCARM__ )
#define __ASM __asm /*!< asm keyword for IAR Compiler */
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */
#elif defined ( __GNUC__ )
#define __ASM __asm /*!< asm keyword for GNU Compiler */
#define __INLINE inline /*!< inline keyword for GNU Compiler */
#elif defined ( __TASKING__ )
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
#endif
#include <stdint.h> /*!< standard types definitions */
#include "core_cmInstr.h" /*!< Core Instruction Access */
#include "core_cmFunc.h" /*!< Core Function Access */
#endif /* __CORE_CM0_H_GENERIC */
#ifndef __CMSIS_GENERIC
#ifndef __CORE_CM0_H_DEPENDANT
#define __CORE_CM0_H_DEPENDANT
/* IO definitions (access restrictions to peripheral registers) */
#ifdef __cplusplus
#define __I volatile /*!< defines 'read only' permissions */
#else
#define __I volatile const /*!< defines 'read only' permissions */
#endif
#define __O volatile /*!< defines 'write only' permissions */
#define __IO volatile /*!< defines 'read / write' permissions */
/*@} end of group CMSIS_core_definitions */
/*******************************************************************************
* Register Abstraction
******************************************************************************/
/** \defgroup CMSIS_core_register CMSIS Core Register
Core Register contain:
- Core Register
- Core NVIC Register
- Core SCB Register
- Core SysTick Register
- Core Debug Register
*/
/** \ingroup CMSIS_core_register
\defgroup CMSIS_CORE CMSIS Core
Type definitions for the Cortex-M Core Registers
@{
*/
/** \brief Union type to access the Application Program Status Register (APSR).
*/
typedef union
{
struct
{
#if (__CORTEX_M != 0x04)
uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */
#else
uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */
uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */
#endif
uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} APSR_Type;
/** \brief Union type to access the Interrupt Program Status Register (IPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} IPSR_Type;
/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR).
*/
typedef union
{
struct
{
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
#if (__CORTEX_M != 0x04)
uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
#else
uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */
uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */
#endif
uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */
uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} xPSR_Type;
/** \brief Union type to access the Control Registers (CONTROL).
*/
typedef union
{
struct
{
uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */
uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */
uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */
} b; /*!< Structure used for bit access */
uint32_t w; /*!< Type used for word access */
} CONTROL_Type;
/*@} end of group CMSIS_CORE */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_NVIC CMSIS NVIC
Type definitions for the Cortex-M NVIC Registers
@{
*/
/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
*/
typedef struct
{
__IO uint32_t ISER[1]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
uint32_t RESERVED0[31];
__IO uint32_t ICER[1]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
uint32_t RSERVED1[31];
__IO uint32_t ISPR[1]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
uint32_t RESERVED2[31];
__IO uint32_t ICPR[1]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
uint32_t RESERVED3[31];
uint32_t RESERVED4[64];
__IO uint32_t IPR[8]; /*!< Offset: 0x3EC (R/W) Interrupt Priority Register */
} NVIC_Type;
/*@} end of group CMSIS_NVIC */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_SCB CMSIS SCB
Type definitions for the Cortex-M System Control Block Registers
@{
*/
/** \brief Structure type to access the System Control Block (SCB).
*/
typedef struct
{
__I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPU ID Base Register */
__IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control State Register */
uint32_t RESERVED0;
__IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt / Reset Control Register */
__IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
__IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
uint32_t RESERVED1;
__IO uint32_t SHP[2]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
__IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
uint32_t RESERVED2[2];
__IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */
} SCB_Type;
/* SCB CPUID Register Definitions */
#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */
#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */
#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */
#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */
#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */
#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */
/* SCB Interrupt Control State Register Definitions */
#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */
#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */
#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */
#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */
#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */
#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */
#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */
#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */
#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */
#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */
/* SCB Application Interrupt and Reset Control Register Definitions */
#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */
#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */
#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */
#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */
#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */
#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
/* SCB System Control Register Definitions */
#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */
#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */
#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */
#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
/* SCB Configuration Control Register Definitions */
#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */
#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */
#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
/* SCB System Handler Control and State Register Definitions */
#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */
#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
/* SCB Debug Fault Status Register Definitions */
#define SCB_DFSR_EXTERNAL_Pos 4 /*!< SCB DFSR: EXTERNAL Position */
#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */
#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */
#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */
#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */
#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */
#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */
#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */
#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */
#define SCB_DFSR_HALTED_Msk (1UL << SCB_DFSR_HALTED_Pos) /*!< SCB DFSR: HALTED Mask */
/*@} end of group CMSIS_SCB */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_SysTick CMSIS SysTick
Type definitions for the Cortex-M System Timer Registers
@{
*/
/** \brief Structure type to access the System Timer (SysTick).
*/
typedef struct
{
__IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
__IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
__IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
__I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
} SysTick_Type;
/* SysTick Control / Status Register Definitions */
#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */
#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */
#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */
#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */
/* SysTick Reload Register Definitions */
#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */
/* SysTick Current Register Definitions */
#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */
#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */
/* SysTick Calibration Register Definitions */
#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */
#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */
#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */
#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */
/*@} end of group CMSIS_SysTick */
/** \ingroup CMSIS_core_register
\defgroup CMSIS_CoreDebug CMSIS Core Debug
Type definitions for the Cortex-M Core Debug Registers
@{
*/
/** \brief Structure type to access the Core Debug Register (CoreDebug).
*/
typedef struct
{
__IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */
__O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */
__IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */
__IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */
} CoreDebug_Type;
/* Debug Halting Control and Status Register */
#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */
#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */
#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */
#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */
#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */
#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */
#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */
#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */
#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */
#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */
#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */
#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */
#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */
#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */
#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */
#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */
#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */
#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */
#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */
#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */
#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */
#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL << CoreDebug_DHCSR_C_DEBUGEN_Pos) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
/* Debug Core Register Selector Register */
#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */
#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */
#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */
#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL << CoreDebug_DCRSR_REGSEL_Pos) /*!< CoreDebug DCRSR: REGSEL Mask */
/* Debug Exception and Monitor Control Register */
#define CoreDebug_DEMCR_DWTENA_Pos 24 /*!< CoreDebug DEMCR: DWTENA Position */
#define CoreDebug_DEMCR_DWTENA_Msk (1UL << CoreDebug_DEMCR_DWTENA_Pos) /*!< CoreDebug DEMCR: DWTENA Mask */
#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */
#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */
#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */
#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL << CoreDebug_DEMCR_VC_CORERESET_Pos) /*!< CoreDebug DEMCR: VC_CORERESET Mask */
/*@} end of group CMSIS_CoreDebug */
/** \ingroup CMSIS_core_register
@{
*/
/* Memory mapping of Cortex-M0 Hardware */
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
#define SCB ((SCB_Type *) SCB_BASE) /*!< SCB configuration struct */
#define SysTick ((SysTick_Type *) SysTick_BASE) /*!< SysTick configuration struct */
#define NVIC ((NVIC_Type *) NVIC_BASE) /*!< NVIC configuration struct */
#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */
/*@} */
/*******************************************************************************
* Hardware Abstraction Layer
******************************************************************************/
/** \defgroup CMSIS_Core_FunctionInterface CMSIS Core Function Interface
Core Function Interface contains:
- Core NVIC Functions
- Core SysTick Functions
- Core Register Access Functions
*/
/* ########################## NVIC functions #################################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_NVICFunctions CMSIS Core NVIC Functions
@{
*/
/* Interrupt Priorities are WORD accessible only under ARMv6M */
/* The following MACROS handle generation of the register offset and byte masks */
#define _BIT_SHIFT(IRQn) ( (((uint32_t)(IRQn) ) & 0x03) * 8 )
#define _SHP_IDX(IRQn) ( ((((uint32_t)(IRQn) & 0x0F)-8) >> 2) )
#define _IP_IDX(IRQn) ( ((uint32_t)(IRQn) >> 2) )
/** \brief Enable External Interrupt
This function enables a device specific interupt in the NVIC interrupt controller.
The interrupt number cannot be a negative value.
\param [in] IRQn Number of the external interrupt to enable
*/
static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
{
NVIC->ISER[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/** \brief Disable External Interrupt
This function disables a device specific interupt in the NVIC interrupt controller.
The interrupt number cannot be a negative value.
\param [in] IRQn Number of the external interrupt to disable
*/
static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
{
NVIC->ICER[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/** \brief Get Pending Interrupt
This function reads the pending register in the NVIC and returns the pending bit
for the specified interrupt.
\param [in] IRQn Number of the interrupt for get pending
\return 0 Interrupt status is not pending
\return 1 Interrupt status is pending
*/
static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
{
return((uint32_t) ((NVIC->ISPR[0] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
}
/** \brief Set Pending Interrupt
This function sets the pending bit for the specified interrupt.
The interrupt number cannot be a negative value.
\param [in] IRQn Number of the interrupt for set pending
*/
static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
{
NVIC->ISPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F));
}
/** \brief Clear Pending Interrupt
This function clears the pending bit for the specified interrupt.
The interrupt number cannot be a negative value.
\param [in] IRQn Number of the interrupt for clear pending
*/
static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
{
NVIC->ICPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */
}
/** \brief Set Interrupt Priority
This function sets the priority for the specified interrupt. The interrupt
number can be positive to specify an external (device specific)
interrupt, or negative to specify an internal (core) interrupt.
Note: The priority cannot be set for every core interrupt.
\param [in] IRQn Number of the interrupt for set priority
\param [in] priority Priority to set
*/
static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if(IRQn < 0) {
SCB->SHP[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
(((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
else {
NVIC->IPR[_IP_IDX(IRQn)] = (NVIC->IPR[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) |
(((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); }
}
/** \brief Get Interrupt Priority
This function reads the priority for the specified interrupt. The interrupt
number can be positive to specify an external (device specific)
interrupt, or negative to specify an internal (core) interrupt.
The returned priority value is automatically aligned to the implemented
priority bits of the microcontroller.
\param [in] IRQn Number of the interrupt for get priority
\return Interrupt Priority
*/
static __INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
{
if(IRQn < 0) {
return((uint32_t)((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M0 system interrupts */
else {
return((uint32_t)((NVIC->IPR[_IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */
}
/** \brief System Reset
This function initiate a system reset request to reset the MCU.
*/
static __INLINE void NVIC_SystemReset(void)
{
__DSB(); /* Ensure all outstanding memory accesses included
buffered write are completed before reset */
SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |
SCB_AIRCR_SYSRESETREQ_Msk);
__DSB(); /* Ensure completion of memory access */
while(1); /* wait until reset */
}
/*@} end of CMSIS_Core_NVICFunctions */
/* ################################## SysTick function ############################################ */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_SysTickFunctions CMSIS Core SysTick Functions
@{
*/
#if (__Vendor_SysTickConfig == 0)
/** \brief System Tick Configuration
This function initialises the system tick timer and its interrupt and start the system tick timer.
Counter is in free running mode to generate periodical interrupts.
\param [in] ticks Number of ticks between two interrupts
\return 0 Function succeeded
\return 1 Function failed
*/
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */
SysTick->VAL = 0; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0); /* Function successful */
}
#endif
/*@} end of CMSIS_Core_SysTickFunctions */
#endif /* __CORE_CM0_H_DEPENDANT */
#endif /* __CMSIS_GENERIC */
#ifdef __cplusplus
}
#endif
/*lint -restore */
@@ -0,0 +1,844 @@
/**************************************************************************//**
* @file core_cmFunc.h
* @brief CMSIS Cortex-M Core Function Access Header File
* @version V2.01
* @date 06. December 2010
*
* @note
* Copyright (C) 2009-2010 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __CORE_CMFUNC_H__
#define __CORE_CMFUNC_H__
/* ########################### Core Function Access ########################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
@{
*/
#if defined ( __CC_ARM ) /*------------------ RealView Compiler ----------------*/
/* ARM armcc specific functions */
/* intrinsic void __enable_irq(); */
/* intrinsic void __disable_irq(); */
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
#if (__ARMCC_VERSION < 400000)
extern uint32_t __get_CONTROL(void);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE uint32_t __get_CONTROL(void)
{
register uint32_t __regControl __ASM("control");
return(__regControl);
}
#endif /* __ARMCC_VERSION */
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
#if (__ARMCC_VERSION < 400000)
extern void __set_CONTROL(uint32_t control);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE void __set_CONTROL(uint32_t control)
{
register uint32_t __regControl __ASM("control");
__regControl = control;
}
#endif /* __ARMCC_VERSION */
/** \brief Get ISPR Register
This function returns the content of the ISPR Register.
\return ISPR Register value
*/
#if (__ARMCC_VERSION < 400000)
extern uint32_t __get_IPSR(void);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE uint32_t __get_IPSR(void)
{
register uint32_t __regIPSR __ASM("ipsr");
return(__regIPSR);
}
#endif /* __ARMCC_VERSION */
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
#if (__ARMCC_VERSION < 400000)
extern uint32_t __get_APSR(void);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE uint32_t __get_APSR(void)
{
register uint32_t __regAPSR __ASM("apsr");
return(__regAPSR);
}
#endif /* __ARMCC_VERSION */
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
#if (__ARMCC_VERSION < 400000)
extern uint32_t __get_xPSR(void);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE uint32_t __get_xPSR(void)
{
register uint32_t __regXPSR __ASM("xpsr");
return(__regXPSR);
}
#endif /* __ARMCC_VERSION */
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
#if (__ARMCC_VERSION < 400000)
extern uint32_t __get_PSP(void);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE uint32_t __get_PSP(void)
{
register uint32_t __regProcessStackPointer __ASM("psp");
return(__regProcessStackPointer);
}
#endif /* __ARMCC_VERSION */
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
#if (__ARMCC_VERSION < 400000)
extern void __set_PSP(uint32_t topOfProcStack);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE void __set_PSP(uint32_t topOfProcStack)
{
register uint32_t __regProcessStackPointer __ASM("psp");
__regProcessStackPointer = topOfProcStack;
}
#endif /* __ARMCC_VERSION */
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
#if (__ARMCC_VERSION < 400000)
extern uint32_t __get_MSP(void);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE uint32_t __get_MSP(void)
{
register uint32_t __regMainStackPointer __ASM("msp");
return(__regMainStackPointer);
}
#endif /* __ARMCC_VERSION */
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
#if (__ARMCC_VERSION < 400000)
extern void __set_MSP(uint32_t topOfMainStack);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE void __set_MSP(uint32_t topOfMainStack)
{
register uint32_t __regMainStackPointer __ASM("msp");
__regMainStackPointer = topOfMainStack;
}
#endif /* __ARMCC_VERSION */
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
#if (__ARMCC_VERSION < 400000)
extern uint32_t __get_PRIMASK(void);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE uint32_t __get_PRIMASK(void)
{
register uint32_t __regPriMask __ASM("primask");
return(__regPriMask);
}
#endif /* __ARMCC_VERSION */
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
#if (__ARMCC_VERSION < 400000)
extern void __set_PRIMASK(uint32_t priMask);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE void __set_PRIMASK(uint32_t priMask)
{
register uint32_t __regPriMask __ASM("primask");
__regPriMask = (priMask);
}
#endif /* __ARMCC_VERSION */
#if (__CORTEX_M >= 0x03)
/** \brief Enable FIQ
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __enable_fault_irq __enable_fiq
/** \brief Disable FIQ
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __disable_fault_irq __disable_fiq
/** \brief Get Base Priority
This function returns the current value of the Base Priority register.
\return Base Priority register value
*/
#if (__ARMCC_VERSION < 400000)
extern uint32_t __get_BASEPRI(void);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE uint32_t __get_BASEPRI(void)
{
register uint32_t __regBasePri __ASM("basepri");
return(__regBasePri);
}
#endif /* __ARMCC_VERSION */
/** \brief Set Base Priority
This function assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
#if (__ARMCC_VERSION < 400000)
extern void __set_BASEPRI(uint32_t basePri);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE void __set_BASEPRI(uint32_t basePri)
{
register uint32_t __regBasePri __ASM("basepri");
__regBasePri = (basePri & 0xff);
}
#endif /* __ARMCC_VERSION */
/** \brief Get Fault Mask
This function returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
#if (__ARMCC_VERSION < 400000)
extern uint32_t __get_FAULTMASK(void);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE uint32_t __get_FAULTMASK(void)
{
register uint32_t __regFaultMask __ASM("faultmask");
return(__regFaultMask);
}
#endif /* __ARMCC_VERSION */
/** \brief Set Fault Mask
This function assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
#if (__ARMCC_VERSION < 400000)
extern void __set_FAULTMASK(uint32_t faultMask);
#else /* (__ARMCC_VERSION >= 400000) */
static __INLINE void __set_FAULTMASK(uint32_t faultMask)
{
register uint32_t __regFaultMask __ASM("faultmask");
__regFaultMask = (faultMask & 1);
}
#endif /* __ARMCC_VERSION */
#endif /* (__CORTEX_M >= 0x03) */
#if (__CORTEX_M == 0x04)
/** \brief Get FPSCR
This function returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
static __INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1)
register uint32_t __regfpscr __ASM("fpscr");
return(__regfpscr);
#else
return(0);
#endif
}
/** \brief Set FPSCR
This function assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
static __INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1)
register uint32_t __regfpscr __ASM("fpscr");
__regfpscr = (fpscr);
#endif
}
#endif /* (__CORTEX_M == 0x04) */
#elif (defined (__ICCARM__)) /*---------------- ICC Compiler ---------------------*/
/* IAR iccarm specific functions */
#if defined (__ICCARM__)
#include <intrinsics.h> /* IAR Intrinsics */
#endif
#pragma diag_suppress=Pe940
/** \brief Enable IRQ Interrupts
This function enables IRQ interrupts by clearing the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __enable_irq __enable_interrupt
/** \brief Disable IRQ Interrupts
This function disables IRQ interrupts by setting the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __disable_irq __disable_interrupt
/* intrinsic unsigned long __get_CONTROL( void ); (see intrinsic.h) */
/* intrinsic void __set_CONTROL( unsigned long ); (see intrinsic.h) */
/** \brief Get ISPR Register
This function returns the content of the ISPR Register.
\return ISPR Register value
*/
static uint32_t __get_IPSR(void)
{
__ASM("mrs r0, ipsr");
}
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
static uint32_t __get_APSR(void)
{
__ASM("mrs r0, apsr");
}
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
static uint32_t __get_xPSR(void)
{
__ASM("mrs r0, psr"); // assembler does not know "xpsr"
}
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
static uint32_t __get_PSP(void)
{
__ASM("mrs r0, psp");
}
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
static void __set_PSP(uint32_t topOfProcStack)
{
__ASM("msr psp, r0");
}
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
static uint32_t __get_MSP(void)
{
__ASM("mrs r0, msp");
}
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
static void __set_MSP(uint32_t topOfMainStack)
{
__ASM("msr msp, r0");
}
/* intrinsic unsigned long __get_PRIMASK( void ); (see intrinsic.h) */
/* intrinsic void __set_PRIMASK( unsigned long ); (see intrinsic.h) */
#if (__CORTEX_M >= 0x03)
/** \brief Enable FIQ
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
static __INLINE void __enable_fault_irq(void)
{
__ASM ("cpsie f");
}
/** \brief Disable FIQ
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
static __INLINE void __disable_fault_irq(void)
{
__ASM ("cpsid f");
}
/* intrinsic unsigned long __get_BASEPRI( void ); (see intrinsic.h) */
/* intrinsic void __set_BASEPRI( unsigned long ); (see intrinsic.h) */
/* intrinsic unsigned long __get_FAULTMASK( void ); (see intrinsic.h) */
/* intrinsic void __set_FAULTMASK(unsigned long); (see intrinsic.h) */
#endif /* (__CORTEX_M >= 0x03) */
#if (__CORTEX_M == 0x04)
/** \brief Get FPSCR
This function returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
static uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1)
__ASM("vmrs r0, fpscr");
#else
return(0);
#endif
}
/** \brief Set FPSCR
This function assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
static void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1)
__ASM("vmsr fpscr, r0");
#endif
}
#endif /* (__CORTEX_M == 0x04) */
#pragma diag_default=Pe940
#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/** \brief Enable IRQ Interrupts
This function enables IRQ interrupts by clearing the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) static __INLINE void __enable_irq(void)
{
__ASM volatile ("cpsie i");
}
/** \brief Disable IRQ Interrupts
This function disables IRQ interrupts by setting the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) static __INLINE void __disable_irq(void)
{
__ASM volatile ("cpsid i");
}
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_CONTROL(void)
{
uint32_t result;
__ASM volatile ("MRS %0, control" : "=r" (result) );
return(result);
}
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_CONTROL(uint32_t control)
{
__ASM volatile ("MSR control, %0" : : "r" (control) );
}
/** \brief Get ISPR Register
This function returns the content of the ISPR Register.
\return ISPR Register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_IPSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, ipsr" : "=r" (result) );
return(result);
}
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_APSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, apsr" : "=r" (result) );
return(result);
}
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_xPSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, xpsr" : "=r" (result) );
return(result);
}
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_PSP(void)
{
register uint32_t result;
__ASM volatile ("MRS %0, psp\n" : "=r" (result) );
return(result);
}
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_PSP(uint32_t topOfProcStack)
{
__ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) );
}
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_MSP(void)
{
register uint32_t result;
__ASM volatile ("MRS %0, msp\n" : "=r" (result) );
return(result);
}
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_MSP(uint32_t topOfMainStack)
{
__ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) );
}
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_PRIMASK(void)
{
uint32_t result;
__ASM volatile ("MRS %0, primask" : "=r" (result) );
return(result);
}
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_PRIMASK(uint32_t priMask)
{
__ASM volatile ("MSR primask, %0" : : "r" (priMask) );
}
#if (__CORTEX_M >= 0x03)
/** \brief Enable FIQ
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) static __INLINE void __enable_fault_irq(void)
{
__ASM volatile ("cpsie f");
}
/** \brief Disable FIQ
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) static __INLINE void __disable_fault_irq(void)
{
__ASM volatile ("cpsid f");
}
/** \brief Get Base Priority
This function returns the current value of the Base Priority register.
\return Base Priority register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_BASEPRI(void)
{
uint32_t result;
__ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
return(result);
}
/** \brief Set Base Priority
This function assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_BASEPRI(uint32_t value)
{
__ASM volatile ("MSR basepri, %0" : : "r" (value) );
}
/** \brief Get Fault Mask
This function returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_FAULTMASK(void)
{
uint32_t result;
__ASM volatile ("MRS %0, faultmask" : "=r" (result) );
return(result);
}
/** \brief Set Fault Mask
This function assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_FAULTMASK(uint32_t faultMask)
{
__ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) );
}
#endif /* (__CORTEX_M >= 0x03) */
#if (__CORTEX_M == 0x04)
/** \brief Get FPSCR
This function returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1)
uint32_t result;
__ASM volatile ("MRS %0, fpscr" : "=r" (result) );
return(result);
#else
return(0);
#endif
}
/** \brief Set FPSCR
This function assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1)
__ASM volatile ("MSR fpscr, %0" : : "r" (fpscr) );
#endif
}
#endif /* (__CORTEX_M == 0x04) */
#elif (defined (__TASKING__)) /*--------------- TASKING Compiler -----------------*/
/* TASKING carm specific functions */
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all instrinsics,
* Including the CMSIS ones.
*/
#endif
/*@} end of CMSIS_Core_RegAccFunctions */
#endif /* __CORE_CMFUNC_H__ */
@@ -0,0 +1,776 @@
/**************************************************************************//**
* @file core_cmInstr.h
* @brief CMSIS Cortex-M Core Instruction Access Header File
* @version V2.01
* @date 06. December 2010
*
* @note
* Copyright (C) 2009-2010 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __CORE_CMINSTR_H__
#define __CORE_CMINSTR_H__
/* ########################## Core Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
Access to dedicated instructions
@{
*/
#if defined ( __CC_ARM ) /*------------------ RealView Compiler ----------------*/
/* ARM armcc specific functions */
/** \brief No Operation
No Operation does nothing. This instruction can be used for code alignment purposes.
*/
#define __NOP __nop
/** \brief Wait For Interrupt
Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
#define __WFI __wfi
/** \brief Wait For Event
Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
#define __WFE __wfe
/** \brief Send Event
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
#define __SEV __sev
/** \brief Instruction Synchronization Barrier
Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or
memory, after the instruction has been completed.
*/
#define __ISB() __isb(0xF)
/** \brief Data Synchronization Barrier
This function acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
#define __DSB() __dsb(0xF)
/** \brief Data Memory Barrier
This function ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
#define __DMB() __dmb(0xF)
/** \brief Reverse byte order (32 bit)
This function reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __REV __rev
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
#if (__ARMCC_VERSION < 400677)
extern uint32_t __REV16(uint32_t value);
#else /* (__ARMCC_VERSION >= 400677) */
static __INLINE __ASM uint32_t __REV16(uint32_t value)
{
rev16 r0, r0
bx lr
}
#endif /* __ARMCC_VERSION */
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
#if (__ARMCC_VERSION < 400677)
extern int32_t __REVSH(int32_t value);
#else /* (__ARMCC_VERSION >= 400677) */
static __INLINE __ASM int32_t __REVSH(int32_t value)
{
revsh r0, r0
bx lr
}
#endif /* __ARMCC_VERSION */
#if (__CORTEX_M >= 0x03)
/** \brief Reverse bit order of value
This function reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __RBIT __rbit
/** \brief LDR Exclusive (8 bit)
This function performs a exclusive LDR command for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
/** \brief LDR Exclusive (16 bit)
This function performs a exclusive LDR command for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
/** \brief LDR Exclusive (32 bit)
This function performs a exclusive LDR command for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
/** \brief STR Exclusive (8 bit)
This function performs a exclusive STR command for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXB(value, ptr) __strex(value, ptr)
/** \brief STR Exclusive (16 bit)
This function performs a exclusive STR command for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXH(value, ptr) __strex(value, ptr)
/** \brief STR Exclusive (32 bit)
This function performs a exclusive STR command for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXW(value, ptr) __strex(value, ptr)
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
#if (__ARMCC_VERSION < 400000)
extern void __CLREX(void);
#else /* (__ARMCC_VERSION >= 400000) */
#define __CLREX __clrex
#endif /* __ARMCC_VERSION */
/** \brief Signed Saturate
This function saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT __ssat
/** \brief Unsigned Saturate
This function saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT __usat
/** \brief Count leading zeros
This function counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
#define __CLZ __clz
#endif /* (__CORTEX_M >= 0x03) */
#elif (defined (__ICCARM__)) /*---------------- ICC Compiler ---------------------*/
/* IAR iccarm specific functions */
#include <intrinsics.h> /* IAR Intrinsics */
#pragma diag_suppress=Pe940
/** \brief No Operation
No Operation does nothing. This instruction can be used for code alignment purposes.
*/
#define __NOP __no_operation
/** \brief Wait For Interrupt
Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
static __INLINE void __WFI(void)
{
__ASM ("wfi");
}
/** \brief Wait For Event
Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
static __INLINE void __WFE(void)
{
__ASM ("wfe");
}
/** \brief Send Event
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
static __INLINE void __SEV(void)
{
__ASM ("sev");
}
/* intrinsic void __ISB(void) (see intrinsics.h) */
/* intrinsic void __DSB(void) (see intrinsics.h) */
/* intrinsic void __DMB(void) (see intrinsics.h) */
/* intrinsic uint32_t __REV(uint32_t value) (see intrinsics.h) */
/* intrinsic __SSAT (see intrinsics.h) */
/* intrinsic __USAT (see intrinsics.h) */
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
static uint32_t __REV16(uint32_t value)
{
__ASM("rev16 r0, r0");
}
/* intrinsic uint32_t __REVSH(uint32_t value) (see intrinsics.h */
#if (__CORTEX_M >= 0x03)
/** \brief Reverse bit order of value
This function reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
static uint32_t __RBIT(uint32_t value)
{
__ASM("rbit r0, r0");
}
/** \brief LDR Exclusive (8 bit)
This function performs a exclusive LDR command for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
static uint8_t __LDREXB(volatile uint8_t *addr)
{
__ASM("ldrexb r0, [r0]");
}
/** \brief LDR Exclusive (16 bit)
This function performs a exclusive LDR command for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
static uint16_t __LDREXH(volatile uint16_t *addr)
{
__ASM("ldrexh r0, [r0]");
}
/** \brief LDR Exclusive (32 bit)
This function performs a exclusive LDR command for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
/* intrinsic unsigned long __LDREX(unsigned long *) (see intrinsics.h) */
static uint32_t __LDREXW(volatile uint32_t *addr)
{
__ASM("ldrex r0, [r0]");
}
/** \brief STR Exclusive (8 bit)
This function performs a exclusive STR command for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
static uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
{
__ASM("strexb r0, r0, [r1]");
}
/** \brief STR Exclusive (16 bit)
This function performs a exclusive STR command for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
static uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
{
__ASM("strexh r0, r0, [r1]");
}
/** \brief STR Exclusive (32 bit)
This function performs a exclusive STR command for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
/* intrinsic unsigned long __STREX(unsigned long, unsigned long) (see intrinsics.h )*/
static uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
{
__ASM("strex r0, r0, [r1]");
}
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
static __INLINE void __CLREX(void)
{
__ASM ("clrex");
}
/* intrinsic unsigned char __CLZ( unsigned long ) (see intrinsics.h) */
#endif /* (__CORTEX_M >= 0x03) */
#pragma diag_default=Pe940
#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/** \brief No Operation
No Operation does nothing. This instruction can be used for code alignment purposes.
*/
__attribute__( ( always_inline ) ) static __INLINE void __NOP(void)
{
__ASM volatile ("nop");
}
/** \brief Wait For Interrupt
Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
__attribute__( ( always_inline ) ) static __INLINE void __WFI(void)
{
__ASM volatile ("wfi");
}
/** \brief Wait For Event
Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
__attribute__( ( always_inline ) ) static __INLINE void __WFE(void)
{
__ASM volatile ("wfe");
}
/** \brief Send Event
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
__attribute__( ( always_inline ) ) static __INLINE void __SEV(void)
{
__ASM volatile ("sev");
}
/** \brief Instruction Synchronization Barrier
Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or
memory, after the instruction has been completed.
*/
__attribute__( ( always_inline ) ) static __INLINE void __ISB(void)
{
__ASM volatile ("isb");
}
/** \brief Data Synchronization Barrier
This function acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
__attribute__( ( always_inline ) ) static __INLINE void __DSB(void)
{
__ASM volatile ("dsb");
}
/** \brief Data Memory Barrier
This function ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
__attribute__( ( always_inline ) ) static __INLINE void __DMB(void)
{
__ASM volatile ("dmb");
}
/** \brief Reverse byte order (32 bit)
This function reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __REV(uint32_t value)
{
uint32_t result;
__ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __REV16(uint32_t value)
{
uint32_t result;
__ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) static __INLINE int32_t __REVSH(int32_t value)
{
uint32_t result;
__ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
#if (__CORTEX_M >= 0x03)
/** \brief Reverse bit order of value
This function reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __RBIT(uint32_t value)
{
uint32_t result;
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief LDR Exclusive (8 bit)
This function performs a exclusive LDR command for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
__attribute__( ( always_inline ) ) static __INLINE uint8_t __LDREXB(volatile uint8_t *addr)
{
uint8_t result;
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/** \brief LDR Exclusive (16 bit)
This function performs a exclusive LDR command for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
__attribute__( ( always_inline ) ) static __INLINE uint16_t __LDREXH(volatile uint16_t *addr)
{
uint16_t result;
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/** \brief LDR Exclusive (32 bit)
This function performs a exclusive LDR command for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __LDREXW(volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/** \brief STR Exclusive (8 bit)
This function performs a exclusive STR command for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
{
uint32_t result;
__ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
return(result);
}
/** \brief STR Exclusive (16 bit)
This function performs a exclusive STR command for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
{
uint32_t result;
__ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
return(result);
}
/** \brief STR Exclusive (32 bit)
This function performs a exclusive STR command for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
return(result);
}
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
__attribute__( ( always_inline ) ) static __INLINE void __CLREX(void)
{
__ASM volatile ("clrex");
}
/** \brief Signed Saturate
This function saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
/** \brief Unsigned Saturate
This function saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
/** \brief Count leading zeros
This function counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
__attribute__( ( always_inline ) ) static __INLINE uint8_t __CLZ(uint32_t value)
{
uint8_t result;
__ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
#endif /* (__CORTEX_M >= 0x03) */
#elif (defined (__TASKING__)) /*--------------- TASKING Compiler -----------------*/
/* TASKING carm specific functions */
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all instrinsics,
* Including the CMSIS ones.
*/
#endif
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
#endif /* __CORE_CMINSTR_H__ */
@@ -0,0 +1,139 @@
#ifndef _XC_DRV_CONFIG_H_
#define _XC_DRV_CONFIG_H_
#include <stdint.h>
#ifndef ADC_OFF
#define ADC_ON 1
#else
#define ADC_ON 0
#endif
#ifndef AOTIMER_OFF
#define AOTIMER_ON 1
#else
#define AOTIMER_ON 0
#endif
#ifndef CALIB_OFF
#define CALIB_ON 1
#else
#define CALIB_ON 0
#endif
#ifndef DMA_OFF
#define DMA_ON 1
#else
#define DMA_ON 0
#endif
#ifndef FMC_SPI_OFF
#define FMC_SPI_ON 1
#else
#define FMC_SPI_ON 0
#endif
#ifndef FMC_SPI_DMA_OFF
#define FMC_SPI_DMA_ON 1
#else
#define FMC_SPI_DMA_ON 0
#endif
#ifndef GPIO_OFF
#define GPIO_ON 1
#else
#define GPIO_ON 0
#endif
#ifndef I2C_OFF
#define I2C_ON 1
#else
#define I2C_ON 0
#endif
#ifndef PGA_OFF
#define PGA_ON 1
#else
#define PGA_ON 0
#endif
#ifndef PWM_OFF
#define PWM_ON 1
#else
#define PWM_ON 0
#endif
#ifndef PWR_OFF
#define PWR_ON 1
#else
#define PWR_ON 0
#endif
#ifndef QDEC_OFF
#define QDEC_ON 1
#else
#define QDEC_ON 0
#endif
#ifndef RTC_OFF
#define RTC_ON 1
#else
#define RTC_ON 0
#endif
#ifndef SPI_OFF
#define SPI_ON 1
#else
#define SPI_ON 0
#endif
#ifndef SPI_DMA_OFF
#define SPI_DMA_ON 1
#else
#define SPI_DMA_ON 0
#endif
#ifndef SW_I2C_OFF
#define SW_I2C_ON 1
#else
#define SW_I2C_ON 0
#endif
#ifndef TIMER_OFF
#define TIMER_ON 1
#else
#define TIMER_ON 0
#endif
#ifndef UART_OFF
#define UART_ON 1
#else
#define UART_ON 0
#endif
#ifndef UART_DMA_OFF
#define UART_DMA_ON 1
#else
#define UART_DMA_ON 0
#endif
#ifndef WDT_OFF
#define WDT_ON 1
#else
#define WDT_ON 0
#endif
#endif // _XC_DRV_CONFIG_H_
@@ -0,0 +1,234 @@
;/*****************************************************************************
; * @file: startup_xinc.s
; * @purpose: CMSIS Cortex-M0 Core Device Startup File for the
; * Device xinc.
; *****************************************************************************/
Stack_Size EQU 0x00000600
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp
Heap_Size EQU 0x00000000
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
PRESERVE8
THUMB
; Vector Table Mapped to Address 0 at Reset
AREA RESET, DATA, READONLY
EXPORT __Vectors
EXPORT __Vectors_End
EXPORT __Vectors_Size
__Vectors DCD __initial_sp ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD MemManage_Handler ; MPU Fault Handler
DCD BusFault_Handler ; Bus Fault Handler
DCD UsageFault_Handler ; Usage Fault Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD DebugMon_Handler ; Debug Monitor Handler
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
; External Interrupts
; ToDo: Add here the vectors for the device specific external interrupts handler
DCD 0 ; 0 BLE Handler
DCD DMAS_Handler ; 1
DCD CPR_Handler ; 2
DCD GPIO_Handler ; 3
DCD RTC_Handler ; 4
DCD TIMER0_Handler ; 5
DCD TIMER1_Handler
DCD TIMER2_Handler
DCD TIMER3_Handler
DCD WDT_Handler
DCD I2C_Handler
DCD UART0_Handler
DCD UART1_Handler
DCD SPI0_Handler
DCD SPI1_Handler
DCD 0
DCD 0
DCD GADC_Handler ; 17
DCD 0 ; 18
DCD 0 ; 19
DCD 0 ; 20
DCD 0 ; 21
DCD SUB1G_Handler ; 22
DCD PWM_Handler ; 23
DCD BOR_Handler ; 24
DCD 0 ; 25
DCD 0 ; 26
DCD AOTIMER0_Handler ; 27
DCD AOTIMER1_Handler ; 28
DCD CMP_Handler ; 29
DCD FMC_Handler ; 30
DCD CAN_Handler ; 31
__Vectors_End
__Vectors_Size EQU __Vectors_End - __Vectors
AREA |.text|, CODE, READONLY
; Reset Handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
LDR r0, =0x4000013C ; remap
LDR r1, =0x10000001
STR r1, [r0]
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
; Dummy Exception Handlers (infinite loops which can be modified)
NMI_Handler PROC
EXPORT NMI_Handler [WEAK]
B .
ENDP
HardFault_Handler\
PROC
EXPORT HardFault_Handler [WEAK]
B .
ENDP
MemManage_Handler\
PROC
EXPORT MemManage_Handler [WEAK]
B .
ENDP
BusFault_Handler\
PROC
EXPORT BusFault_Handler [WEAK]
B .
ENDP
UsageFault_Handler\
PROC
EXPORT UsageFault_Handler [WEAK]
B .
ENDP
SVC_Handler PROC
EXPORT SVC_Handler [WEAK]
B .
ENDP
DebugMon_Handler\
PROC
EXPORT DebugMon_Handler [WEAK]
B .
ENDP
Default_Handler PROC
;EXPORT BLE_Handler [WEAK]
EXPORT DMAS_Handler [WEAK]
EXPORT CPR_Handler [WEAK]
EXPORT GPIO_Handler [WEAK]
EXPORT RTC_Handler [WEAK]
EXPORT TIMER0_Handler [WEAK]
EXPORT TIMER1_Handler [WEAK]
EXPORT TIMER2_Handler [WEAK]
EXPORT TIMER3_Handler [WEAK]
EXPORT WDT_Handler [WEAK]
EXPORT I2C_Handler [WEAK]
EXPORT UART0_Handler [WEAK]
EXPORT UART1_Handler [WEAK]
EXPORT SPI0_Handler [WEAK]
EXPORT SPI1_Handler [WEAK]
;EXPORT KBS_Handler [WEAK]
;EXPORT QDEC_Handler [WEAK]
EXPORT GADC_Handler [WEAK]
EXPORT AOTIMER0_Handler [WEAK]
EXPORT AOTIMER1_Handler [WEAK]
EXPORT CMP_Handler [WEAK]
EXPORT FMC_Handler [WEAK]
EXPORT CAN_Handler [WEAK]
;EXPORT SIM_Handler [WEAK]
;EXPORT AES_Handler [WEAK]
EXPORT PendSV_Handler [WEAK]
EXPORT SysTick_Handler [WEAK]
EXPORT SUB1G_Handler [WEAK]
EXPORT PWM_Handler [WEAK]
EXPORT BOR_Handler [WEAK]
PendSV_Handler
SysTick_Handler
;BLE_Handler
DMAS_Handler
CPR_Handler
GPIO_Handler
RTC_Handler
TIMER0_Handler
TIMER1_Handler
TIMER2_Handler
TIMER3_Handler
WDT_Handler
I2C_Handler
UART0_Handler
UART1_Handler
SPI0_Handler
SPI1_Handler
;KBS_Handler
;QDEC_Handler
GADC_Handler
;SIM_Handler
;AES_Handler
AOTIMER0_Handler
AOTIMER1_Handler
CMP_Handler
FMC_Handler
CAN_Handler
SUB1G_Handler
PWM_Handler
BOR_Handler
B .
ENDP
ALIGN
; User Initial Stack & Heap
IMPORT __use_two_region_memory
EXPORT __user_initial_stackheap
__user_initial_stackheap
LDR R0, = Heap_Mem
LDR R1, = (Stack_Mem + Stack_Size)
LDR R2, = (Heap_Mem + Heap_Size)
LDR R3, = Stack_Mem
BX LR
ALIGN
END
@@ -0,0 +1,231 @@
/*!
* \file system_it_xinc.c
*
* \brief Target system interruption implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "system_it_xinc.h"
/*------------------------------------------------------------------------------------
Func Prototype
-------------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------------
Functions
-------------------------------------------------------------------------------------*/
/**
****************************************************************************************
* @brief This function handles NMI exception.
*
* @param[in]
* @param[in]
****************************************************************************************
*/
void NMI_Handler(void)
{
/* USER CODE BEGIN NonMaskableInt_IRQn */
DEBUG("%s\n", __func__);
/* USER CODE END NonMaskableInt_IRQn */
while (1)
{
}
}
/**
****************************************************************************************
* @brief This function handles Hard Fault exception.
*
* @param[in]
* @param[in]
****************************************************************************************
*/
void HardFault_Handler(void)
{
/* USER CODE BEGIN HardFault_IRQn */
DEBUG("%s\n", __func__);
/* USER CODE END HardFault_IRQn */
while (1)
{
}
}
/**
****************************************************************************************
* @brief This function handles Memory Manage exception.
*
* @param[in]
* @param[in]
****************************************************************************************
*/
void MemManage_Handler(void)
{
/* USER CODE BEGIN */
DEBUG("%s\n", __func__);
/* USER CODE END */
while (1)
{
}
}
/**
****************************************************************************************
* @brief This function handles Bus Fault exception.
*
* @param[in]
* @param[in]
****************************************************************************************
*/
void BusFault_Handler(void)
{
/* USER CODE BEGIN */
DEBUG("%s\n", __func__);
/* USER CODE END */
while (1)
{
}
}
/**
****************************************************************************************
* @brief This function handles Usage Fault exception.
*
* @param[in]
* @param[in]
****************************************************************************************
*/
void UsageFault_Handler(void)
{
/* USER CODE BEGIN */
DEBUG("%s\n", __func__);
/* USER CODE END */
while (1)
{
}
}
/**
****************************************************************************************
* @brief This function handles SVCall exception.
*
* @param[in]
* @param[in]
****************************************************************************************
*/
void SVC_Handler(void)
{
/* USER CODE BEGIN SVCall_IRQn */
DEBUG("%s\n", __func__);
/* USER CODE END SVCall_IRQn */
while (1)
{
}
}
/**
****************************************************************************************
* @brief This function handles Debug Monitor exception.
*
* @param[in]
* @param[in]
****************************************************************************************
*/
void DebugMon_Handler(void)
{
/* USER CODE BEGIN */
DEBUG("%s\n", __func__);
/* USER CODE END */
while (1)
{
}
}
/**
****************************************************************************************
* @brief This function handles PendSVC exception.
*
* @param[in]
* @param[in]
****************************************************************************************
*/
void PendSV_Handler(void)
{
/* USER CODE BEGIN PendSV_IRQn */
DEBUG("%s\n", __func__);
/* USER CODE END PendSV_IRQn */
while (1)
{
}
}
/****************************** Hard Fault Handler Functions *******************************/
/*------------------------------------------------------------------------------------
Private Functions
-------------------------------------------------------------------------------------*/
void HardFault_Handler_c(unsigned int * HardFault_args)
{
/*栈帧里面内容:*/
unsigned int stack_r0; //压栈的 R0
unsigned int stack_r1; //压栈的 R1
unsigned int stack_r2; //压栈的 R2
unsigned int stack_r3; //压栈的 R3
unsigned int stack_r12; //压栈的 R12
unsigned int stack_lr; //压栈的 lr
unsigned int stack_pc; //压栈的 pc
unsigned int stack_psr; //压栈的 psr
stack_r0 = ((unsigned int)HardFault_args[0]);
stack_r1 = ((unsigned int)HardFault_args[1]);
stack_r2 = ((unsigned int)HardFault_args[2]);
stack_r3 = ((unsigned int)HardFault_args[3]);
stack_r12 = ((unsigned int)HardFault_args[4]);
stack_lr = ((unsigned int)HardFault_args[5]);
stack_pc = ((unsigned int)HardFault_args[6]);
stack_psr = ((unsigned int)HardFault_args[7]);
DEBUG("----%s----\n", __func__);
DEBUG("R0=%x\n",stack_r0);
DEBUG("R1=%x\n",stack_r1);
DEBUG("R2=%x\n",stack_r2);
DEBUG("R3=%x\n",stack_r3);
DEBUG("R12=%x\n",stack_r12);
DEBUG("LR[R14]=%x\n",stack_lr);
DEBUG("PC[R15]=%x\n",stack_pc);
DEBUG("PSR=%x\n",stack_psr);
DEBUG("SCB_SHCSR=%x\n",SCB->SHCSR);
DEBUG("---------------------------\n");
while(1);
}
/*******************************************************************************************/
@@ -0,0 +1,56 @@
/*!
* \file system_it_xinc.h
*
* \brief The header of system_it_xinc.c
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __SYSTEM_IT_XINC_H__
#define __SYSTEM_IT_XINC_H__
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "xc6xxx.h"
/*------------------------------------------------------------------------------------
Exported Functions
-------------------------------------------------------------------------------------*/
void NMI_Handler(void);
void HardFault_Handler(void);
void MemManage_Handler(void);
void BusFault_Handler(void);
void UsageFault_Handler(void);
void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
void HardFault_Handler_c(unsigned int *HardFault_args);
#ifdef __cplusplus
}
#endif
#endif /* __SYSTEM_IT_XINC_H__ */
@@ -0,0 +1,108 @@
/**
* Initialize the system
*
* @param none
* @return none
*
* @brief Setup the microcontroller system
*
*/
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include <stdio.h>
#include "xc6xxx.h"
/*------------------------------------------------------------------------------------
Macros
-------------------------------------------------------------------------------------*/
#define __DEBUG_OUT_PORT 0
/*------------------------------------------------------------------------------------
Functions
-------------------------------------------------------------------------------------*/
#define VECTOR_NUM 48
void set_vector(void)
{
#if (USE_XIP == 1)
__disable_irq();
for (uint32_t i = 0, *Pvector = (uint32_t *)(0x11001000 + 0),
*_vector_table = (uint32_t *)(0x10000000);
i < VECTOR_NUM; i++) // copy vertor table
{
_vector_table[i] = *Pvector++;
}
*((volatile unsigned int *)(0x4000013C)) =
0x10000001; // inter vertor table remap
__enable_irq();
#endif
}
static void WDT_ResetInit(void)
{
//cpr_ctlapbclken_grctl__wdt_pclk_en__setf(DISABLE);
cpr_rstctl_ctlapb_sw__wdt_rstn__setf(RSTCTL_ENABLE);
cpr_rstctl_ctlapb_sw__wdt_rstn__setf(RSTCTL_DISABLE);
}
void SystemInit(void)
{
WDT_ResetInit();
#if (USE_XIP == 1)
set_vector();
#endif
}
__RAM_CODE int sendchar(int c)
{
unsigned int status;
#if (__DEBUG_OUT_PORT == 1)
for (;;) {
status = (*((volatile unsigned *)(0x40011000 + 0x14)));
status &= 0x20;
if (status == 0x20)
break;
}
(*((volatile unsigned *)(0x40011000 + 0x00))) = c;
return (1);
#else
for (;;) {
status = (*((volatile unsigned *)(0x40010000 + 0x14)));
status &= 0x20;
if (status == 0x20)
break;
}
(*((volatile unsigned *)(0x40010000 + 0x00))) = c;
return (1);
#endif
}
struct __FILE
{
int handle; /* Add whatever you need here */
};
FILE __stdout;
__RAM_CODE int fputc(int ch, FILE *f) { return (sendchar(ch)); }
int ferror(FILE *f)
{
/* Your implementation of ferror */
return EOF;
}
void _ttywrch(int ch) { sendchar(ch); }
void _sys_exit(int return_code)
{
label:
goto label; /* endless loop */
}
@@ -0,0 +1,257 @@
;/*****************************************************************************
; * @file: startup_xinc.s
; * @purpose: CMSIS Cortex-M0 Core Device Startup File for the
; * Device xinc.
; *****************************************************************************/
Stack_Size EQU 0x00001000
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp
Heap_Size EQU 0x00000000
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
PRESERVE8
THUMB
; Vector Table Mapped to Address 0 at Reset
AREA RESET, DATA, READONLY
EXPORT __Vectors
EXPORT __Vectors_End
EXPORT __Vectors_Size
__Vectors DCD __initial_sp ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD MemManage_Handler ; MPU Fault Handler
DCD BusFault_Handler ; Bus Fault Handler
DCD UsageFault_Handler ; Usage Fault Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD DebugMon_Handler ; Debug Monitor Handler
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
; External Interrupts
; ToDo: Add here the vectors for the device specific external interrupts handler
DCD BLE_Handler ; 0
DCD DMA_Handler ; 1
DCD CPR_Handler ; 2
DCD GPIO_Handler ; 3
DCD RTC_Handler ; 4
DCD TIMER0_Handler ; 5
DCD TIMER1_Handler ; 6
DCD TIMER2_Handler ; 7
DCD TIMER3_Handler ; 8
DCD WDT_Handler ; 9
DCD I2C_Handler ; 10
DCD UART0_Handler ; 11
DCD UART1_Handler ; 12
DCD SPI0_Handler ; 13
DCD SPI1_Handler ; 14
DCD 0 ; 15
DCD 0 ; 16
DCD GADC_Handler ; 17
DCD PWM_Handler ; 18
DCD AES_Handler ; 19
DCD USB_Handler ; 20
DCD AUDIO_Handler ; 21
DCD RF24G_Handler ; 22
DCD SPI2_Handler ; 23
DCD MPU_Handler ; 24
DCD UART2_Handler ; 25
DCD I2S_Handler ; 26
DCD AOTIMER0_Handler ; 27
DCD AOTIMER1_Handler ; 28
DCD CMP_Handler ; 29
DCD FMC_Handler ; 30
DCD CAN_Handler ; 31
__Vectors_End
__Vectors_Size EQU __Vectors_End - __Vectors
AREA |.text|, CODE, READONLY
; Reset Handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
LDR r0, =0x4000013C ; remap
LDR r1, =0x10000001
STR r1, [r0]
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
; Dummy Exception Handlers (infinite loops which can be modified)
NMI_Handler PROC
EXPORT NMI_Handler [WEAK]
B .
ENDP
HardFault_Handler\
PROC
IMPORT HardFault_Handler_c ;函数声明
movs r0, #4 ;判断主栈指针还是进程栈指针
mov r1, lr
tst r0, r1
beq hf_used_msp ;如果是主栈指针
mrs r0, psp ;否则是进程栈指针,把进程栈指针地址付给 R0
ldr r1, =HardFault_Handler_c ;跳转到 HardFault 中断程序
bx r1
hf_used_msp
mrs r0, msp ;把主栈指针地址赋给 R0
ldr r1, =HardFault_Handler_c
bx r1
;EXPORT HardFault_Handler [WEAK]
;B .
ENDP
MemManage_Handler\
PROC
EXPORT MemManage_Handler [WEAK]
B .
ENDP
BusFault_Handler\
PROC
EXPORT BusFault_Handler [WEAK]
B .
ENDP
UsageFault_Handler\
PROC
EXPORT UsageFault_Handler [WEAK]
B .
ENDP
SVC_Handler PROC
EXPORT SVC_Handler [WEAK]
B .
ENDP
DebugMon_Handler\
PROC
EXPORT DebugMon_Handler [WEAK]
B .
ENDP
Default_Handler PROC
EXPORT BLE_Handler [WEAK]
EXPORT DMA_Handler [WEAK]
EXPORT CPR_Handler [WEAK]
EXPORT GPIO_Handler [WEAK]
EXPORT RTC_Handler [WEAK]
EXPORT TIMER0_Handler [WEAK]
EXPORT TIMER1_Handler [WEAK]
EXPORT TIMER2_Handler [WEAK]
EXPORT TIMER3_Handler [WEAK]
EXPORT WDT_Handler [WEAK]
EXPORT I2C_Handler [WEAK]
EXPORT UART0_Handler [WEAK]
EXPORT UART1_Handler [WEAK]
EXPORT SPI0_Handler [WEAK]
EXPORT SPI1_Handler [WEAK]
;EXPORT KBS_Handler [WEAK]
;EXPORT QDEC_Handler [WEAK]
EXPORT GADC_Handler [WEAK]
EXPORT PWM_Handler [WEAK]
EXPORT AES_Handler [WEAK]
EXPORT PendSV_Handler [WEAK]
EXPORT SysTick_Handler [WEAK]
EXPORT USB_Handler [WEAK];20
EXPORT AUDIO_Handler [WEAK];21
EXPORT RF24G_Handler [WEAK];22
EXPORT SPI2_Handler [WEAK];23
EXPORT MPU_Handler [WEAK];24
EXPORT UART2_Handler [WEAK];25
EXPORT I2S_Handler [WEAK];26
EXPORT AOTIMER0_Handler [WEAK];27
EXPORT AOTIMER1_Handler [WEAK];28
EXPORT CMP_Handler [WEAK];29
EXPORT FMC_Handler [WEAK];30
EXPORT CAN_Handler [WEAK];31
PendSV_Handler
SysTick_Handler
BLE_Handler
RF24G_Handler
DMA_Handler
CPR_Handler
GPIO_Handler
RTC_Handler
TIMER0_Handler
TIMER1_Handler
TIMER2_Handler
TIMER3_Handler
WDT_Handler
I2C_Handler
I2S_Handler
UART0_Handler
UART1_Handler
UART2_Handler
SPI0_Handler
SPI1_Handler
SPI2_Handler
MPU_Handler
;KBS_Handler
;QDEC_Handler
GADC_Handler
PWM_Handler
AUDIO_Handler
;SIM_Handler
AES_Handler
AOTIMER0_Handler
AOTIMER1_Handler
CMP_Handler
FMC_Handler
CAN_Handler
USB_Handler
B .
ENDP
ALIGN
; User Initial Stack & Heap
IMPORT __use_two_region_memory
EXPORT __user_initial_stackheap
__user_initial_stackheap
LDR R0, = Heap_Mem
LDR R1, = (Stack_Mem + Stack_Size)
LDR R2, = (Heap_Mem + Heap_Size)
LDR R3, = Stack_Mem
BX LR
ALIGN
END
@@ -0,0 +1,110 @@
/*!
* \file diskio.h
*
* \brief Target disk I/O implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef _DISKIO_DEFINED
#define _DISKIO_DEFINED
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "integer.h"
/*------------------------------------------------------------------------------------
Macros
-------------------------------------------
-----------------------------------------*/
#define _USE_WRITE 1 /* 1: Enable disk_write function */
#define _USE_IOCTL 1 /* 1: Enable disk_ioctl function */
/* Disk Status Bits (DSTATUS) */
#define STA_NOINIT 0x01 /* Drive not initialized */
#define STA_NODISK 0x02 /* No medium in the drive */
#define STA_PROTECT 0x04 /* Write protected */
/* Command code for disk_ioctrl fucntion */
/* Generic command (Used by FatFs) */
#define CTRL_SYNC \
0 /* Complete pending write process (needed at _FS_READONLY == 0) */
#define GET_SECTOR_COUNT 1 /* Get media size (needed at _USE_MKFS == 1) */
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at _MAX_SS != _MIN_SS) */
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at _USE_MKFS == 1) */
#define CTRL_TRIM \
4 /* Inform device that the data on the block of sectors is no longer used \
(needed at _USE_TRIM == 1) */
/* Generic command (Not used by FatFs) */
#define CTRL_POWER 5 /* Get/Set power status */
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
#define CTRL_EJECT 7 /* Eject media */
#define CTRL_FORMAT 8 /* Create physical format on the media */
/* MMC/SDC specific ioctl command */
#define MMC_GET_TYPE 10 /* Get card type */
#define MMC_GET_CSD 11 /* Get CSD */
#define MMC_GET_CID 12 /* Get CID */
#define MMC_GET_OCR 13 /* Get OCR */
#define MMC_GET_SDSTAT 14 /* Get SD status */
/* ATA/CF specific ioctl command */
#define ATA_GET_REV 20 /* Get F/W revision */
#define ATA_GET_MODEL 21 /* Get model name */
#define ATA_GET_SN 22 /* Get serial number */
/*------------------------------------------------------------------------------------
Typedef
------------------------------------------------------------------------------------*/
/* Status of Disk Functions */
typedef BYTE DSTATUS;
/* Results of Disk Functions */
typedef enum {
RES_OK = 0, /* 0: Successful */
RES_ERROR, /* 1: R/W Error */
RES_WRPRT, /* 2: Write Protected */
RES_NOTRDY, /* 3: Not Ready */
RES_PARERR /* 4: Invalid Parameter */
} DRESULT;
/*------------------------------------------------------------------------------------
Exported Functions
-------------------------------------------------------------------------------------*/
DSTATUS disk_initialize(BYTE pdrv);
DSTATUS disk_status(BYTE pdrv);
DRESULT disk_read(BYTE pdrv, BYTE *buff, DWORD sector, UINT count);
DRESULT disk_write(BYTE pdrv, const BYTE *buff, DWORD sector, UINT count);
DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff);
DWORD get_fattime(void);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,55 @@
/*!
* \file fatfs.h
*
* \brief Target FatFS implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __fatfs_H
#define __fatfs_H
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "ff.h"
#include "ff_gen_drv.h"
/*------------------------------------------------------------------------------------
Global Variables
-------------------------------------------------------------------------------------*/
extern char Path[4]; /* USER logical drive path */
extern FATFS FatFS; /* File system object for USER logical drive */
extern FIL File; /* File object for USER */
/*------------------------------------------------------------------------------------
Exported Functions
-------------------------------------------
-----------------------------------------*/
void FATFS_Init(void);
#ifdef __cplusplus
}
#endif
#endif /*__fatfs_H */
@@ -0,0 +1,362 @@
/*----------------------------------------------------------------------------/
/ FatFs - Generic FAT file system module R0.12c /
/-----------------------------------------------------------------------------/
/
/ Copyright (C) 2017, ChaN, all right reserved.
/
/ FatFs module is an open source software. Redistribution and use of FatFs in
/ source and binary forms, with or without modification, are permitted provided
/ that the following condition is met:
/ 1. Redistributions of source code must retain the above copyright notice,
/ this condition and the following disclaimer.
/
/ This software is provided by the copyright holder and contributors "AS IS"
/ and any warranties related to this software are DISCLAIMED.
/ The copyright owner or contributors be NOT LIABLE for any damages caused
/ by use of this software.
/----------------------------------------------------------------------------*/
#ifndef _FF_H
#define _FF_H 68300 /* Revision ID */
#ifdef __cplusplus
extern "C" {
#endif
#include "integer.h" /* Basic integer types */
#include "ffconf.h" /* FatFs configuration options */
#if _FF_H != _FFCONF
#error Wrong configuration file (ffconf.h).
#endif
/* Definitions of volume management */
#if _MULTI_PARTITION /* Multiple partition configuration */
typedef struct {
BYTE pd; /* Physical drive number */
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
} PARTITION;
extern PARTITION VolToPart[]; /* Volume - Partition resolution table */
#endif
/* Type of path name strings on FatFs API */
#if _LFN_UNICODE /* Unicode (UTF-16) string */
#if _USE_LFN == 0
#error _LFN_UNICODE must be 0 at non-LFN cfg.
#endif
#ifndef _INC_TCHAR
typedef WCHAR TCHAR;
#define _T(x) L ## x
#define _TEXT(x) L ## x
#endif
#else /* ANSI/OEM string */
#ifndef _INC_TCHAR
typedef char TCHAR;
#define _T(x) x
#define _TEXT(x) x
#endif
#endif
/* Type of file size variables */
#if _FS_EXFAT
#if _USE_LFN == 0
#error LFN must be enabled when enable exFAT
#endif
typedef QWORD FSIZE_t;
#else
typedef DWORD FSIZE_t;
#endif
/* File system object structure (FATFS) */
typedef struct {
BYTE fs_type; /* File system type (0:N/A) */
BYTE drv; /* Physical drive number */
BYTE n_fats; /* Number of FATs (1 or 2) */
BYTE wflag; /* win[] flag (b0:dirty) */
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
WORD id; /* File system mount ID */
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
WORD csize; /* Cluster size [sectors] */
#if _MAX_SS != _MIN_SS
WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */
#endif
#if _USE_LFN != 0
WCHAR* lfnbuf; /* LFN working buffer */
#endif
#if _FS_EXFAT
BYTE* dirbuf; /* Directory entry block scratchpad buffer */
#endif
#if _FS_REENTRANT
_SYNC_t sobj; /* Identifier of sync object */
#endif
#if !_FS_READONLY
DWORD last_clst; /* Last allocated cluster */
DWORD free_clst; /* Number of free clusters */
#endif
#if _FS_RPATH != 0
DWORD cdir; /* Current directory start cluster (0:root) */
#if _FS_EXFAT
DWORD cdc_scl; /* Containing directory start cluster (invalid when cdir is 0) */
DWORD cdc_size; /* b31-b8:Size of containing directory, b7-b0: Chain status */
DWORD cdc_ofs; /* Offset in the containing directory (invalid when cdir is 0) */
#endif
#endif
DWORD n_fatent; /* Number of FAT entries (number of clusters + 2) */
DWORD fsize; /* Size of an FAT [sectors] */
DWORD volbase; /* Volume base sector */
DWORD fatbase; /* FAT base sector */
DWORD dirbase; /* Root directory base sector/cluster */
DWORD database; /* Data base sector */
DWORD winsect; /* Current sector appearing in the win[] */
BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
} FATFS;
/* Object ID and allocation information (_FDID) */
typedef struct {
FATFS* fs; /* Pointer to the owner file system object */
WORD id; /* Owner file system mount ID */
BYTE attr; /* Object attribute */
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous (no data on FAT), =3:flagmented in this session, b2:sub-directory stretched) */
DWORD sclust; /* Object start cluster (0:no cluster or root directory) */
FSIZE_t objsize; /* Object size (valid when sclust != 0) */
#if _FS_EXFAT
DWORD n_cont; /* Size of first fragment, clusters - 1 (valid when stat == 3) */
DWORD n_frag; /* Size of last fragment needs to be written (valid when not zero) */
DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */
DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */
DWORD c_ofs; /* Offset in the containing directory (valid when sclust != 0 and non-directory object) */
#endif
#if _FS_LOCK != 0
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
#endif
} _FDID;
/* File object structure (FIL) */
typedef struct {
_FDID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */
BYTE flag; /* File status flags */
BYTE err; /* Abort flag (error code) */
FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */
DWORD clust; /* Current cluster of fpter (invalid when fptr is 0) */
DWORD sect; /* Sector number appearing in buf[] (0:invalid) */
#if !_FS_READONLY
DWORD dir_sect; /* Sector number containing the directory entry */
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] */
#endif
#if _USE_FASTSEEK
DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */
#endif
#if !_FS_TINY
BYTE buf[_MAX_SS]; /* File private data read/write window */
#endif
} FIL;
/* Directory object structure (DIR) */
typedef struct {
_FDID obj; /* Object identifier */
DWORD dptr; /* Current read/write offset */
DWORD clust; /* Current cluster */
DWORD sect; /* Current sector (0:Read operation has terminated) */
BYTE* dir; /* Pointer to the directory item in the win[] */
BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */
#if _USE_LFN != 0
DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */
#endif
#if _USE_FIND
const TCHAR* pat; /* Pointer to the name matching pattern */
#endif
} DIR;
/* File information structure (FILINFO) */
typedef struct {
FSIZE_t fsize; /* File size */
WORD fdate; /* Modified date */
WORD ftime; /* Modified time */
BYTE fattrib; /* File attribute */
#if _USE_LFN != 0
TCHAR altname[13]; /* Alternative file name */
TCHAR fname[_MAX_LFN + 1]; /* Primary file name */
#else
TCHAR fname[13]; /* File name */
#endif
} FILINFO;
/* File function return code (FRESULT) */
typedef enum {
FR_OK = 0, /* (0) Succeeded */
FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
FR_INT_ERR, /* (2) Assertion failed */
FR_NOT_READY, /* (3) The physical drive cannot work */
FR_NO_FILE, /* (4) Could not find the file */
FR_NO_PATH, /* (5) Could not find the path */
FR_INVALID_NAME, /* (6) The path name format is invalid */
FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
FR_EXIST, /* (8) Access denied due to prohibited access */
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
FR_NOT_ENABLED, /* (12) The volume has no work area */
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_LOCK */
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
} FRESULT;
/*--------------------------------------------------------------*/
/* FatFs module application interface */
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */
FRESULT f_close (FIL* fp); /* Close an open file object */
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */
FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */
FRESULT f_truncate (FIL* fp); /* Truncate the file */
FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */
FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */
FRESULT f_closedir (DIR* dp); /* Close an open directory */
FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */
FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */
FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */
FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */
FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */
FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of a file/dir */
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change timestamp of a file/dir */
FRESULT f_chdir (const TCHAR* path); /* Change current directory */
FRESULT f_chdrive (const TCHAR* path); /* Change current drive */
FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */
FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
FRESULT f_expand (FIL* fp, FSIZE_t szf, BYTE opt); /* Allocate a contiguous block to the file */
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */
FRESULT f_fdisk (BYTE pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */
int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */
int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))
#define f_error(fp) ((fp)->err)
#define f_tell(fp) ((fp)->fptr)
#define f_size(fp) ((fp)->obj.objsize)
#define f_rewind(fp) f_lseek((fp), 0)
#define f_rewinddir(dp) f_readdir((dp), 0)
#define f_rmdir(path) f_unlink(path)
#define f_unmount(path) f_mount(0, path, 0)
#ifndef EOF
#define EOF (-1)
#endif
/*--------------------------------------------------------------*/
/* Additional user defined functions */
/* RTC function */
#if !_FS_READONLY && !_FS_NORTC
DWORD get_fattime (void);
#endif
/* Unicode support functions */
#if _USE_LFN != 0 /* Unicode - OEM code conversion */
WCHAR ff_convert (WCHAR chr, UINT dir); /* OEM-Unicode bidirectional conversion */
WCHAR ff_wtoupper (WCHAR chr); /* Unicode upper-case conversion */
#if _USE_LFN == 3 /* Memory functions */
void* ff_memalloc (UINT msize); /* Allocate memory block */
void ff_memfree (void* mblock); /* Free memory block */
#endif
#endif
/* Sync functions */
#if _FS_REENTRANT
int ff_cre_syncobj (BYTE vol, _SYNC_t* sobj); /* Create a sync object */
int ff_req_grant (_SYNC_t sobj); /* Lock sync object */
void ff_rel_grant (_SYNC_t sobj); /* Unlock sync object */
int ff_del_syncobj (_SYNC_t sobj); /* Delete a sync object */
#endif
/*--------------------------------------------------------------*/
/* Flags and offset address */
/* File access mode and open method flags (3rd argument of f_open) */
#define FA_READ 0x01
#define FA_WRITE 0x02
#define FA_OPEN_EXISTING 0x00
#define FA_CREATE_NEW 0x04
#define FA_CREATE_ALWAYS 0x08
#define FA_OPEN_ALWAYS 0x10
#define FA_OPEN_APPEND 0x30
/* Fast seek controls (2nd argument of f_lseek) */
#define CREATE_LINKMAP ((FSIZE_t)0 - 1)
/* Format options (2nd argument of f_mkfs) */
#define FM_FAT 0x01
#define FM_FAT32 0x02
#define FM_EXFAT 0x04
#define FM_ANY 0x07
#define FM_SFD 0x08
/* Filesystem type (FATFS.fs_type) */
#define FS_FAT12 1
#define FS_FAT16 2
#define FS_FAT32 3
#define FS_EXFAT 4
/* File attribute bits for directory entry (FILINFO.fattrib) */
#define AM_RDO 0x01 /* Read only */
#define AM_HID 0x02 /* Hidden */
#define AM_SYS 0x04 /* System */
#define AM_DIR 0x10 /* Directory */
#define AM_ARC 0x20 /* Archive */
#ifdef __cplusplus
}
#endif
#endif /* _FATFS */
@@ -0,0 +1,80 @@
/**
******************************************************************************
* @file ff_gen_drv.h
* @author MCD Application Team
* @brief Header for ff_gen_drv.c module.
*****************************************************************************
* @attention
*
* Copyright (c) 2017 STMicroelectronics. All rights reserved.
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
**/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __FF_GEN_DRV_H
#define __FF_GEN_DRV_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "diskio.h"
#include "ff.h"
#include "stdint.h"
/* Exported types ------------------------------------------------------------*/
/**
* @brief Disk IO Driver structure definition
*/
typedef struct
{
DSTATUS (*disk_initialize) (BYTE); /*!< Initialize Disk Drive */
DSTATUS (*disk_status) (BYTE); /*!< Get Disk Status */
DRESULT (*disk_read) (BYTE, BYTE*, DWORD, UINT); /*!< Read Sector(s) */
#if _USE_WRITE == 1
DRESULT (*disk_write) (BYTE, const BYTE*, DWORD, UINT); /*!< Write Sector(s) when _USE_WRITE = 0 */
#endif /* _USE_WRITE == 1 */
#if _USE_IOCTL == 1
DRESULT (*disk_ioctl) (BYTE, BYTE, void*); /*!< I/O control operation when _USE_IOCTL = 1 */
#endif /* _USE_IOCTL == 1 */
}Diskio_drvTypeDef;
/**
* @brief Global Disk IO Drivers structure definition
*/
typedef struct
{
uint8_t is_initialized[_VOLUMES];
const Diskio_drvTypeDef *drv[_VOLUMES];
uint8_t lun[_VOLUMES];
volatile uint8_t nbr;
}Disk_drvTypeDef;
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
uint8_t FATFS_LinkDriver(const Diskio_drvTypeDef *drv, char *path);
uint8_t FATFS_UnLinkDriver(char *path);
uint8_t FATFS_LinkDriverEx(const Diskio_drvTypeDef *drv, char *path, BYTE lun);
uint8_t FATFS_UnLinkDriverEx(char *path, BYTE lun);
uint8_t FATFS_GetAttachedDriversNbr(void);
#ifdef __cplusplus
}
#endif
#endif /* __FF_GEN_DRV_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,267 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* FatFs - Generic FAT file system module R0.12c (C)ChaN, 2017
******************************************************************************
* @attention
*
* Copyright (c) 2022 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
#ifndef _FFCONF
#define _FFCONF 68300 /* Revision ID */
/*-----------------------------------------------------------------------------/
/ Additional user header to be used
/-----------------------------------------------------------------------------*/
//#include "main.h"
//#include "stm32f4xx_hal.h"
/*-----------------------------------------------------------------------------/
/ Function Configurations
/-----------------------------------------------------------------------------*/
#define _FS_READONLY 0 /* 0:Read/Write or 1:Read only */
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
/ and optional writing functions as well. */
#define _FS_MINIMIZE 0 /* 0 to 3 */
/* This option defines minimization level to remove some basic API functions.
/
/ 0: All basic functions are enabled.
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
/ are removed.
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
/ 3: f_lseek() function is removed in addition to 2. */
#define _USE_STRFUNC 2 /* 0:Disable or 1-2:Enable */
/* This option switches string functions, f_gets(), f_putc(), f_puts() and
/ f_printf().
/
/ 0: Disable string functions.
/ 1: Enable without LF-CRLF conversion.
/ 2: Enable with LF-CRLF conversion. */
#define _USE_FIND 0
/* This option switches filtered directory read functions, f_findfirst() and
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
#define _USE_MKFS 1
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
#define _USE_FASTSEEK 1
/* This option switches fast seek feature. (0:Disable or 1:Enable) */
#define _USE_EXPAND 0
/* This option switches f_expand function. (0:Disable or 1:Enable) */
#define _USE_CHMOD 0
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
/ (0:Disable or 1:Enable) Also _FS_READONLY needs to be 0 to enable this option. */
#define _USE_LABEL 1
/* This option switches volume label functions, f_getlabel() and f_setlabel().
/ (0:Disable or 1:Enable) */
#define _USE_FORWARD 0
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
/*-----------------------------------------------------------------------------/
/ Locale and Namespace Configurations
/-----------------------------------------------------------------------------*/
#define _CODE_PAGE 437//850
/* This option specifies the OEM code page to be used on the target system.
/ Incorrect setting of the code page can cause a file open failure.
/
/ 1 - ASCII (No extended character. Non-LFN cfg. only)
/ 437 - U.S.
/ 720 - Arabic
/ 737 - Greek
/ 771 - KBL
/ 775 - Baltic
/ 850 - Latin 1
/ 852 - Latin 2
/ 855 - Cyrillic
/ 857 - Turkish
/ 860 - Portuguese
/ 861 - Icelandic
/ 862 - Hebrew
/ 863 - Canadian French
/ 864 - Arabic
/ 865 - Nordic
/ 866 - Russian
/ 869 - Greek 2
/ 932 - Japanese (DBCS)
/ 936 - Simplified Chinese (DBCS)
/ 949 - Korean (DBCS)
/ 950 - Traditional Chinese (DBCS)
*/
#define _USE_LFN 0 /* 0 to 3 */
#define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */
/* The _USE_LFN switches the support of long file name (LFN).
/
/ 0: Disable support of LFN. _MAX_LFN has no effect.
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
/ 2: Enable LFN with dynamic working buffer on the STACK.
/ 3: Enable LFN with dynamic working buffer on the HEAP.
/
/ To enable the LFN, Unicode handling functions (option/unicode.c) must be added
/ to the project. The working buffer occupies (_MAX_LFN + 1) * 2 bytes and
/ additional 608 bytes at exFAT enabled. _MAX_LFN can be in range from 12 to 255.
/ It should be set 255 to support full featured LFN operations.
/ When use stack for the working buffer, take care on stack overflow. When use heap
/ memory for the working buffer, memory management functions, ff_memalloc() and
/ ff_memfree(), must be added to the project. */
#define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */
/* This option switches character encoding on the API. (0:ANSI/OEM or 1:UTF-16)
/ To use Unicode string for the path name, enable LFN and set _LFN_UNICODE = 1.
/ This option also affects behavior of string I/O functions. */
#define _STRF_ENCODE 3
/* When _LFN_UNICODE == 1, this option selects the character encoding ON THE FILE to
/ be read/written via string I/O functions, f_gets(), f_putc(), f_puts and f_printf().
/
/ 0: ANSI/OEM
/ 1: UTF-16LE
/ 2: UTF-16BE
/ 3: UTF-8
/
/ This option has no effect when _LFN_UNICODE == 0. */
#define _FS_RPATH 0 /* 0 to 2 */
/* This option configures support of relative path.
/
/ 0: Disable relative path and remove related functions.
/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
/ 2: f_getcwd() function is available in addition to 1.
*/
/*---------------------------------------------------------------------------/
/ Drive/Volume Configurations
/----------------------------------------------------------------------------*/
#define _VOLUMES 1
/* Number of volumes (logical drives) to be used. */
/* USER CODE BEGIN Volumes */
#define _STR_VOLUME_ID 0 /* 0:Use only 0-9 for drive ID, 1:Use strings for drive ID */
#define _VOLUME_STRS "RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3"
/* _STR_VOLUME_ID switches string support of volume ID.
/ When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
/ number in the path name. _VOLUME_STRS defines the drive ID strings for each
/ logical drives. Number of items must be equal to _VOLUMES. Valid characters for
/ the drive ID strings are: A-Z and 0-9. */
/* USER CODE END Volumes */
#define _MULTI_PARTITION 0 /* 0:Single partition, 1:Multiple partition */
/* This option switches support of multi-partition on a physical drive.
/ By default (0), each logical drive number is bound to the same physical drive
/ number and only an FAT volume found on the physical drive will be mounted.
/ When multi-partition is enabled (1), each logical drive number can be bound to
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
/ function will be available. */
#define _MIN_SS 512 /* 512, 1024, 2048 or 4096 */
#define _MAX_SS 512//4096 /* 512, 1024, 2048 or 4096 */
/* These options configure the range of sector size to be supported. (512, 1024,
/ 2048 or 4096) Always set both 512 for most systems, all type of memory cards and
/ harddisk. But a larger value may be required for on-board flash memory and some
/ type of optical media. When _MAX_SS is larger than _MIN_SS, FatFs is configured
/ to variable sector size and GET_SECTOR_SIZE command must be implemented to the
/ disk_ioctl() function. */
#define _USE_TRIM 0
/* This option switches support of ATA-TRIM. (0:Disable or 1:Enable)
/ To enable Trim function, also CTRL_TRIM command should be implemented to the
/ disk_ioctl() function. */
#define _FS_NOFSINFO 0 /* 0,1,2 or 3 */
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
/ option, and f_getfree() function at first time after volume mount will force
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
/
/ bit0=0: Use free cluster count in the FSINFO if available.
/ bit0=1: Do not trust free cluster count in the FSINFO.
/ bit1=0: Use last allocated cluster number in the FSINFO if available.
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
*/
/*---------------------------------------------------------------------------/
/ System Configurations
/----------------------------------------------------------------------------*/
#define _FS_TINY 0 /* 0:Normal or 1:Tiny */
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
/ At the tiny configuration, size of file object (FIL) is reduced _MAX_SS bytes.
/ Instead of private sector buffer eliminated from the file object, common sector
/ buffer in the file system object (FATFS) is used for the file data transfer. */
#define _FS_EXFAT 0
/* This option switches support of exFAT file system. (0:Disable or 1:Enable)
/ When enable exFAT, also LFN needs to be enabled. (_USE_LFN >= 1)
/ Note that enabling exFAT discards C89 compatibility. */
#define _FS_NORTC 0
#define _NORTC_MON 6
#define _NORTC_MDAY 4
#define _NORTC_YEAR 2015
/* The option _FS_NORTC switches timestamp functiton. If the system does not have
/ any RTC function or valid timestamp is not needed, set _FS_NORTC = 1 to disable
/ the timestamp function. All objects modified by FatFs will have a fixed timestamp
/ defined by _NORTC_MON, _NORTC_MDAY and _NORTC_YEAR in local time.
/ To enable timestamp function (_FS_NORTC = 0), get_fattime() function need to be
/ added to the project to get current time form real-time clock. _NORTC_MON,
/ _NORTC_MDAY and _NORTC_YEAR have no effect.
/ These options have no effect at read-only configuration (_FS_READONLY = 1). */
#define _FS_LOCK 2 /* 0:Disable or >=1:Enable */
/* The option _FS_LOCK switches file lock function to control duplicated file open
/ and illegal operation to open objects. This option must be 0 when _FS_READONLY
/ is 1.
/
/ 0: Disable file lock function. To avoid volume corruption, application program
/ should avoid illegal open, remove and rename to the open objects.
/ >0: Enable file lock function. The value defines how many files/sub-directories
/ can be opened simultaneously under file lock control. Note that the file
/ lock control is independent of re-entrancy. */
#define _FS_REENTRANT 0 /* 0:Disable or 1:Enable */
#define _FS_TIMEOUT 1000 /* Timeout period in unit of time ticks */
#define _SYNC_t NULL
/* The option _FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
/ module itself. Note that regardless of this option, file access to different
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
/ to the same volume is under control of this function.
/
/ 0: Disable re-entrancy. _FS_TIMEOUT and _SYNC_t have no effect.
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
/ function, must be added to the project. Samples are available in
/ option/syscall.c.
/
/ The _FS_TIMEOUT defines timeout period in unit of time tick.
/ The _SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
/ SemaphoreHandle_t and etc.. A header file for O/S definitions needs to be
/ included somewhere in the scope of ff.h. */
/* define the ff_malloc ff_free macros as standard malloc free */
#if !defined(ff_malloc) && !defined(ff_free)
#include <stdlib.h>
#define ff_malloc malloc
#define ff_free free
#endif
#endif /* _FFCONF */
@@ -0,0 +1,38 @@
/*-------------------------------------------*/
/* Integer type definitions for FatFs module */
/*-------------------------------------------*/
#ifndef _FF_INTEGER
#define _FF_INTEGER
#ifdef _WIN32 /* FatFs development platform */
#include <windows.h>
#include <tchar.h>
typedef unsigned __int64 QWORD;
#else /* Embedded platform */
/* These types MUST be 16-bit or 32-bit */
typedef int INT;
typedef unsigned int UINT;
/* This type MUST be 8-bit */
typedef unsigned char BYTE;
/* These types MUST be 16-bit */
typedef short SHORT;
typedef unsigned short WORD;
typedef unsigned short WCHAR;
/* These types MUST be 32-bit */
typedef long LONG;
typedef unsigned long DWORD;
/* This type MUST be 64-bit (Remove this for ANSI C (C89) compatibility) */
typedef unsigned long long QWORD;
#endif
#endif
@@ -0,0 +1,231 @@
/*!
* \file diskio.c
*
* \brief Target disk I/O implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "diskio.h"
#include "ff_gen_drv.h"
#include "msc_flash.h"
#include "time_conv.h"
/*------------------------------------------------------------------------------------
Macros
-------------------------------------------
-----------------------------------------*/
#if defined(__GNUC__)
#ifndef __weak
#define __weak __attribute__((weak))
#endif
#endif
#define DEV_USB 0 /* Example: Map USB MSD to physical drive 0 */
/*------------------------------------------------------------------------------------
Global Variables
-------------------------------------------
-----------------------------------------*/
extern Disk_drvTypeDef disk;
/*------------------------------------------------------------------------------------
Functions
-------------------------------------------
-----------------------------------------*/
/**
* @brief Gets Disk Status
* @param pdrv: Physical drive number (0..)
* @retval DSTATUS: Operation status
*/
DSTATUS disk_status(BYTE pdrv /* Physical drive number to identify the drive */
)
{
DSTATUS stat = STA_NOINIT;
// stat = disk.drv[pdrv]->disk_status(disk.lun[pdrv]);
if (FAT_FLASH_ID == Fat_Flash_ReadID()) {
stat = RES_OK;
} else {
stat = STA_NOINIT;
}
return stat;
}
/**
* @brief Initializes a Drive
* @param pdrv: Physical drive number (0..)
* @retval DSTATUS: Operation status
*/
DSTATUS
disk_initialize(BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
DSTATUS stat = STA_NOINIT;
switch (pdrv) {
case DEV_USB: {
if (true == Disk_Init())
stat = RES_OK;
} break;
}
// if(disk.is_initialized[pdrv] == 0)
// {
// disk.is_initialized[pdrv] = 1;
// stat = disk.drv[pdrv]->disk_initialize(disk.lun[pdrv]);
// }
return stat;
}
/**
* @brief Reads Sector(s)
* @param pdrv: Physical drive number (0..)
* @param *buff: Data buffer to store read data
* @param sector: Sector address (LBA)
* @param count: Number of sectors to read (1..128)
* @retval DRESULT: Operation result
*/
DRESULT disk_read(BYTE pdrv, /* Physical drive nmuber to identify the drive */
BYTE *buff, /* Data buffer to store read data */
DWORD sector, /* Sector address in LBA */
UINT count /* Number of sectors to read */
)
{
DRESULT res = RES_ERROR;
switch (pdrv) {
case DEV_USB: {
if (Disk_UnitRead(sector, count, buff) == true) {
res = RES_OK;
}
} break;
}
// res = disk.drv[pdrv]->disk_read(disk.lun[pdrv], buff, sector, count);
return res;
}
/**
* @brief Writes Sector(s)
* @param pdrv: Physical drive number (0..)
* @param *buff: Data to be written
* @param sector: Sector address (LBA)
* @param count: Number of sectors to write (1..128)
* @retval DRESULT: Operation result
*/
#if _USE_WRITE == 1
DRESULT disk_write(BYTE pdrv, /* Physical drive nmuber to identify the drive */
const BYTE *buff, /* Data to be written */
DWORD sector, /* Sector address in LBA */
UINT count /* Number of sectors to write */
)
{
DRESULT res = RES_ERROR;
switch (pdrv) {
case DEV_USB: {
if (Disk_UnitWrite(sector, count, (uint8_t *)buff) == true) {
res = RES_OK;
}
} break;
}
// res = disk.drv[pdrv]->disk_write(disk.lun[pdrv], buff, sector, count);
return res;
}
#endif /* _USE_WRITE == 1 */
/**
* @brief I/O control operation
* @param pdrv: Physical drive number (0..)
* @param cmd: Control code
* @param *buff: Buffer to send/receive control data
* @retval DRESULT: Operation result
*/
#if _USE_IOCTL == 1
DRESULT disk_ioctl(BYTE pdrv, /* Physical drive nmuber (0..) */
BYTE cmd, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
DRESULT res = RES_PARERR;
switch (pdrv) {
case DEV_USB: {
switch (cmd) {
case CTRL_SYNC:
res = RES_OK;
break;
case GET_SECTOR_COUNT: {
*(DWORD *)buff = Disk_UnitCount();
res = RES_OK;
break;
}
case GET_SECTOR_SIZE: {
*(DWORD *)buff = Disk_UnitSize();
res = RES_OK;
break;
}
case GET_BLOCK_SIZE: {
*(DWORD *)buff = 1;
res = RES_OK;
break;
}
default:
res = RES_PARERR;
break;
}
} break;
}
// res = disk.drv[pdrv]->disk_ioctl(disk.lun[pdrv], cmd, buff);
return res;
}
#endif /* _USE_IOCTL == 1 */
/**
* @brief Gets Time from RTC
* @param None
* @retval Time in DWORD
*/
__weak DWORD get_fattime(void)
{
uint32_t fattime;
// utc sec convert to utc date
DateTime_t tmp_date = UTC_SecToDate(Utc_TotalSec);
tmp_date = UTC_DateToZoneDate(TIME_ZONE, YEAR_BASE, tmp_date.year,
tmp_date.month, tmp_date.day, tmp_date.hour,
tmp_date.min, tmp_date.sec, tmp_date.week);
fattime = ((YEAR_BASE + tmp_date.year - 1980) << 25) |
(tmp_date.month << 21) | (tmp_date.day << 16) |
(tmp_date.hour << 11) | (tmp_date.min << 5) | (tmp_date.sec >> 1);
return fattime;
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,91 @@
/*!
* \file fatfs.c
*
* \brief Target FatFS implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "fatfs.h"
#include "xc6xxx.h"
/*------------------------------------------------------------------------------------
Local Variables
-------------------------------------------------------------------------------------*/
char Path[4]; /* Logical drive path */
FATFS FatFS; /* File system object for Logical drive */
FIL File; /* File object */
DIR Dir;
uint8_t buffer[_MAX_SS];
/*------------------------------------------------------------------------------------
Functions
------------------------------------------------------------------------------------*/
/**
* @brief FatFS Initalization
* @param void
* @retval void
*/
void FATFS_Init(void)
{
FRESULT res;
SPI_InitCfg_t spi_cfg = {0};
spi_cfg.Mode = SPI_MODE_MASTER;
spi_cfg.DataSize = SSI_CTRL0_DFS_LEN_8BIT;
spi_cfg.Direction = SSI_CTRL0_TMOD_WR;
spi_cfg.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
spi_cfg.CLKPolarity = SSI_CTRL0_SCPOL_LOW;
spi_cfg.CLKPhase = SPI_CPHA_LEAD;
spi_cfg.FirstBit = SPI_FirstBit_MSB;
xc_spi_init(XC_SPI0, &spi_cfg);
xc_spi_flash_wake_up(XC_SPI0);
DEBUG("FatFS Init\r\n");
res = f_mount(&FatFS, "0:", 1);
DEBUG("Mount FRESULT: %d\r\n", res);
res = f_opendir(&Dir, "0:");
DEBUG("Read Dir: %d\r\n", res);
if (FR_NO_FILESYSTEM == res) {
res = f_mkfs("0:", FM_FAT, _MAX_SS, buffer, sizeof(buffer));
DEBUG("Format FRESULT: %d\r\n", res);
res = f_unmount("0:");
DEBUG("Umount FRESULT: %d\r\n", res);
// res = f_setlabel( "XinChip" );
// DEBUG("Set label: %d\r\n", res);
res = f_mount(&FatFS, "0:", 1);
DEBUG("Remount FRESULT: %d\r\n", res);
res = f_unmount("0:");
DEBUG("Umount FRESULT: %d\r\n", res);
} else {
res = f_unmount("0:");
DEBUG("Umount FRESULT: %d\r\n", res);
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,116 @@
/**
******************************************************************************
* @file ff_gen_drv.c
* @author MCD Application Team
* @brief FatFs generic low level driver.
*****************************************************************************
* @attention
*
* Copyright (c) 2017 STMicroelectronics. All rights reserved.
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
**/
/* Includes ------------------------------------------------------------------*/
#include "ff_gen_drv.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
Disk_drvTypeDef disk = {{0}, {0}, {0}, 0};
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/**
* @brief Links a compatible diskio driver/lun id and increments the number of
active
* linked drivers.
* @note The number of linked drivers (volumes) is up to 10 due to FatFs
limits.
* @param drv: pointer to the disk IO Driver structure
* @param path: pointer to the logical drive path
* @param lun : only used for USB Key Disk to add multi-lun management
else the parameter must be equal to 0
* @retval Returns 0 in case of success, otherwise 1.
*/
uint8_t FATFS_LinkDriverEx(const Diskio_drvTypeDef *drv, char *path,
uint8_t lun)
{
uint8_t ret = 1;
uint8_t DiskNum = 0;
if (disk.nbr < _VOLUMES) {
disk.is_initialized[disk.nbr] = 0;
disk.drv[disk.nbr] = drv;
disk.lun[disk.nbr] = lun;
DiskNum = disk.nbr++;
path[0] = DiskNum + '0';
path[1] = ':';
path[2] = '/';
path[3] = 0;
ret = 0;
}
return ret;
}
/**
* @brief Links a compatible diskio driver and increments the number of active
* linked drivers.
* @note The number of linked drivers (volumes) is up to 10 due to FatFs
* limits
* @param drv: pointer to the disk IO Driver structure
* @param path: pointer to the logical drive path
* @retval Returns 0 in case of success, otherwise 1.
*/
uint8_t FATFS_LinkDriver(const Diskio_drvTypeDef *drv, char *path)
{
return FATFS_LinkDriverEx(drv, path, 0);
}
/**
* @brief Unlinks a diskio driver and decrements the number of active linked
* drivers.
* @param path: pointer to the logical drive path
* @param lun : not used
* @retval Returns 0 in case of success, otherwise 1.
*/
uint8_t FATFS_UnLinkDriverEx(char *path, uint8_t lun)
{
uint8_t DiskNum = 0;
uint8_t ret = 1;
if (disk.nbr >= 1) {
DiskNum = path[0] - '0';
if (disk.drv[DiskNum] != 0) {
disk.drv[DiskNum] = 0;
disk.lun[DiskNum] = 0;
disk.nbr--;
ret = 0;
}
}
return ret;
}
/**
* @brief Unlinks a diskio driver and decrements the number of active linked
* drivers.
* @param path: pointer to the logical drive path
* @retval Returns 0 in case of success, otherwise 1.
*/
uint8_t FATFS_UnLinkDriver(char *path) { return FATFS_UnLinkDriverEx(path, 0); }
/**
* @brief Gets number of linked drivers to the FatFs module.
* @param None
* @retval Number of attached drivers.
*/
uint8_t FATFS_GetAttachedDriversNbr(void) { return disk.nbr; }
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
@@ -0,0 +1,75 @@
/*!
* \file usb_device.c
*
* \brief Target usb device implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usb_device.h"
#include "usbd_cdc.h"
#include "usbd_cdc_if.h"
#include "usbd_core.h"
#include "usbd_desc.h"
/*------------------------------------------------------------------------------------
Global Variables
-------------------------------------------------------------------------------------*/
/* USB Device Core handle declaration. */
USBD_HandleTypeDef hUsbDeviceFS;
/*------------------------------------------------------------------------------------
Functions
-------------------------------------------------------------------------------------*/
/**
* @brief This function handles USB On The Go FS global interrupt.
* @param void
* @retval void
*/
void USB_Handler(void) { HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS); }
/**
* @brief Init USB device Library, add supported class and start the library
* @param void
* @retval void
*/
void USB_DEVICE_Init(void)
{
/* Init Device Library, add supported class and start the library. */
if (USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS) != USBD_OK) {
USBD_UsrLog("__USB_INIT_FAIL__\r\n");
Error_Handler();
}
if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_CDC) != USBD_OK) {
USBD_UsrLog("__USB_CLASS_FAIL__\r\n");
Error_Handler();
}
if (USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS) !=
USBD_OK) {
USBD_UsrLog("__USB_CDC_FAIL__\r\n");
Error_Handler();
}
if (USBD_Start(&hUsbDeviceFS) != USBD_OK) {
USBD_UsrLog("__USB_START_FAIL__\r\n");
Error_Handler();
}
}
@@ -0,0 +1,47 @@
/*!
* \file usb_device.h
*
* \brief Target usb device implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_DEVICE_H
#define __USB_DEVICE_H
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_def.h"
/*------------------------------------------------------------------------------------
Exported Functions
-------------------------------------------------------------------------------------*/
void USB_DEVICE_Init( void );
#ifdef __cplusplus
}
#endif
#endif /* __USB_DEVICE_H */
@@ -0,0 +1,322 @@
/*!
* \file usbd_cdc_if.c
*
* \brief Usb device for Virtual Com Port.
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_cdc_if.h"
#include "ringbuffer.h"
/*------------------------------------------------------------------------------------
Global Variables
-------------------------------------------------------------------------------------*/
/** @defgroup USBD_CDC_IF_Exported_Variables USBD_CDC_IF_Exported_Variables
* @brief Public variables.
* @{
*/
uint8_t Next_ep = 0;
extern USBD_HandleTypeDef hUsbDeviceFS;
/**
* @}
*/
/*------------------------------------------------------------------------------------
Local Variables
-------------------------------------------------------------------------------------*/
/** Received data over USB are stored in this buffer */
uint8_t UserRxBufferFS[APP_RX_DATA_SIZE];
uint16_t UserRxBufferLen = 0;
/** Data to send over USB CDC are stored in this buffer */
uint8_t UserTxBufferFS[APP_TX_DATA_SIZE];
uint8_t UserReTx = false;
uint8_t TempBuffer[APP_TX_DATA_SIZE / 2];
/**
* @}
*/
/*------------------------------------------------------------------------------------
Func Prototype
-------------------------------------------------------------------------------------*/
/** @defgroup USBD_CDC_IF_Private_FunctionPrototypes
* USBD_CDC_IF_Private_FunctionPrototypes
* @brief Private functions declaration.
* @{
*/
static int8_t CDC_Init_FS(void);
static int8_t CDC_DeInit_FS(void);
static int8_t CDC_Control_FS(uint8_t cmd, uint8_t *pbuf, uint16_t length);
static int8_t CDC_Receive_FS(uint8_t *pbuf, uint32_t *Len);
static int8_t CDC_TransmitCplt_FS(uint8_t *pbuf, uint32_t *Len, uint8_t epnum);
/**
* @}
*/
USBD_CDC_ItfTypeDef USBD_Interface_fops_FS = {CDC_Init_FS, CDC_DeInit_FS,
CDC_Control_FS, CDC_Receive_FS,
CDC_TransmitCplt_FS};
/*------------------------------------------------------------------------------------
Functions
-------------------------------------------------------------------------------------*/
/**
* @brief Initializes the CDC media low layer over the FS USB IP
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t CDC_Init_FS(void)
{
/* Set Application Buffers */
memset(TempBuffer, 0, sizeof(TempBuffer));
UserRxBufferLen = 0;
// USB_FlushTxFifo(hpcd_USB_OTG_FS.Instance, 0x10U);
USBD_CDC_SetTxBuffer(&hUsbDeviceFS, UserTxBufferFS, 0);
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, UserRxBufferFS);
return (USBD_OK);
}
/**
* @brief DeInitializes the CDC media low layer
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t CDC_DeInit_FS(void) { return (USBD_OK); }
/**
* @brief Manage the CDC class requests
* @param cmd: Command code
* @param pbuf: Buffer containing command data (request parameters)
* @param length: Number of data to be sent (in bytes)
* @retval Result of the operation: USBD_OK if all operations are OK else
* USBD_FAIL
*/
static int8_t CDC_Control_FS(uint8_t cmd, uint8_t *pbuf, uint16_t length)
{
switch (cmd) {
case CDC_SEND_ENCAPSULATED_COMMAND:
break;
case CDC_GET_ENCAPSULATED_RESPONSE:
break;
case CDC_SET_COMM_FEATURE:
break;
case CDC_GET_COMM_FEATURE:
break;
case CDC_CLEAR_COMM_FEATURE:
break;
/*******************************************************************************/
/* Line Coding Structure */
/*-----------------------------------------------------------------------------*/
/* Offset | Field | Size | Value | Description */
/* 0 | dwDTERate | 4 | Number |Data terminal rate, in bits per
* second*/
/* 4 | bCharFormat | 1 | Number | Stop bits */
/* 0 - 1 Stop bit */
/* 1 - 1.5 Stop bits */
/* 2 - 2 Stop bits */
/* 5 | bParityType | 1 | Number | Parity */
/* 0 - None */
/* 1 - Odd */
/* 2 - Even */
/* 3 - Mark */
/* 4 - Space */
/* 6 | bDataBits | 1 | Number Data bits (5, 6, 7, 8 or 16). */
/*******************************************************************************/
case CDC_SET_LINE_CODING:
break;
case CDC_GET_LINE_CODING:
break;
case CDC_SET_CONTROL_LINE_STATE:
break;
case CDC_SEND_BREAK:
break;
default:
break;
}
return (USBD_OK);
}
/**
* @brief Data received over USB OUT endpoint are sent over CDC interface
* through this function.
*
* @note
* This function will issue a NAK packet on any OUT packet received on
* USB endpoint until exiting this function. If you exit this function
* before transfer is complete on CDC interface (ie. using DMA
* controller) it will result in receiving more data while previous ones are
* still not sent.
*
* @param Buf: Buffer of data to be received
* @param Len: Number of data received (in bytes)
* @retval Result of the operation: USBD_OK if all operations are OK else
* USBD_FAIL
*/
static int8_t CDC_Receive_FS(uint8_t *Buf, uint32_t *Len)
{
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
// Receive Timer Refresh
// TIMER_SetUs(XC_TIMER0, CDC_RECV_TIMEOUT_MS);
// TIMER_Start_IT(XC_TIMER0);
// DEBUG("len %d\n", *Len);
//// Delay_Ms(10);
// if(*Len != 0)
// {
// if(UserRxBufferLen < (APP_TX_DATA_SIZE/2))
// {
// ring_buffer_queue_arr(&CDC_Rx, Buf, *Len);
// UserRxBufferLen += *Len;
// }
// }
// DEBUG("u_len %d\n", UserRxBufferLen);
CDC_Transmit_FS(UserRxBufferFS, *Len, CDC_IN_EP);
return (USBD_OK);
}
/**
* @brief CDC_Transmit_FS
* Data to send over USB IN endpoint are sent over CDC interface
* through this function.
* @note
*
*
* @param Buf: Buffer of data to be sent
* @param Len: Number of data to be sent (in bytes)
* @retval USBD_OK if all operations are OK else USBD_FAIL or USBD_BUSY
*/
uint8_t CDC_Transmit_FS(uint8_t *Buf, uint16_t Len, uint8_t epnum)
{
uint8_t result = USBD_OK;
// DEBUG("cdc_epnum: %d\n", epnum);
USBD_CDC_HandleTypeDef *hcdc =
(USBD_CDC_HandleTypeDef *)hUsbDeviceFS.pClassData;
if (hcdc->TxState != 0) {
// DEBUG("bsy: %d\n", hcdc->TxState);
return USBD_BUSY;
}
// DEBUG("tx_len %d\r", Len);
USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf, Len);
result = USBD_CDC_TransmitPacket(&hUsbDeviceFS, epnum);
// uint8_t packetSendCnt = Len / 64;
// uint8_t packetSendRem = Len % 64;
//
// for(uint8_t i=0; i<packetSendCnt; i++)
// {
// USBD_CDC_SetTxBuffer(&hUsbDeviceFS, &Buf[i * 64], 64);
// result = USBD_CDC_TransmitPacket(&hUsbDeviceFS, epnum);
// while(hcdc->TxState != 0);
// USBD_CDC_SetTxBuffer(&hUsbDeviceFS, NULL, 0);
// result = USBD_CDC_TransmitPacket(&hUsbDeviceFS, epnum);
// while(hcdc->TxState != 0);
// }
//
// if(packetSendRem != 0)
// {
// DEBUG("SendRem\r");
// USBD_CDC_SetTxBuffer(&hUsbDeviceFS, &Buf[Len - packetSendRem],
// packetSendRem); result = USBD_CDC_TransmitPacket(&hUsbDeviceFS,
// epnum);
// }
// while(hcdc->TxState != 0);
// memset(TempBuffer, 0, sizeof(TempBuffer));
// UserRxBufferLen = 0;
return result;
}
/**
* @brief CDC_TransmitCplt_FS
* Data transmitted callback
*
* @note
* This function is IN transfer complete callback used to inform user
* that the submitted Data is successfully sent over USB.
*
* @param Buf: Buffer of data to be received
* @param Len: Number of data received (in bytes)
* @retval Result of the operation: USBD_OK if all operations are OK else
* USBD_FAIL
*/
static int8_t CDC_TransmitCplt_FS(uint8_t *Buf, uint32_t *Len, uint8_t epnum)
{
uint8_t result = USBD_OK;
// static uint8_t offset = 0;
UNUSED(Buf);
UNUSED(Len);
UNUSED(epnum);
// if(UserReTx == true)
// {
// UserRxBufferLen -= CDC_DATA_FS_MAX_PACKET_SIZE;
// offset++;
// if(UserRxBufferLen > CDC_DATA_FS_MAX_PACKET_SIZE)
// CDC_Transmit_FS(TempBuffer+offset*CDC_DATA_FS_MAX_PACKET_SIZE,
// CDC_DATA_FS_MAX_PACKET_SIZE, CDC_IN_EP);
// else
// {
// UserReTx = false;
// CDC_Transmit_FS(TempBuffer+offset*CDC_DATA_FS_MAX_PACKET_SIZE,
// UserRxBufferLen, CDC_IN_EP);
// }
// }
// else
// {
// if(UserRxBufferLen <= CDC_DATA_FS_MAX_PACKET_SIZE)
// {
// offset = 0;
// memset(TempBuffer, 0, sizeof(TempBuffer));
// UserRxBufferLen = 0;
// }
// }
return result;
}
@@ -0,0 +1,84 @@
/*!
* \file usbd_cdc_if.h
*
* \brief Header for usbd_cdc_if.c file.
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_CDC_IF_H
#define __USBD_CDC_IF_H
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_cdc.h"
/*------------------------------------------------------------------------------------
Macros
-----------------------------------------------------------------------------------*/
/** @defgroup USBD_CDC_IF_Exported_Defines USBD_CDC_IF_Exported_Defines
* @brief Defines.
* @{
*/
/* Define size for the receive and transmit buffer over CDC */
#define APP_RX_DATA_SIZE 1024
#define APP_TX_DATA_SIZE 1024
#define CDC_RECV_TIMEOUT_MS 5000U
/**
* @}
*/
/*------------------------------------------------------------------------------------
Global Variables
-------------------------------------------------------------------------------------*/
/** CDC Interface callback. */
extern USBD_CDC_ItfTypeDef USBD_Interface_fops_FS;
extern uint8_t Next_ep;
//extern tHandler_callback CDC_Recv_Timer_Cbk[4];
extern uint16_t UserRxBufferLen;
extern uint8_t UserTxBufferFS[APP_TX_DATA_SIZE];
extern uint8_t UserTxEnable;
/**
* @}
*/
/*------------------------------------------------------------------------------------
Exported Functions
-------------------------------------------------------------------------------------*/
uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len, uint8_t epnum);
void CDC_Receive_Timeout(uint16_t val);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBD_CDC_IF_H */
@@ -0,0 +1,348 @@
/*!
* \file usbd_desc.c
*
* \brief Target the USB device descriptors implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_desc.h"
#include "usbd_conf.h"
#include "usbd_core.h"
/*------------------------------------------------------------------------------------
Macros
-------------------------------------------
-----------------------------------------*/
/** @defgroup USBD_DESC_Private_Defines USBD_DESC_Private_Defines
* @brief Private defines.
* @{
*/
#define USBD_VID 0x0483
#define USBD_LANGID_STRING 0x0409
#define USBD_MANUFACTURER_STRING "XinChip"
#define USBD_PID_FS 22336
#define USBD_PRODUCT_STRING_FS "XinChip Virtual ComPort"
#define USBD_CONFIGURATION_STRING_FS "CDC Config"
#define USBD_INTERFACE_STRING_FS "CDC Interface"
#define USB_SIZ_BOS_DESC 0x0C
/*------------------------------------------------------------------------------------
Func Prototypes
-------------------------------------------------------------------------------------*/
/** @defgroup USBD_DESC_Private_FunctionPrototypes
* USBD_DESC_Private_FunctionPrototypes
* @brief Private functions declaration.
* @{
*/
static void Get_SerialNum(void);
static void IntToUnicode(uint32_t value, uint8_t *pbuf, uint8_t len);
/** @defgroup USBD_DESC_Private_FunctionPrototypes
* USBD_DESC_Private_FunctionPrototypes
* @brief Private functions declaration for FS.
* @{
*/
uint8_t *USBD_FS_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *USBD_FS_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *USBD_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed,
uint16_t *length);
uint8_t *USBD_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed,
uint16_t *length);
uint8_t *USBD_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *USBD_FS_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *USBD_FS_InterfaceStrDescriptor(USBD_SpeedTypeDef speed,
uint16_t *length);
#if (USBD_LPM_ENABLED == 1)
uint8_t *USBD_FS_USR_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
#endif /* (USBD_LPM_ENABLED == 1) */
/*------------------------------------------------------------------------------------
Local Variables
-------------------------------------------------------------------------------------*/
/** @defgroup USBD_DESC_Private_Variables USBD_DESC_Private_Variables
* @brief Private variables.
* @{
*/
USBD_DescriptorsTypeDef FS_Desc = {USBD_FS_DeviceDescriptor,
USBD_FS_LangIDStrDescriptor,
USBD_FS_ManufacturerStrDescriptor,
USBD_FS_ProductStrDescriptor,
USBD_FS_SerialStrDescriptor,
USBD_FS_ConfigStrDescriptor,
USBD_FS_InterfaceStrDescriptor
#if (USBD_LPM_ENABLED == 1)
,
USBD_FS_USR_BOSDescriptor
#endif /* (USBD_LPM_ENABLED == 1) */
};
#if defined(__ICCARM__) /* IAR Compiler */
#pragma data_alignment = 4
#endif /* defined ( __ICCARM__ ) */
/** USB standard device descriptor. */
__ALIGN_BEGIN uint8_t USBD_FS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
0x12, /*bLength */
USB_DESC_TYPE_DEVICE, /*bDescriptorType*/
#if (USBD_LPM_ENABLED == 1)
0x01,
/*bcdUSB */ /* changed to USB version 2.01
in order to support LPM L1 suspend
resume test of USBCV3.0*/
#else
0x00, /*bcdUSB */
#endif /* (USBD_LPM_ENABLED == 1) */
0x02,
DEV_CLASS, /*bDeviceClass*/
DEV_SUB_CLASS, /*bDeviceSubClass*/
DEV_PROTOCOL, /*bDeviceProtocol*/
USB_MAX_EP0_SIZE, /*bMaxPacketSize*/
LOBYTE(USBD_VID), /*idVendor*/
HIBYTE(USBD_VID), /*idVendor*/
LOBYTE(USBD_PID_FS), /*idProduct*/
HIBYTE(USBD_PID_FS), /*idProduct*/
0x00, /*bcdDevice rel. 2.00*/
0x02,
USBD_IDX_MFC_STR, /*Index of manufacturer string*/
USBD_IDX_PRODUCT_STR, /*Index of product string*/
USBD_IDX_SERIAL_STR, /*Index of serial number string*/
USBD_MAX_NUM_CONFIGURATION /*bNumConfigurations*/
};
/* USB_DeviceDescriptor */
/** BOS descriptor. */
#if (USBD_LPM_ENABLED == 1)
#if defined(__ICCARM__) /* IAR Compiler */
#pragma data_alignment = 4
#endif /* defined ( __ICCARM__ ) */
__ALIGN_BEGIN uint8_t USBD_FS_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END = {
0x5, USB_DESC_TYPE_BOS, 0xC, 0x0, 0x1, /* 1 device capability*/
/* device capability*/
0x7, USB_DEVICE_CAPABITY_TYPE, 0x2, 0x2, /* LPM capability bit set*/
0x0, 0x0, 0x0};
#endif /* (USBD_LPM_ENABLED == 1) */
/** @defgroup USBD_DESC_Private_Variables USBD_DESC_Private_Variables
* @brief Private variables.
* @{
*/
#if defined(__ICCARM__) /* IAR Compiler */
#pragma data_alignment = 4
#endif /* defined ( __ICCARM__ ) */
/** USB lang identifier descriptor. */
__ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = {
USB_LEN_LANGID_STR_DESC, USB_DESC_TYPE_STRING, LOBYTE(USBD_LANGID_STRING),
HIBYTE(USBD_LANGID_STRING)};
#if defined(__ICCARM__) /* IAR Compiler */
#pragma data_alignment = 4
#endif /* defined ( __ICCARM__ ) */
/* Internal string descriptor. */
__ALIGN_BEGIN uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END;
#if defined(__ICCARM__) /*!< IAR Compiler */
#pragma data_alignment = 4
#endif
__ALIGN_BEGIN uint8_t USBD_StringSerial[USB_SIZ_STRING_SERIAL] __ALIGN_END = {
USB_SIZ_STRING_SERIAL,
USB_DESC_TYPE_STRING,
};
/*------------------------------------------------------------------------------------
Functions
-------------------------------------------------------------------------------------*/
/**
* @brief Return the device descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_FS_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
UNUSED(speed);
*length = sizeof(USBD_FS_DeviceDesc);
return USBD_FS_DeviceDesc;
}
/**
* @brief Return the LangID string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_FS_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
UNUSED(speed);
*length = sizeof(USBD_LangIDDesc);
return USBD_LangIDDesc;
}
/**
* @brief Return the product string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
if (speed == 0) {
USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length);
} else {
USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length);
}
return USBD_StrDesc;
}
/**
* @brief Return the manufacturer string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed,
uint16_t *length)
{
UNUSED(speed);
USBD_GetString((uint8_t *)USBD_MANUFACTURER_STRING, USBD_StrDesc, length);
return USBD_StrDesc;
}
/**
* @brief Return the serial number string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
UNUSED(speed);
*length = USB_SIZ_STRING_SERIAL;
/* Update the serial number string descriptor with the data from the unique
* ID */
Get_SerialNum();
/* USER CODE BEGIN USBD_FS_SerialStrDescriptor */
/* USER CODE END USBD_FS_SerialStrDescriptor */
return (uint8_t *)USBD_StringSerial;
}
/**
* @brief Return the configuration string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_FS_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING_FS, USBD_StrDesc,
length);
return USBD_StrDesc;
}
/**
* @brief Return the interface string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_FS_InterfaceStrDescriptor(USBD_SpeedTypeDef speed,
uint16_t *length)
{
if (speed == 0) {
USBD_GetString((uint8_t *)USBD_INTERFACE_STRING_FS, USBD_StrDesc,
length);
} else {
USBD_GetString((uint8_t *)USBD_INTERFACE_STRING_FS, USBD_StrDesc,
length);
}
return USBD_StrDesc;
}
#if (USBD_LPM_ENABLED == 1)
/**
* @brief Return the BOS descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_FS_USR_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
UNUSED(speed);
*length = sizeof(USBD_FS_BOSDesc);
return (uint8_t *)USBD_FS_BOSDesc;
}
#endif /* (USBD_LPM_ENABLED == 1) */
/**
* @brief Create the serial number string descriptor
* @param None
* @retval None
*/
static void Get_SerialNum(void)
{
uint32_t deviceserial0, deviceserial1, deviceserial2;
deviceserial0 = DEVICE_ID1;
deviceserial1 = DEVICE_ID2;
deviceserial2 = DEVICE_ID3;
deviceserial0 += deviceserial2;
if (deviceserial0 != 0) {
IntToUnicode(deviceserial0, &USBD_StringSerial[2], 8);
IntToUnicode(deviceserial1, &USBD_StringSerial[18], 4);
}
}
/**
* @brief Convert Hex 32Bits value into char
* @param value: value to convert
* @param pbuf: pointer to the buffer
* @param len: buffer length
* @retval None
*/
static void IntToUnicode(uint32_t value, uint8_t *pbuf, uint8_t len)
{
uint8_t idx = 0;
for (idx = 0; idx < len; idx++) {
if (((value >> 28)) < 0xA) {
pbuf[2 * idx] = (value >> 28) + '0';
} else {
pbuf[2 * idx] = (value >> 28) + 'A' - 10;
}
value = value << 4;
pbuf[2 * idx + 1] = 0;
}
}
/**
* @}
*/
@@ -0,0 +1,76 @@
/*!
* \file usbd_desc.h
*
* \brief Target the USB device descriptors implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_DESC__C
#define __USBD_DESC__C
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_def.h"
/*------------------------------------------------------------------------------------
Macros
-------------------------------------------------------------------------------------*/
/** @defgroup USBD_DESC_Exported_Constants USBD_DESC_Exported_Constants
* @brief Constants.
* @{
*/
#define DEV_CLASS 0x02
#define DEV_SUB_CLASS 0x02
#define DEV_PROTOCOL 0x00
#define DEVICE_ID1 0x20220000
#define DEVICE_ID2 0x1B0000
#define DEVICE_ID3 0x0914
#define USB_SIZ_STRING_SERIAL 0x1A
/**
* @}
*/
/*------------------------------------------------------------------------------------
Global Variables
-------------------------------------------------------------------------------------*/
/** Descriptor for the Usb device. */
extern USBD_DescriptorsTypeDef FS_Desc;
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBD_DESC__C */
@@ -0,0 +1,184 @@
/*!
* \file usb_device.c
*
* \brief Target usb device implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usb_device.h"
#include "usbd_core.h"
#include "usbd_desc.h"
#include "usbd_hid.h"
/*------------------------------------------------------------------------------------
Macros
-------------------------------------------------------------------------------------*/
#if ((HID_CLASS_MODE & HID_MOUSE) == HID_MOUSE)
#define CURSOR_STEP 2U
#define CURSOR_WIDTH 200U
#elif ((HID_CLASS_MODE & HID_KEYBOARD) == HID_KEYBOARD)
#define KEY_CAPS_DATA 0x39
#endif
/*------------------------------------------------------------------------------------
Global Variables
-------------------------------------------------------------------------------------*/
/* USB Device Core handle declaration. */
USBD_HandleTypeDef hUsbDeviceFS;
/*------------------------------------------------------------------------------------
Functions
-------------------------------------------------------------------------------------*/
/**
* @brief This function handles USB On The Go FS global interrupt.
* @param void
* @retval void
*/
void USB_Handler(void) { HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS); }
/**
* @brief Init USB device Library, add supported class and start the library
* @param void
* @retval void
*/
void USB_DEVICE_Init(void)
{
/* Init Device Library, add supported class and start the library. */
if (USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS) != USBD_OK) {
Error_Handler();
}
if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_HID) != USBD_OK) {
Error_Handler();
}
if (USBD_Start(&hUsbDeviceFS) != USBD_OK) {
Error_Handler();
}
}
#if ((HID_CLASS_MODE & HID_MOUSE) == HID_MOUSE)
/**
* @brief Mouse get pointer datas
* @param uint8_t *pbuf
* @retval void
*/
void GetPointerData(uint8_t *pbuf)
{
static int32_t move_cnt = 0;
static uint8_t step_x_y = 0;
static int8_t x = 0, y = 0;
static uint16_t cnt = 0;
move_cnt++;
if (move_cnt > CURSOR_WIDTH) {
step_x_y++;
step_x_y = step_x_y % 4;
move_cnt = 0;
}
switch (step_x_y) {
case 0: {
y = 0;
x = CURSOR_STEP;
} break;
case 1: {
x = 0;
y = CURSOR_STEP;
} break;
case 2: {
y = 0;
x = (int8_t)(-CURSOR_STEP);
} break;
case 3: {
x = 0;
y = (int8_t)(-CURSOR_STEP);
} break;
}
cnt++;
pbuf[0] = 0; // 1;
if (cnt > 1000) {
pbuf[0] = 16; // 17;
cnt = 0;
}
pbuf[1] = x;
pbuf[2] = y;
pbuf[3] = 0;
}
/**
* @brief Usb mouse test send report
* @param void
* @retval void
*/
void USB_Mouse_Test_SendReport(void)
{
uint8_t buff[4] = {0};
USBD_HID_SendReport(&hUsbDeviceFS, HID_EPIN_ADDR, buff, HID_EPIN_SIZE);
}
#endif
#if ((HID_CLASS_MODE & HID_KEYBOARD) == HID_KEYBOARD)
/**
* @brief Usb Keyboard test send report
* @param void
* @retval void
*/
void USB_Keyboard_Test_SendReport(eKeyState key_sta)
{
uint8_t buff[HID_EPIN_SIZE] = {0};
if (key_sta == KEY_PRESS) {
buff[2] = KEY_CAPS_DATA;
USBD_HID_SendReport(&hUsbDeviceFS, HID_EPIN_ADDR, buff, HID_EPIN_SIZE);
} else if (key_sta == KEY_RELEASE) {
USBD_HID_SendReport(&hUsbDeviceFS, HID_EPIN_ADDR, buff, HID_EPIN_SIZE);
} else if (key_sta == KEY_HOLD_PRESS) {
return;
}
}
#endif
#if (HID_CLASS_MODE == HID_CUSTOM)
/**
* @brief Usb custom hid test send report
* @param void
* @retval void
*/
void USB_Custom_Test_SendReport(void)
{
uint8_t usb_tx_data[64] = {0};
// usb_tx_data[0] = 0x01;
for (uint8_t i = 0; i < 64; i++)
usb_tx_data[i] = i;
USBD_HID_SendReport(&hUsbDeviceFS, HID_EPIN_ADDR, usb_tx_data, 64);
}
#endif
@@ -0,0 +1,66 @@
/*!
* \file usb_device.h
*
* \brief Target usb device implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_DEVICE_H__
#define __USB_DEVICE_H__
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_def.h"
extern USBD_HandleTypeDef hUsbDeviceFS;
typedef enum {
KEY_RELEASE = 0,
KEY_PRESS,
KEY_HOLD_PRESS
} eKeyState;
extern USBD_HandleTypeDef hUsbDeviceFS;
/*------------------------------------------------------------------------------------
Exported Functions
-------------------------------------------------------------------------------------*/
void USB_DEVICE_Init( void );
void USB_Mouse_Test_SendReport( void );
void USB_Keyboard_Test_SendReport(eKeyState key_sta);
void USB_Custom_Test_SendReport( void );
void GetPointerData(uint8_t *pbuf);
#ifdef __cplusplus
}
#endif
#endif /* __USB_DEVICE_H__ */
@@ -0,0 +1,352 @@
/*!
* \file usbd_desc.c
*
* \brief Target the USB device descriptors implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_desc.h"
#include "usbd_conf.h"
#include "usbd_core.h"
/*------------------------------------------------------------------------------------
Macros
-------------------------------------------
-----------------------------------------*/
/** @defgroup USBD_DESC_Private_Defines USBD_DESC_Private_Defines
* @brief Private defines.
* @{
*/
#define USBD_VID VID_VAL
#define USBD_LANGID_STRING LANG_ID_STR
#define USBD_MANUFACTURER_STRING "XinChip"
#define USBD_PID_FS PID_FS_VAL
#define USBD_PRODUCT_STRING_FS \
"XinChip Custom Human interface" //"XinChip Human interface"
#define USBD_CONFIGURATION_STRING_FS "Custom HID Config" //"HID Config"
#define USBD_INTERFACE_STRING_FS "Custom HID Interface" //"HID Interface"
#define USB_SIZ_BOS_DESC 0x0C
/*------------------------------------------------------------------------------------
Func Prototypes
-------------------------------------------------------------------------------------*/
/** @defgroup USBD_DESC_Private_FunctionPrototypes
* USBD_DESC_Private_FunctionPrototypes
* @brief Private functions declaration.
* @{
*/
static void Get_SerialNum(void);
static void IntToUnicode(uint32_t value, uint8_t *pbuf, uint8_t len);
/** @defgroup USBD_DESC_Private_FunctionPrototypes
* USBD_DESC_Private_FunctionPrototypes
* @brief Private functions declaration for FS.
* @{
*/
uint8_t *USBD_FS_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *USBD_FS_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *USBD_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed,
uint16_t *length);
uint8_t *USBD_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed,
uint16_t *length);
uint8_t *USBD_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *USBD_FS_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *USBD_FS_InterfaceStrDescriptor(USBD_SpeedTypeDef speed,
uint16_t *length);
#if (USBD_LPM_ENABLED == 1)
uint8_t *USBD_FS_USR_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
#endif /* (USBD_LPM_ENABLED == 1) */
/*------------------------------------------------------------------------------------
Local Variables
-------------------------------------------------------------------------------------*/
/** @defgroup USBD_DESC_Private_Variables USBD_DESC_Private_Variables
* @brief Private variables.
* @{
*/
USBD_DescriptorsTypeDef FS_Desc = {USBD_FS_DeviceDescriptor,
USBD_FS_LangIDStrDescriptor,
USBD_FS_ManufacturerStrDescriptor,
USBD_FS_ProductStrDescriptor,
USBD_FS_SerialStrDescriptor,
USBD_FS_ConfigStrDescriptor,
USBD_FS_InterfaceStrDescriptor
#if (USBD_LPM_ENABLED == 1)
,
USBD_FS_USR_BOSDescriptor
#endif /* (USBD_LPM_ENABLED == 1) */
};
#if defined(__ICCARM__) /* IAR Compiler */
#pragma data_alignment = 4
#endif /* defined ( __ICCARM__ ) */
/** USB standard device descriptor. */
__ALIGN_BEGIN uint8_t USBD_FS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
0x12, /*bLength */
USB_DESC_TYPE_DEVICE, /*bDescriptorType*/
#if (USBD_LPM_ENABLED == 1)
0x01,
/*bcdUSB */ /* changed to USB version 2.01
in order to support LPM L1 suspend
resume test of USBCV3.0*/
#else
0x00, /*bcdUSB */
#endif /* (USBD_LPM_ENABLED == 1) */
0x02,
DEV_CLASS, /*bDeviceClass*/
DEV_SUB_CLASS, /*bDeviceSubClass*/
DEV_PROTOCOL, /*bDeviceProtocol*/
USB_MAX_EP0_SIZE, /*bMaxPacketSize*/
LOBYTE(USBD_VID), /*idVendor*/
HIBYTE(USBD_VID), /*idVendor*/
LOBYTE(USBD_PID_FS), /*idProduct*/
HIBYTE(USBD_PID_FS), /*idProduct*/
0x00, /*bcdDevice rel. 2.00*/
0x02,
USBD_IDX_MFC_STR, /*Index of manufacturer string*/
USBD_IDX_PRODUCT_STR, /*Index of product string*/
USBD_IDX_SERIAL_STR, /*Index of serial number string*/
USBD_MAX_NUM_CONFIGURATION /*bNumConfigurations*/
};
/* USB_DeviceDescriptor */
/** BOS descriptor. */
#if (USBD_LPM_ENABLED == 1)
#if defined(__ICCARM__) /* IAR Compiler */
#pragma data_alignment = 4
#endif /* defined ( __ICCARM__ ) */
__ALIGN_BEGIN uint8_t USBD_FS_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END = {
0x5, USB_DESC_TYPE_BOS, 0xC, 0x0, 0x1, /* 1 device capability*/
/* device capability*/
0x7, USB_DEVICE_CAPABITY_TYPE, 0x2, 0x2, /* LPM capability bit set*/
0x0, 0x0, 0x0};
#endif /* (USBD_LPM_ENABLED == 1) */
/** @defgroup USBD_DESC_Private_Variables USBD_DESC_Private_Variables
* @brief Private variables.
* @{
*/
#if defined(__ICCARM__) /* IAR Compiler */
#pragma data_alignment = 4
#endif /* defined ( __ICCARM__ ) */
/** USB lang identifier descriptor. */
__ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = {
USB_LEN_LANGID_STR_DESC, USB_DESC_TYPE_STRING, LOBYTE(USBD_LANGID_STRING),
HIBYTE(USBD_LANGID_STRING)};
#if defined(__ICCARM__) /* IAR Compiler */
#pragma data_alignment = 4
#endif /* defined ( __ICCARM__ ) */
/* Internal string descriptor. */
__ALIGN_BEGIN uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END;
#if defined(__ICCARM__) /*!< IAR Compiler */
#pragma data_alignment = 4
#endif
__ALIGN_BEGIN uint8_t USBD_StringSerial[USB_SIZ_STRING_SERIAL] __ALIGN_END = {
USB_SIZ_STRING_SERIAL,
USB_DESC_TYPE_STRING,
};
/*------------------------------------------------------------------------------------
Functions
-------------------------------------------------------------------------------------*/
/**
* @brief Return the device descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_FS_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
*length = sizeof(USBD_FS_DeviceDesc);
return USBD_FS_DeviceDesc;
}
/**
* @brief Return the LangID string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_FS_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
UNUSED(speed);
*length = sizeof(USBD_LangIDDesc);
return USBD_LangIDDesc;
}
/**
* @brief Return the product string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
if (speed == 0) {
USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length);
} else {
USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length);
}
return USBD_StrDesc;
}
/**
* @brief Return the manufacturer string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed,
uint16_t *length)
{
UNUSED(speed);
USBD_GetString((uint8_t *)USBD_MANUFACTURER_STRING, USBD_StrDesc, length);
return USBD_StrDesc;
}
/**
* @brief Return the serial number string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
UNUSED(speed);
*length = USB_SIZ_STRING_SERIAL;
/* Update the serial number string descriptor with the data from the unique
* ID */
Get_SerialNum();
/* USER CODE BEGIN USBD_FS_SerialStrDescriptor */
/* USER CODE END USBD_FS_SerialStrDescriptor */
return (uint8_t *)USBD_StringSerial;
}
/**
* @brief Return the configuration string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_FS_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
if (speed == USBD_SPEED_HIGH) {
USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING_FS, USBD_StrDesc,
length);
} else {
USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING_FS, USBD_StrDesc,
length);
}
return USBD_StrDesc;
}
/**
* @brief Return the interface string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_FS_InterfaceStrDescriptor(USBD_SpeedTypeDef speed,
uint16_t *length)
{
if (speed == 0) {
USBD_GetString((uint8_t *)USBD_INTERFACE_STRING_FS, USBD_StrDesc,
length);
} else {
USBD_GetString((uint8_t *)USBD_INTERFACE_STRING_FS, USBD_StrDesc,
length);
}
return USBD_StrDesc;
}
#if (USBD_LPM_ENABLED == 1)
/**
* @brief Return the BOS descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_FS_USR_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
UNUSED(speed);
*length = sizeof(USBD_FS_BOSDesc);
return (uint8_t *)USBD_FS_BOSDesc;
}
#endif /* (USBD_LPM_ENABLED == 1) */
/**
* @brief Create the serial number string descriptor
* @param None
* @retval None
*/
static void Get_SerialNum(void)
{
uint32_t deviceserial0, deviceserial1, deviceserial2;
deviceserial0 = DEVICE_ID1;
deviceserial1 = DEVICE_ID2;
deviceserial2 = DEVICE_ID3;
deviceserial0 += deviceserial2;
if (deviceserial0 != 0) {
IntToUnicode(deviceserial0, &USBD_StringSerial[2], 8);
IntToUnicode(deviceserial1, &USBD_StringSerial[18], 4);
}
}
/**
* @brief Convert Hex 32Bits value into char
* @param value: value to convert
* @param pbuf: pointer to the buffer
* @param len: buffer length
* @retval None
*/
static void IntToUnicode(uint32_t value, uint8_t *pbuf, uint8_t len)
{
uint8_t idx = 0;
for (idx = 0; idx < len; idx++) {
if (((value >> 28)) < 0xA) {
pbuf[2 * idx] = (value >> 28) + '0';
} else {
pbuf[2 * idx] = (value >> 28) + 'A' - 10;
}
value = value << 4;
pbuf[2 * idx + 1] = 0;
}
}
/**
* @}
*/
@@ -0,0 +1,120 @@
/*!
* \file usbd_desc.h
*
* \brief Target the USB device descriptors implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_DESC__C__
#define __USBD_DESC__C__
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_def.h"
/*------------------------------------------------------------------------------------
Macros
-------------------------------------------------------------------------------------*/
/** @defgroup USBD_DESC_Exported_Constants USBD_DESC_Exported_Constants
* @brief Constants.
* @{
*/
#if (HID_CLASS_MODE == HID_MOUSE)
#define VID_VAL 1155
#define LANG_ID_STR 1033
#define PID_FS_VAL 17799
#define DEVICE_ID1 0x20220000
#define DEVICE_ID2 0x1D0000
#define DEVICE_ID3 0x1122
#elif (HID_CLASS_MODE == HID_KEYBOARD)
#define VID_VAL 1155
#define LANG_ID_STR 1033
#define PID_FS_VAL 17780
#define DEVICE_ID1 0x20220000
#define DEVICE_ID2 0x1F0000
#define DEVICE_ID3 0x1123
#elif (HID_CLASS_MODE == HID_CUSTOM)
#define VID_VAL 1155
#define LANG_ID_STR 1033
#define PID_FS_VAL 17781
#define DEVICE_ID1 0x20220000
#define DEVICE_ID2 0x1F0000
#define DEVICE_ID3 0x1124
#elif (HID_CLASS_MODE == (HID_MOUSE | HID_CUSTOM))
#define VID_VAL 1156
#define LANG_ID_STR 1033
#define PID_FS_VAL 22353
#define DEVICE_ID1 0x20220000
#define DEVICE_ID2 0x1E0000
#define DEVICE_ID3 0x1123
#elif (HID_CLASS_MODE == (HID_KEYBOARD | HID_CUSTOM))
#define VID_VAL 1156
#define LANG_ID_STR 1033
#define PID_FS_VAL 22354
#define DEVICE_ID1 0x20220000
#define DEVICE_ID2 0x200000
#define DEVICE_ID3 0x1215
#elif (HID_CLASS_MODE == (HID_KEYBOARD | HID_MOUSE))
#define VID_VAL 1157
#define LANG_ID_STR 1033
#define PID_FS_VAL 22355
#define DEVICE_ID1 0x20230000
#define DEVICE_ID2 0x210000
#define DEVICE_ID3 0x0228
#endif
#define DEV_CLASS 0x00
#define DEV_SUB_CLASS 0x00
#define DEV_PROTOCOL 0x00
#define USB_SIZ_STRING_SERIAL 0x1A
/**
* @}
*/
/*------------------------------------------------------------------------------------
Global Variables
-------------------------------------------------------------------------------------*/
/** Descriptor for the Usb device. */
extern USBD_DescriptorsTypeDef FS_Desc;
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBD_DESC__C__ */
@@ -0,0 +1,194 @@
/*!
* \file usb_device.c
*
* \brief Target usb device implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usb_device.h"
#include "usbd_core.h"
#include "usbd_desc.h"
#include "usbd_hid.h"
/*------------------------------------------------------------------------------------
Macros
-------------------------------------------------------------------------------------*/
#define CURSOR_STEP 2U
#define CURSOR_WIDTH 200U
/*------------------------------------------------------------------------------------
Global Variables
-------------------------------------------------------------------------------------*/
/* USB Device Core handle declaration. */
USBD_HandleTypeDef hUsbDeviceFS;
/*------------------------------------------------------------------------------------
Functions
-------------------------------------------------------------------------------------*/
/**
* @brief This function handles USB On The Go FS global interrupt.
* @param void
* @retval void
*/
void USB_Handler(void) { HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS); }
/**
* @brief Init USB device Library, add supported class and start the library
* @param void
* @retval void
*/
void USB_DEVICE_Init(void)
{
/* Init Device Library, add supported class and start the library. */
if (USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS) != USBD_OK) {
Error_Handler();
}
if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_HID) != USBD_OK) {
Error_Handler();
}
if (USBD_Start(&hUsbDeviceFS) != USBD_OK) {
Error_Handler();
}
}
#if ((HID_CLASS_MODE & HID_MOUSE) == HID_MOUSE)
/**
* @brief Mouse get pointer datas
* @param uint8_t *pbuf
* @retval void
*/
void GetPointerData(uint8_t *pbuf)
{
static int32_t move_cnt = 0;
static uint8_t step_x_y = 0;
static int8_t x = 0, y = 0;
static uint16_t cnt = 0;
move_cnt++;
if (move_cnt > CURSOR_WIDTH) {
step_x_y++;
step_x_y = step_x_y % 4;
move_cnt = 0;
}
switch (step_x_y) {
case 0: {
y = 0;
x = CURSOR_STEP;
} break;
case 1: {
x = 0;
y = CURSOR_STEP;
} break;
case 2: {
y = 0;
x = (int8_t)(-CURSOR_STEP);
} break;
case 3: {
x = 0;
y = (int8_t)(-CURSOR_STEP);
} break;
}
cnt++;
if (cnt > 1000) {
if (pbuf[0] != 16)
pbuf[0] = 16;
else
pbuf[0] = 0;
cnt = 0;
}
pbuf[1] = x;
pbuf[2] = y;
pbuf[3] = 0;
}
/**
* @brief Usb mouse test send report
* @param void
* @retval void
*/
void USB_Mouse_Test_SendReport(void)
{
uint8_t buff[4] = {0};
#if (HID_CLASS_MODE == (HID_KEYBOARD | HID_MOUSE))
USBD_Mouse_HID_SendReport(&hUsbDeviceFS, buff, HID_EP2IN_SIZE);
#elif (HID_CLASS_MODE == (HID_CUSTOM | HID_MOUSE))
USBD_Mouse_HID_SendReport(&hUsbDeviceFS, buff, HID_EPIN_SIZE);
#endif
}
#endif
#if ((HID_CLASS_MODE & HID_CUSTOM) == HID_CUSTOM)
#define CUSTOM_SR_LEN 64U
/**
* @brief Usb custom hid test send report
* @param void
* @retval void
*/
void USB_Custom_Test_SendReport(void)
{
uint8_t usb_tx_data[CUSTOM_SR_LEN] = {0};
for (uint8_t i = 0; i < CUSTOM_SR_LEN; i++)
usb_tx_data[i] = i;
USBD_Custom_HID_SendReport(&hUsbDeviceFS, usb_tx_data, CUSTOM_SR_LEN);
}
#endif
#if (HID_CLASS_MODE == HID_DOUBLE_CUSTOM)
/**
* @brief Usb custom1 hid test send report
* @param void
* @retval void
*/
void USB_Custom1_Test_SendReport(void)
{
uint8_t usb_tx_data[64] = {0};
usb_tx_data[0] = 0x81;
for (uint8_t i = 1; i < 64; i++)
usb_tx_data[i] = i;
USBD_Custom1_HID_SendReport(&hUsbDeviceFS, usb_tx_data, 64);
}
/**
* @brief Usb custom2 hid test send report
* @param void
* @retval void
*/
void USB_Custom2_Test_SendReport(void)
{
uint8_t usb_tx_data[64] = {0};
usb_tx_data[0] = 0x82;
for (uint8_t i = 1; i < 64; i++)
usb_tx_data[i] = i;
USBD_Custom2_HID_SendReport(&hUsbDeviceFS, usb_tx_data, 64);
}
#endif
@@ -0,0 +1,56 @@
/*!
* \file usb_device.h
*
* \brief Target usb device implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_DEVICE_H__
#define __USB_DEVICE_H__
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_def.h"
/*------------------------------------------------------------------------------------
Exported Functions
-------------------------------------------------------------------------------------*/
void USB_DEVICE_Init( void );
uint8_t USB_Dev_State_Judge(uint8_t * rtc_cnt);
void USB_Mouse_Test_SendReport( void );
void USB_Custom_Test_SendReport( void );
#if (HID_CLASS_MODE == HID_DOUBLE_CUSTOM)
void USB_Custom1_Test_SendReport( void );
void USB_Custom2_Test_SendReport( void );
#endif
#ifdef __cplusplus
}
#endif
#endif /* __USB_DEVICE_H__ */
@@ -0,0 +1,351 @@
/*!
* \file usbd_desc.c
*
* \brief Target the USB device descriptors implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_desc.h"
#include "usbd_conf.h"
#include "usbd_core.h"
/*------------------------------------------------------------------------------------
Macros
-------------------------------------------
-----------------------------------------*/
/** @defgroup USBD_DESC_Private_Defines USBD_DESC_Private_Defines
* @brief Private defines.
* @{
*/
#define USBD_VID VID_VAL
#define USBD_LANGID_STRING LANG_ID_STR
#define USBD_MANUFACTURER_STRING "XinChip"
#define USBD_PID_FS PID_FS_VAL
#define USBD_PRODUCT_STRING_FS "XinChip Human interface"
#define USBD_CONFIGURATION_STRING_FS "HID Config"
#define USBD_INTERFACE_STRING_FS "HID Interface"
#define USB_SIZ_BOS_DESC 0x0C
/*------------------------------------------------------------------------------------
Func Prototypes
-------------------------------------------------------------------------------------*/
/** @defgroup USBD_DESC_Private_FunctionPrototypes
* USBD_DESC_Private_FunctionPrototypes
* @brief Private functions declaration.
* @{
*/
static void Get_SerialNum(void);
static void IntToUnicode(uint32_t value, uint8_t *pbuf, uint8_t len);
/** @defgroup USBD_DESC_Private_FunctionPrototypes
* USBD_DESC_Private_FunctionPrototypes
* @brief Private functions declaration for FS.
* @{
*/
uint8_t *USBD_FS_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *USBD_FS_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *USBD_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed,
uint16_t *length);
uint8_t *USBD_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed,
uint16_t *length);
uint8_t *USBD_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *USBD_FS_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *USBD_FS_InterfaceStrDescriptor(USBD_SpeedTypeDef speed,
uint16_t *length);
#if (USBD_LPM_ENABLED == 1)
uint8_t *USBD_FS_USR_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
#endif /* (USBD_LPM_ENABLED == 1) */
/*------------------------------------------------------------------------------------
Local Variables
-------------------------------------------------------------------------------------*/
/** @defgroup USBD_DESC_Private_Variables USBD_DESC_Private_Variables
* @brief Private variables.
* @{
*/
USBD_DescriptorsTypeDef FS_Desc = {USBD_FS_DeviceDescriptor,
USBD_FS_LangIDStrDescriptor,
USBD_FS_ManufacturerStrDescriptor,
USBD_FS_ProductStrDescriptor,
USBD_FS_SerialStrDescriptor,
USBD_FS_ConfigStrDescriptor,
USBD_FS_InterfaceStrDescriptor
#if (USBD_LPM_ENABLED == 1)
,
USBD_FS_USR_BOSDescriptor
#endif /* (USBD_LPM_ENABLED == 1) */
};
#if defined(__ICCARM__) /* IAR Compiler */
#pragma data_alignment = 4
#endif /* defined ( __ICCARM__ ) */
/** USB standard device descriptor. */
__ALIGN_BEGIN uint8_t USBD_FS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
0x12, /*bLength */
USB_DESC_TYPE_DEVICE, /*bDescriptorType*/
#if (USBD_LPM_ENABLED == 1)
0x01,
/*bcdUSB */ /* changed to USB version 2.01
in order to support LPM L1 suspend
resume test of USBCV3.0*/
#else
0x00, /*bcdUSB */
#endif /* (USBD_LPM_ENABLED == 1) */
0x02,
DEV_CLASS, /*bDeviceClass*/
DEV_SUB_CLASS, /*bDeviceSubClass*/
DEV_PROTOCOL, /*bDeviceProtocol*/
USB_MAX_EP0_SIZE, /*bMaxPacketSize*/
LOBYTE(USBD_VID), /*idVendor*/
HIBYTE(USBD_VID), /*idVendor*/
LOBYTE(USBD_PID_FS), /*idProduct*/
HIBYTE(USBD_PID_FS), /*idProduct*/
0x00, /*bcdDevice rel. 2.00*/
0x02,
USBD_IDX_MFC_STR, /*Index of manufacturer string*/
USBD_IDX_PRODUCT_STR, /*Index of product string*/
USBD_IDX_SERIAL_STR, /*Index of serial number string*/
USBD_MAX_NUM_CONFIGURATION /*bNumConfigurations*/
};
/* USB_DeviceDescriptor */
/** BOS descriptor. */
#if (USBD_LPM_ENABLED == 1)
#if defined(__ICCARM__) /* IAR Compiler */
#pragma data_alignment = 4
#endif /* defined ( __ICCARM__ ) */
__ALIGN_BEGIN uint8_t USBD_FS_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END = {
0x5, USB_DESC_TYPE_BOS, 0xC, 0x0, 0x1, /* 1 device capability*/
/* device capability*/
0x7, USB_DEVICE_CAPABITY_TYPE, 0x2, 0x2, /* LPM capability bit set*/
0x0, 0x0, 0x0};
#endif /* (USBD_LPM_ENABLED == 1) */
/** @defgroup USBD_DESC_Private_Variables USBD_DESC_Private_Variables
* @brief Private variables.
* @{
*/
#if defined(__ICCARM__) /* IAR Compiler */
#pragma data_alignment = 4
#endif /* defined ( __ICCARM__ ) */
/** USB lang identifier descriptor. */
__ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = {
USB_LEN_LANGID_STR_DESC, USB_DESC_TYPE_STRING, LOBYTE(USBD_LANGID_STRING),
HIBYTE(USBD_LANGID_STRING)};
#if defined(__ICCARM__) /* IAR Compiler */
#pragma data_alignment = 4
#endif /* defined ( __ICCARM__ ) */
/* Internal string descriptor. */
__ALIGN_BEGIN uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END;
#if defined(__ICCARM__) /*!< IAR Compiler */
#pragma data_alignment = 4
#endif
__ALIGN_BEGIN uint8_t USBD_StringSerial[USB_SIZ_STRING_SERIAL] __ALIGN_END = {
USB_SIZ_STRING_SERIAL,
USB_DESC_TYPE_STRING,
};
/*------------------------------------------------------------------------------------
Functions
-------------------------------------------------------------------------------------*/
/**
* @brief Return the device descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_FS_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
*length = sizeof(USBD_FS_DeviceDesc);
return USBD_FS_DeviceDesc;
}
/**
* @brief Return the LangID string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_FS_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
UNUSED(speed);
*length = sizeof(USBD_LangIDDesc);
return USBD_LangIDDesc;
}
/**
* @brief Return the product string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
if (speed == 0) {
USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length);
} else {
USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length);
}
return USBD_StrDesc;
}
/**
* @brief Return the manufacturer string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed,
uint16_t *length)
{
UNUSED(speed);
USBD_GetString((uint8_t *)USBD_MANUFACTURER_STRING, USBD_StrDesc, length);
return USBD_StrDesc;
}
/**
* @brief Return the serial number string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
UNUSED(speed);
*length = USB_SIZ_STRING_SERIAL;
/* Update the serial number string descriptor with the data from the unique
* ID */
Get_SerialNum();
/* USER CODE BEGIN USBD_FS_SerialStrDescriptor */
/* USER CODE END USBD_FS_SerialStrDescriptor */
return (uint8_t *)USBD_StringSerial;
}
/**
* @brief Return the configuration string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_FS_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
if (speed == USBD_SPEED_HIGH) {
USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING_FS, USBD_StrDesc,
length);
} else {
USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING_FS, USBD_StrDesc,
length);
}
return USBD_StrDesc;
}
/**
* @brief Return the interface string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_FS_InterfaceStrDescriptor(USBD_SpeedTypeDef speed,
uint16_t *length)
{
if (speed == 0) {
USBD_GetString((uint8_t *)USBD_INTERFACE_STRING_FS, USBD_StrDesc,
length);
} else {
USBD_GetString((uint8_t *)USBD_INTERFACE_STRING_FS, USBD_StrDesc,
length);
}
return USBD_StrDesc;
}
#if (USBD_LPM_ENABLED == 1)
/**
* @brief Return the BOS descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_FS_USR_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
UNUSED(speed);
*length = sizeof(USBD_FS_BOSDesc);
return (uint8_t *)USBD_FS_BOSDesc;
}
#endif /* (USBD_LPM_ENABLED == 1) */
/**
* @brief Create the serial number string descriptor
* @param None
* @retval None
*/
static void Get_SerialNum(void)
{
uint32_t deviceserial0, deviceserial1, deviceserial2;
deviceserial0 = DEVICE_ID1;
deviceserial1 = DEVICE_ID2;
deviceserial2 = DEVICE_ID3;
deviceserial0 += deviceserial2;
if (deviceserial0 != 0) {
IntToUnicode(deviceserial0, &USBD_StringSerial[2], 8);
IntToUnicode(deviceserial1, &USBD_StringSerial[18], 4);
}
}
/**
* @brief Convert Hex 32Bits value into char
* @param value: value to convert
* @param pbuf: pointer to the buffer
* @param len: buffer length
* @retval None
*/
static void IntToUnicode(uint32_t value, uint8_t *pbuf, uint8_t len)
{
uint8_t idx = 0;
for (idx = 0; idx < len; idx++) {
if (((value >> 28)) < 0xA) {
pbuf[2 * idx] = (value >> 28) + '0';
} else {
pbuf[2 * idx] = (value >> 28) + 'A' - 10;
}
value = value << 4;
pbuf[2 * idx + 1] = 0;
}
}
/**
* @}
*/
@@ -0,0 +1,128 @@
/*!
* \file usbd_desc.h
*
* \brief Target the USB device descriptors implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_DESC__C__
#define __USBD_DESC__C__
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_def.h"
/*------------------------------------------------------------------------------------
Macros
-------------------------------------------------------------------------------------*/
/** @defgroup USBD_DESC_Exported_Constants USBD_DESC_Exported_Constants
* @brief Constants.
* @{
*/
#if (HID_CLASS_MODE == HID_MOUSE)
#define VID_VAL 1155
#define LANG_ID_STR 1033
#define PID_FS_VAL 17799
#define DEVICE_ID1 0x20220000
#define DEVICE_ID2 0x1D0000
#define DEVICE_ID3 0x1122
#elif (HID_CLASS_MODE == HID_KEYBOARD)
#define VID_VAL 1155
#define LANG_ID_STR 1033
#define PID_FS_VAL 17780
#define DEVICE_ID1 0x20220000
#define DEVICE_ID2 0x1F0000
#define DEVICE_ID3 0x1123
#elif (HID_CLASS_MODE == HID_CUSTOM)
#define VID_VAL 1155
#define LANG_ID_STR 1033
#define PID_FS_VAL 17781
#define DEVICE_ID1 0x20220000
#define DEVICE_ID2 0x1F0000
#define DEVICE_ID3 0x1124
#elif (HID_CLASS_MODE == (HID_MOUSE | HID_CUSTOM))
#define VID_VAL 1156
#define LANG_ID_STR 1033
#define PID_FS_VAL 22353
#define DEVICE_ID1 0x20220000
#define DEVICE_ID2 0x1E0000
#define DEVICE_ID3 0x1123
#elif (HID_CLASS_MODE == (HID_KEYBOARD | HID_CUSTOM))
#define VID_VAL 1156
#define LANG_ID_STR 1033
#define PID_FS_VAL 22354
#define DEVICE_ID1 0x20220000
#define DEVICE_ID2 0x200000
#define DEVICE_ID3 0x1215
#elif (HID_CLASS_MODE == (HID_KEYBOARD | HID_MOUSE))
#define VID_VAL 1157
#define LANG_ID_STR 1033
#define PID_FS_VAL 22355
#define DEVICE_ID1 0x20230000
#define DEVICE_ID2 0x210000
#define DEVICE_ID3 0x0228
#elif (HID_CLASS_MODE == HID_DOUBLE_CUSTOM)
#define VID_VAL 1158
#define LANG_ID_STR 1033
#define PID_FS_VAL 22356
#define DEVICE_ID1 0x20230000
#define DEVICE_ID2 0x210000
#define DEVICE_ID3 0x0816
#endif
#define DEV_CLASS 0x00
#define DEV_SUB_CLASS 0x00
#define DEV_PROTOCOL 0x00
#define USB_SIZ_STRING_SERIAL 0x1A
/**
* @}
*/
/*------------------------------------------------------------------------------------
Global Variables
-------------------------------------------------------------------------------------*/
/** Descriptor for the Usb device. */
extern USBD_DescriptorsTypeDef FS_Desc;
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBD_DESC__C__ */
@@ -0,0 +1,274 @@
/*!
* \file msc_flash.c
*
* \brief Target fatfs flash implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "msc_flash.h"
/*------------------------------------------------------------------------------------
Local Variables
-------------------------------------------
-----------------------------------------*/
uint8_t spim_init = false;
#define FLASH_SECTOR_ALIGN(address) \
((uint32_t)(address) & ~(FAT_FLASH_SECTOR_SIZE - 1))
#define FLASH_SECTOR_OFFSET(address) \
((uint32_t)(address) & (FAT_FLASH_SECTOR_SIZE - 1))
static uint8_t dataBuffer[FAT_FLASH_SECTOR_SIZE] = {0};
/*------------------------------------------------------------------------------------
Functions
-------------------------------------------
-----------------------------------------*/
/**
* @brief FatFs flash read id
* @param void
* @retval uint32_t - id
*/
uint32_t Fat_Flash_ReadID(void)
{
uint32_t id = 0;
DEBUG("id\r");
if (XR_OK == spi_flash_rdid(XC_SPI0, (uint8_t *)&id)) {
DEBUG("read id :0x%08x\r\n", id);
return id;
}
return id;
}
/**
* @brief FatFs flash chip erase
* @param void
* @retval bool - true or false
*/
bool Fat_Flash_ChipErase(void)
{
uint32_t offset_cnt =
(FAT_FLASH_END_ADDR - FAT_FLASH_START_ADDR + 1) / FAT_FLASH_SECTOR_SIZE;
for (uint32_t i = 0; i < offset_cnt; i++) {
if (XR_OK !=
xc_spi_flash_erase_sector(XC_SPI0, FAT_FLASH_START_ADDR +
i * FAT_FLASH_SECTOR_SIZE))
return false;
}
return true;
}
/**
* @brief FatFs flash sector erase
* @param void
* @retval bool - true or false
*/
bool Fat_Flash_SectorErase(uint32_t address)
{
if (XR_OK == xc_spi_flash_erase_sector(XC_SPI0, address))
return true;
return false;
}
/**
* @brief FatFs flash write data
* @param void
* @retval bool - true or false
*/
bool Fat_Flash_WriteData(uint32_t address, uint8_t *buffer, uint16_t length)
{
uint16_t writeLen, pageOff;
while (length > 0) {
pageOff = FLASH_PAGE_SIZE - (address % FLASH_PAGE_SIZE);
writeLen = length > pageOff ? pageOff : length;
if (XR_OK == spi_write_bytes(XC_SPI0, address, buffer, writeLen)) {
length -= writeLen;
address += writeLen;
buffer += writeLen;
} else
return false;
}
return true;
}
/**
* @brief FatFs flash read data
* @param void
* @retval bool - true or false
*/
bool Fat_Flash_ReadData(uint32_t address, uint8_t *buffer, uint16_t length)
{
if (XR_OK == spi_flash_read(XC_SPI0, address, buffer, length))
return true;
return false;
}
/**
* @brief FatFs flash data are write in units of 512 bytes
* @param void
* @retval bool - true or false
*/
bool Fat_Flash_Write_512B(uint32_t address, uint8_t count, uint8_t *data)
{
uint32_t sectorAddress;
uint32_t sectorOffset;
address += FAT_FLASH_START_ADDR;
if (address >= FAT_FLASH_END_ADDR)
return false;
// count *= 2;
while (count > 0) {
sectorAddress = FLASH_SECTOR_ALIGN(address);
sectorOffset = FLASH_SECTOR_OFFSET(address);
Fat_Flash_ReadData(sectorAddress, dataBuffer, FAT_FLASH_SECTOR_SIZE);
Fat_Flash_SectorErase(address);
while (count > 0) {
memcpy(dataBuffer + sectorOffset, data, DISK_UNIT_SIZE);
data += DISK_UNIT_SIZE;
address += DISK_UNIT_SIZE;
count -= 1;
sectorOffset += DISK_UNIT_SIZE;
if ((sectorOffset & (FAT_FLASH_SECTOR_SIZE - 1)) == 0) {
break;
}
}
if (false == Fat_Flash_WriteData(sectorAddress, dataBuffer,
FAT_FLASH_SECTOR_SIZE))
return false;
}
return true;
}
/**
* @brief FatFs flash data are read in units of 512 bytes
* @param void
* @retval bool - true or false
*/
bool Fat_Flash_Read_512B(uint32_t address, uint8_t count, uint8_t *data)
{
address += FAT_FLASH_START_ADDR;
if (address >= FAT_FLASH_END_ADDR)
return false;
// count *= 2;
while (count--) {
if (true == Fat_Flash_ReadData(address, data, (DISK_UNIT_SIZE))) {
data += (DISK_UNIT_SIZE);
address += (DISK_UNIT_SIZE);
} else {
return false;
}
}
return true;
}
/*----------------------------- Disk Map -----------------------------------*/
/**
* @brief Disk init
* @param void
* @retval bool - true or false
*/
bool Disk_Init(void)
{
if (spim_init == false) {
SPI_Flash_Init();
spim_init = true;
}
return true;
}
/**
* @brief Disk erase
* @param void
* @retval bool - true or false
*/
bool Disk_Erase(void)
{
if (true == Fat_Flash_ChipErase())
return true;
return false;
}
/**
* @brief Disk unit size
* @param void
* @retval uint16_t - size
*/
uint16_t Disk_UnitSize(void) { return DISK_UNIT_SIZE; }
/**
* @brief Disk unit count
* @param void
* @retval uint32_t - count
*/
uint32_t Disk_UnitCount(void)
{
uint32_t count = 0;
count = (FAT_FLASH_END_ADDR - FAT_FLASH_START_ADDR + 1) /
FAT_FLASH_PAGE_SIZE / 2;
return count;
}
/**
* @brief Disk unit data read
* @param void
* @retval bool - true or false
*/
bool Disk_UnitRead(uint32_t unitAddr, uint16_t unitCount, uint8_t *data)
{
if (true == Fat_Flash_Read_512B(unitAddr * 512, unitCount, data))
return true;
return false;
}
/**
* @brief Disk unit data write
* @param void
* @retval bool - true or false
*/
bool Disk_UnitWrite(uint32_t unitAddr, uint16_t unitCount, uint8_t *data)
{
if (true == Fat_Flash_Write_512B(unitAddr * 512, unitCount, data))
return true;
return false;
}
/*--------------------------------------------------------------------------*/
@@ -0,0 +1,72 @@
/*!
* \file msc_flash.h
*
* \brief Target msc flash implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MSC_FLASH_H__
#define __MSC_FLASH_H__
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "xc6xxx_hal_spi.h"
/*------------------------------------------------------------------------------------
Macros
-------------------------------------------------------------------------------------*/
#define FAT_FLASH_ID 0x12408500 //0x00136085
#define FAT_FLASH_PAGE_SIZE 256U
#define FAT_FLASH_SECTOR_SIZE 4096u
#define FAT_FLASH_START_ADDR 0x20000 //0x40000
#define FAT_FLASH_END_ADDR 0x40000 //0x7FFFF
#define DISK_UNIT_SIZE 512U
/*------------------------------------------------------------------------------------
Exported Functions
------------------------------------------- -----------------------------------------*/
uint32_t Fat_Flash_ReadID( void );
bool Disk_Init( void );
bool Disk_Erase( void );
uint16_t Disk_UnitSize( void );
uint32_t Disk_UnitCount( void );
bool Disk_UnitRead( uint32_t unitAddr, uint16_t unitCount, uint8_t *data );
bool Disk_UnitWrite( uint32_t unitAddr, uint16_t unitCount, uint8_t *data );
#ifdef __cplusplus
}
#endif
#endif /* __MAIN_H */
@@ -0,0 +1,71 @@
/*!
* \file usb_device.c
*
* \brief Target usb device implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usb_device.h"
#include "usbd_core.h"
#include "usbd_desc.h"
#include "usbd_msc.h"
#include "usbd_storage_if.h"
/*------------------------------------------------------------------------------------
Global Variables
-------------------------------------------------------------------------------------*/
/* USB Device Core handle declaration. */
USBD_HandleTypeDef hUsbDeviceFS;
/*------------------------------------------------------------------------------------
Functions
-------------------------------------------------------------------------------------*/
/**
* @brief This function handles USB On The Go FS global interrupt.
* @param void
* @retval void
*/
void USB_Handler(void) { HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS); }
/**
* @brief Init USB device Library, add supported class and start the library
* @param void
* @retval void
*/
void USB_DEVICE_Init(void)
{
/* Init Device Library, add supported class and start the library. */
if (USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS) != USBD_OK) {
Error_Handler();
}
if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_MSC) != USBD_OK) {
Error_Handler();
}
if (USBD_MSC_RegisterStorage(&hUsbDeviceFS,
&USBD_Storage_Interface_fops_FS) != USBD_OK) {
Error_Handler();
}
if (USBD_Start(&hUsbDeviceFS) != USBD_OK) {
Error_Handler();
}
}
@@ -0,0 +1,47 @@
/*!
* \file usb_device.h
*
* \brief Target usb device implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_DEVICE_H__
#define __USB_DEVICE_H__
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_def.h"
/*------------------------------------------------------------------------------------
Exported Functions
-------------------------------------------------------------------------------------*/
void USB_DEVICE_Init( void );
#ifdef __cplusplus
}
#endif
#endif /* __USB_DEVICE_H__ */
@@ -0,0 +1,358 @@
/*!
* \file usbd_desc.c
*
* \brief Target the USB device descriptors implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_desc.h"
#include "usbd_conf.h"
#include "usbd_core.h"
/*------------------------------------------------------------------------------------
Macros
-------------------------------------------
-----------------------------------------*/
/** @defgroup USBD_DESC_Private_Defines USBD_DESC_Private_Defines
* @brief Private defines.
* @{
*/
#define USBD_VID 0x0483 // 1155
#define USBD_LANGID_STRING 0x0409 // 1033
#define USBD_MANUFACTURER_STRING "XinChip" //"XinChip"
#define USBD_PID_FS 22314 // 17788
#define USBD_PRODUCT_STRING_FS "XinChip Mass Storage" //"XinChip Mass Storage"
#define USBD_CONFIGURATION_STRING_FS "MSC Config"
#define USBD_INTERFACE_STRING_FS "MSC Interface"
#define USB_SIZ_BOS_DESC 0x0C
/*------------------------------------------------------------------------------------
Func Prototypes
-------------------------------------------
-----------------------------------------*/
/** @defgroup USBD_DESC_Private_FunctionPrototypes
* USBD_DESC_Private_FunctionPrototypes
* @brief Private functions declaration.
* @{
*/
static void Get_SerialNum(void);
static void IntToUnicode(uint32_t value, uint8_t *pbuf, uint8_t len);
/** @defgroup USBD_DESC_Private_FunctionPrototypes
* USBD_DESC_Private_FunctionPrototypes
* @brief Private functions declaration for FS.
* @{
*/
uint8_t *USBD_FS_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *USBD_FS_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *USBD_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed,
uint16_t *length);
uint8_t *USBD_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed,
uint16_t *length);
uint8_t *USBD_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *USBD_FS_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *USBD_FS_InterfaceStrDescriptor(USBD_SpeedTypeDef speed,
uint16_t *length);
#if (USBD_LPM_ENABLED == 1)
uint8_t *USBD_FS_USR_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
#endif /* (USBD_LPM_ENABLED == 1) */
/*------------------------------------------------------------------------------------
Local Variables
-------------------------------------------------------------------------------------*/
/** @defgroup USBD_DESC_Private_Variables USBD_DESC_Private_Variables
* @brief Private variables.
* @{
*/
USBD_DescriptorsTypeDef FS_Desc = {USBD_FS_DeviceDescriptor,
USBD_FS_LangIDStrDescriptor,
USBD_FS_ManufacturerStrDescriptor,
USBD_FS_ProductStrDescriptor,
USBD_FS_SerialStrDescriptor,
USBD_FS_ConfigStrDescriptor,
USBD_FS_InterfaceStrDescriptor
#if (USBD_LPM_ENABLED == 1)
,
USBD_FS_USR_BOSDescriptor
#endif /* (USBD_LPM_ENABLED == 1) */
};
#if defined(__ICCARM__) /* IAR Compiler */
#pragma data_alignment = 4
#endif /* defined ( __ICCARM__ ) */
/** USB standard device descriptor. */
__ALIGN_BEGIN uint8_t USBD_FS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
0x12, /*bLength */
USB_DESC_TYPE_DEVICE, /*bDescriptorType*/
#if (USBD_LPM_ENABLED == 1)
0x01,
/*bcdUSB */ /* changed to USB version 2.01
in order to support LPM L1 suspend
resume test of USBCV3.0*/
#else
0x00, /*bcdUSB */
#endif /* (USBD_LPM_ENABLED == 1) */
0x02,
0x00, /*bDeviceClass*/
0x00, /*bDeviceSubClass*/
0x00, /*bDeviceProtocol*/
USB_MAX_EP0_SIZE, /*bMaxPacketSize*/
LOBYTE(USBD_VID), /*idVendor*/
HIBYTE(USBD_VID), /*idVendor*/
LOBYTE(USBD_PID_FS), /*idProduct*/
HIBYTE(USBD_PID_FS), /*idProduct*/
0x00, /*bcdDevice rel. 2.00*/
0x02,
USBD_IDX_MFC_STR, /*Index of manufacturer string*/
USBD_IDX_PRODUCT_STR, /*Index of product string*/
USBD_IDX_SERIAL_STR, /*Index of serial number string*/
USBD_MAX_NUM_CONFIGURATION /*bNumConfigurations*/
};
/* USB_DeviceDescriptor */
/** BOS descriptor. */
#if (USBD_LPM_ENABLED == 1)
#if defined(__ICCARM__) /* IAR Compiler */
#pragma data_alignment = 4
#endif /* defined ( __ICCARM__ ) */
__ALIGN_BEGIN uint8_t USBD_FS_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END = {
0x5, USB_DESC_TYPE_BOS, 0xC, 0x0, 0x1, /* 1 device capability*/
/* device capability*/
0x7, USB_DEVICE_CAPABITY_TYPE, 0x2, 0x2, /* LPM capability bit set*/
0x0, 0x0, 0x0};
#endif /* (USBD_LPM_ENABLED == 1) */
/** @defgroup USBD_DESC_Private_Variables USBD_DESC_Private_Variables
* @brief Private variables.
* @{
*/
#if defined(__ICCARM__) /* IAR Compiler */
#pragma data_alignment = 4
#endif /* defined ( __ICCARM__ ) */
/** USB lang identifier descriptor. */
__ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = {
USB_LEN_LANGID_STR_DESC, USB_DESC_TYPE_STRING, LOBYTE(USBD_LANGID_STRING),
HIBYTE(USBD_LANGID_STRING)};
#if defined(__ICCARM__) /* IAR Compiler */
#pragma data_alignment = 4
#endif /* defined ( __ICCARM__ ) */
/* Internal string descriptor. */
__ALIGN_BEGIN uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END;
#if defined(__ICCARM__) /*!< IAR Compiler */
#pragma data_alignment = 4
#endif
__ALIGN_BEGIN uint8_t USBD_StringSerial[USB_SIZ_STRING_SERIAL] __ALIGN_END = {
USB_SIZ_STRING_SERIAL,
USB_DESC_TYPE_STRING,
};
/*------------------------------------------------------------------------------------
Functions
-------------------------------------------------------------------------------------*/
/**
* @brief Return the device descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_FS_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
UNUSED(speed);
*length = sizeof(USBD_FS_DeviceDesc);
return USBD_FS_DeviceDesc;
}
/**
* @brief Return the LangID string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_FS_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
UNUSED(speed);
*length = sizeof(USBD_LangIDDesc);
return USBD_LangIDDesc;
}
/**
* @brief Return the product string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
if (speed == 0) {
USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length);
} else {
USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length);
}
return USBD_StrDesc;
}
/**
* @brief Return the manufacturer string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed,
uint16_t *length)
{
UNUSED(speed);
USBD_GetString((uint8_t *)USBD_MANUFACTURER_STRING, USBD_StrDesc, length);
return USBD_StrDesc;
}
/**
* @brief Return the serial number string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
UNUSED(speed);
*length = USB_SIZ_STRING_SERIAL;
/* Update the serial number string descriptor with the data from the unique
* ID */
Get_SerialNum();
/* USER CODE BEGIN USBD_FS_SerialStrDescriptor */
/* USER CODE END USBD_FS_SerialStrDescriptor */
return (uint8_t *)USBD_StringSerial;
}
/**
* @brief Return the configuration string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_FS_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
if (speed == USBD_SPEED_HIGH) {
USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING_FS, USBD_StrDesc,
length);
} else {
USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING_FS, USBD_StrDesc,
length);
}
return USBD_StrDesc;
}
/**
* @brief Return the interface string descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_FS_InterfaceStrDescriptor(USBD_SpeedTypeDef speed,
uint16_t *length)
{
if (speed == 0) {
USBD_GetString((uint8_t *)USBD_INTERFACE_STRING_FS, USBD_StrDesc,
length);
} else {
USBD_GetString((uint8_t *)USBD_INTERFACE_STRING_FS, USBD_StrDesc,
length);
}
return USBD_StrDesc;
}
#if (USBD_LPM_ENABLED == 1)
/**
* @brief Return the BOS descriptor
* @param speed : Current device speed
* @param length : Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_FS_USR_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
INFO("\n");
UNUSED(speed);
*length = sizeof(USBD_FS_BOSDesc);
return (uint8_t *)USBD_FS_BOSDesc;
}
#endif /* (USBD_LPM_ENABLED == 1) */
/**
* @brief Create the serial number string descriptor
* @param None
* @retval None
*/
static void Get_SerialNum(void)
{
uint32_t deviceserial0, deviceserial1; //, deviceserial2;
// deviceserial0 = *(uint32_t *) DEVICE_ID1;
// deviceserial1 = *(uint32_t *) DEVICE_ID2;
// deviceserial2 = *(uint32_t *) DEVICE_ID3;
deviceserial0 = 0x20220902; // 5177440; //0;//5177402;
deviceserial1 = 0x1A0000; // 1395675155; //0x001A0000;
// deviceserial2 = //540488500; //0;
// deviceserial0 += deviceserial2;
if (deviceserial0 != 0) {
IntToUnicode(deviceserial0, &USBD_StringSerial[2], 8);
IntToUnicode(deviceserial1, &USBD_StringSerial[18], 4);
}
}
/**
* @brief Convert Hex 32Bits value into char
* @param value: value to convert
* @param pbuf: pointer to the buffer
* @param len: buffer length
* @retval None
*/
static void IntToUnicode(uint32_t value, uint8_t *pbuf, uint8_t len)
{
uint8_t idx = 0;
for (idx = 0; idx < len; idx++) {
if (((value >> 28)) < 0xA) {
pbuf[2 * idx] = (value >> 28) + '0';
} else {
pbuf[2 * idx] = (value >> 28) + 'A' - 10;
}
value = value << 4;
pbuf[2 * idx + 1] = 0;
}
}
/**
* @}
*/
@@ -0,0 +1,70 @@
/*!
* \file usbd_desc.h
*
* \brief Target the USB device descriptors implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_DESC__C__
#define __USBD_DESC__C__
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_def.h"
/*------------------------------------------------------------------------------------
Macros
------------------------------------------- -----------------------------------------*/
/** @defgroup USBD_DESC_Exported_Constants USBD_DESC_Exported_Constants
* @brief Constants.
* @{
*/
#define DEVICE_ID1 (UID_BASE)
#define DEVICE_ID2 (UID_BASE + 0x4)
#define DEVICE_ID3 (UID_BASE + 0x8)
#define USB_SIZ_STRING_SERIAL 0x1A
/**
* @}
*/
/*------------------------------------------------------------------------------------
Global Variables
-------------------------------------------------------------------------------------*/
/** Descriptor for the Usb device. */
extern USBD_DescriptorsTypeDef FS_Desc;
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBD_DESC__C__ */
@@ -0,0 +1,242 @@
/*!
* \file usbd_storage_if.c
*
* \brief Memory management layer.
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_storage_if.h"
#include "msc_flash.h"
/*------------------------------------------------------------------------------------
Macros
-------------------------------------------
-----------------------------------------*/
/** @defgroup USBD_STORAGE_Private_Defines
* @brief Private defines.
* @{
*/
#define STORAGE_LUN_NBR 1
#define STORAGE_BLK_NBR 0x48
#define STORAGE_BLK_SIZ 0x200
/*------------------------------------------------------------------------------------
Consts
-------------------------------------------
-----------------------------------------*/
/* USER CODE BEGIN INQUIRY_DATA_FS */
/** USB Mass storage Standard Inquiry Data. */
const int8_t STORAGE_Inquirydata_FS[] = {
/* 36 */
/* LUN 0 */
0x00, 0x80, 0x02, 0x02, (STANDARD_INQUIRY_DATA_LEN - 5),
0x00, 0x00, 0x00, 'X', 'i',
'n', 'C', 'h', 'i', 'p',
' ', /* Manufacturer : 8 bytes */
'P', 'r', 'o', 'd', 'u',
'c', 't', ' ', /* Product : 16 Bytes */
' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', '0', '.',
'0', '1' /* Version : 4 Bytes */
};
/**
* @}
*/
/*------------------------------------------------------------------------------------
Global Variables
-------------------------------------------------------------------------------------*/
/** @defgroup USBD_STORAGE_Exported_Variables
* @brief Public variables.
* @{
*/
extern USBD_HandleTypeDef hUsbDeviceFS;
/**
* @}
*/
/*------------------------------------------------------------------------------------
Func Prototype
-------------------------------------------------------------------------------------*/
/** @defgroup USBD_STORAGE_Private_FunctionPrototypes
* @brief Private functions declaration.
* @{
*/
static int8_t STORAGE_Init_FS(uint8_t lun);
static int8_t STORAGE_GetCapacity_FS(uint8_t lun, uint32_t *block_num,
uint16_t *block_size);
static int8_t STORAGE_IsReady_FS(uint8_t lun);
static int8_t STORAGE_IsWriteProtected_FS(uint8_t lun);
static int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr,
uint16_t blk_len);
static int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr,
uint16_t blk_len);
static int8_t STORAGE_GetMaxLun_FS(void);
/**
* @}
*/
USBD_StorageTypeDef USBD_Storage_Interface_fops_FS = {
STORAGE_Init_FS, STORAGE_GetCapacity_FS,
STORAGE_IsReady_FS, STORAGE_IsWriteProtected_FS,
STORAGE_Read_FS, STORAGE_Write_FS,
STORAGE_GetMaxLun_FS, (int8_t *)STORAGE_Inquirydata_FS};
/*------------------------------------------------------------------------------------
Functions
-------------------------------------------------------------------------------------*/
/**
* @brief Initializes the storage unit (medium) over USB FS IP
* @param lun: Logical unit number.
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
int8_t STORAGE_Init_FS(uint8_t lun)
{
UNUSED(lun);
return (USBD_OK);
}
/**
* @brief Returns the medium capacity.
* @param lun: Logical unit number.
* @param block_num: Number of total block number.
* @param block_size: Block size.
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
int8_t STORAGE_GetCapacity_FS(uint8_t lun, uint32_t *block_num,
uint16_t *block_size)
{
UNUSED(lun);
#if STORAGE_NO_FLASH
// STORAGE_BLK_NBR;
// STORAGE_BLK_SIZ;
*block_num = STORAGE_BLK_NBR;
*block_size = STORAGE_BLK_SIZ;
#else
*block_num = Disk_UnitCount();
*block_size = Disk_UnitSize();
#endif
return (USBD_OK);
}
/**
* @brief Checks whether the medium is ready.
* @param lun: Logical unit number.
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
int8_t STORAGE_IsReady_FS(uint8_t lun)
{
UNUSED(lun);
return (USBD_OK);
}
/**
* @brief Checks whether the medium is write protected.
* @param lun: Logical unit number.
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
int8_t STORAGE_IsWriteProtected_FS(uint8_t lun)
{
UNUSED(lun);
return (USBD_OK);
}
/**
* @brief Reads data from the medium.
* @param lun: Logical unit number.
* @param buf: data buffer.
* @param blk_addr: Logical block address.
* @param blk_len: Blocks number.
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr,
uint16_t blk_len)
{
UNUSED(lun);
#if STORAGE_NO_FLASH
UNUSED(buf);
UNUSED(blk_addr);
UNUSED(blk_len);
// memcpy(buf, temp + (blk_addr * STORAGE_BLK_SIZ), blk_len *
// STORAGE_BLK_SIZ);
#else
Disk_UnitRead(blk_addr, blk_len, buf);
#endif
return (USBD_OK);
}
/**
* @brief Writes data into the medium.
* @param lun: Logical unit number.
* @param buf: data buffer.
* @param blk_addr: Logical block address.
* @param blk_len: Blocks number.
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr,
uint16_t blk_len)
{
UNUSED(lun);
#if STORAGE_NO_FLASH
UNUSED(buf);
UNUSED(blk_addr);
UNUSED(blk_len);
// memcpy(temp + (blk_addr * STORAGE_BLK_SIZ), buf, blk_len *
// STORAGE_BLK_SIZ);
#else
Disk_UnitWrite(blk_addr, blk_len, buf);
#endif
return (USBD_OK);
}
/**
* @brief Returns the Max Supported LUNs.
* @param None
* @retval Lun(s) number.
*/
int8_t STORAGE_GetMaxLun_FS(void) { return (STORAGE_LUN_NBR - 1); }
/**
* @}
*/
@@ -0,0 +1,73 @@
/*!
* \file usbd_storage_if.h
*
* \brief Header for usbd_storage_if.c file.
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_STORAGE_IF_H__
#define __USBD_STORAGE_IF_H__
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_msc.h"
/*------------------------------------------------------------------------------------
Macros
------------------------------------------- -----------------------------------------*/
/** @defgroup USBD_STORAGE_Exported_Defines USBD_STORAGE_Exported_Defines
* @brief Defines.
* @{
*/
#define STORAGE_NO_FLASH 0U
/**
* @}
*/
/*------------------------------------------------------------------------------------
Global Variables
-------------------------------------------------------------------------------------*/
/** @defgroup USBD_STORAGE_Exported_Variables USBD_STORAGE_Exported_Variables
* @brief Public variables.
* @{
*/
/** STORAGE Interface callback. */
extern USBD_StorageTypeDef USBD_Storage_Interface_fops_FS;
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBD_STORAGE_IF_H__ */
@@ -0,0 +1,766 @@
/*!
* \file usbd_cdc.c
*
* \brief This file provides the high layer firmware functions to manage the
* following functionalities of the USB CDC Class:
* - Initialization and Configuration of high and low layer
* - Enumeration as CDC Device (and enumeration for each implemented
* memory interface)
* - OUT/IN data transfer
* - Command IN transfer (class requests management)
* - Error management
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author MCD Application Team
*
* \author ( XinChip ) Alex-J
*
* @verbatim
*
* ===================================================================
* CDC Class Driver Description
* ===================================================================
* This driver manages the "Universal Serial Bus Class Definitions for
* Communications Devices Revision 1.2 November 16, 2007" and the sub-protocol
* specification of "Universal Serial Bus Communications Class Subclass
* Specification for PSTN Devices Revision 1.2 February 9, 2007" This driver
* implements the following aspects of the specification:
* - Device descriptor management
* - Configuration descriptor management
* - Enumeration as CDC device with 2 data endpoints (IN and OUT)
* and 1 command endpoint (IN)
* - Requests management (as described in section 6.2 in
* specification)
* - Abstract Control Model compliant
* - Union Functional collection (using 1 IN endpoint for control)
* - Data interface class
*
* These aspects may be enriched or modified for a specific user
* application.
*
* This driver doesn't implement the following aspects of the
* specification (but it is possible to manage these features with some
* modifications on this driver):
* - Any class-specific aspect relative to communication classes
* should be managed by user application.
* - All communication classes other than PSTN are not managed
*
* @endverbatim
*
*/
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_cdc.h"
#include "usbd_ctlreq.h"
/*-----------------------------------------------------------------------------------
Func Prototype
------------------------------------------------------------------------------------*/
/** @defgroup USBD_CDC_Private_FunctionPrototypes
* @{
*/
static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
USBD_SetupReqTypedef *req);
static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev);
static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length);
static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length);
static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length);
static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length);
uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length);
/*------------------------------------------------------------------------------------
Local Variables
-------------------------------------------------------------------------------------*/
/* USB Standard Device Descriptor */
__ALIGN_BEGIN static uint8_t
USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = {
USB_LEN_DEV_QUALIFIER_DESC,
USB_DESC_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
0x00,
0x00,
0x00,
0x40,
0x01,
0x00,
};
/**
* @}
*/
/** @defgroup USBD_CDC_Private_Variables
* @{
*/
/* CDC interface class callbacks structure */
USBD_ClassTypeDef USBD_CDC = {
USBD_CDC_Init,
USBD_CDC_DeInit,
USBD_CDC_Setup,
NULL, /* EP0_TxSent */
USBD_CDC_EP0_RxReady,
USBD_CDC_DataIn,
USBD_CDC_DataOut,
NULL,
NULL,
NULL,
USBD_CDC_GetHSCfgDesc,
USBD_CDC_GetFSCfgDesc,
USBD_CDC_GetOtherSpeedCfgDesc,
USBD_CDC_GetDeviceQualifierDescriptor,
};
/* USB CDC device Configuration Descriptor */
__ALIGN_BEGIN static uint8_t
USBD_CDC_CfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = {
/* Configuration Descriptor */
0x09, /* bLength: Configuration Descriptor size */
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength */
0x00, 0x02, /* bNumInterfaces: 2 interfaces */
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor
describing the configuration */
#if (USBD_SELF_POWERED == 1U)
0xC0, /* bmAttributes: Bus Powered according to user configuration */
#else
0x80, /* bmAttributes: Bus Powered according to user configuration */
#endif /* USBD_SELF_POWERED */
USBD_MAX_POWER, /* MaxPower (mA) */
/* Interface Descriptor */
0x09, /* bLength: Interface Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
/* Interface descriptor type */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints: One endpoint used */
0x02, /* bInterfaceClass: Communication Interface Class */
0x02, /* bInterfaceSubClass: Abstract Control Model */
0x01, /* bInterfaceProtocol: Common AT commands */
0x00, /* iInterface */
/* 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 */
/* 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: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_CMD_EP, /* bEndpointAddress */
0x03, /* bmAttributes: Interrupt */
LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize */
HIBYTE(CDC_CMD_PACKET_SIZE), CDC_FS_BINTERVAL, /* bInterval */
/*---------------------------------------------------------------------------*/
/* Data class interface descriptor */
0x09, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
0x01, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x02, /* bNumEndpoints: Two endpoints used */
0x0A, /* bInterfaceClass: CDC */
0x00, /* bInterfaceSubClass */
0x00, /* bInterfaceProtocol */
0x00, /* iInterface */
/* Endpoint OUT Descriptor */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_OUT_EP, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize */
HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), CDC_FS_BINTERVAL, /* bInterval */
/* Endpoint IN Descriptor */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
CDC_IN_EP, /* bEndpointAddress */
0x02, /* bmAttributes: Bulk */
LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize */
HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), CDC_FS_BINTERVAL, /* bInterval */
};
/*------------------------------------------------------------------------------------
Global Variables
-------------------------------------------------------------------------------------*/
extern USBD_HandleTypeDef hUsbDeviceFS;
/**
* @}
*/
/*------------------------------------------------------------------------------------
Local Variables
-------------------------------------------------------------------------------------*/
static uint8_t CDCInEpAdd = CDC_IN_EP;
static uint8_t CDCOutEpAdd = CDC_OUT_EP;
static uint8_t CDCCmdEpAdd = CDC_CMD_EP;
/**
* @}
*/
/*------------------------------------------------------------------------------------
Functions
-------------------------------------------------------------------------------------*/
/**
* @brief USBD_CDC_Init
* Initialize the CDC interface
* @param pdev: device instance
* @param cfgidx: Configuration index
* @retval status
*/
static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
UNUSED(cfgidx);
USBD_CDC_HandleTypeDef *hcdc;
hcdc =
(USBD_CDC_HandleTypeDef *)USBD_malloc(sizeof(USBD_CDC_HandleTypeDef));
if (hcdc == NULL) {
pdev->pClassDataCmsit[pdev->classId] = NULL;
return (uint8_t)USBD_EMEM;
}
(void)USBD_memset(hcdc, 0, sizeof(USBD_CDC_HandleTypeDef));
pdev->pClassDataCmsit[pdev->classId] = (void *)hcdc;
pdev->pClassData = pdev->pClassDataCmsit[pdev->classId];
/* Open EP IN */
(void)USBD_LL_OpenEP(pdev, CDCInEpAdd, USBD_EP_TYPE_BULK,
CDC_DATA_FS_IN_PACKET_SIZE);
pdev->ep_in[CDCInEpAdd & 0xFU].is_used = 1U;
/* Open EP OUT */
(void)USBD_LL_OpenEP(pdev, CDCOutEpAdd, USBD_EP_TYPE_BULK,
CDC_DATA_FS_OUT_PACKET_SIZE);
pdev->ep_out[CDCOutEpAdd & 0xFU].is_used = 1U;
/* Set bInterval for CMD Endpoint */
pdev->ep_in[CDCCmdEpAdd & 0xFU].bInterval = CDC_FS_BINTERVAL;
/* Open Command IN EP */
(void)USBD_LL_OpenEP(pdev, CDCCmdEpAdd, USBD_EP_TYPE_INTR,
CDC_CMD_PACKET_SIZE);
pdev->ep_in[CDCCmdEpAdd & 0xFU].is_used = 1U;
hcdc->RxBuffer = NULL;
/* Init physical Interface components */
((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->Init();
/* Init Xfer states */
hcdc->TxState = 0U;
hcdc->RxState = 0U;
if (hcdc->RxBuffer == NULL) {
return (uint8_t)USBD_EMEM;
}
/* Prepare Out endpoint to receive next packet */
(void)USBD_LL_PrepareReceive(pdev, CDCOutEpAdd, hcdc->RxBuffer,
CDC_DATA_FS_OUT_PACKET_SIZE);
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_CDC_Init
* DeInitialize the CDC layer
* @param pdev: device instance
* @param cfgidx: Configuration index
* @retval status
*/
static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
UNUSED(cfgidx);
/* Close EP IN */
(void)USBD_LL_CloseEP(pdev, CDCInEpAdd);
pdev->ep_in[CDCInEpAdd & 0xFU].is_used = 0U;
/* Close EP OUT */
(void)USBD_LL_CloseEP(pdev, CDCOutEpAdd);
pdev->ep_out[CDCOutEpAdd & 0xFU].is_used = 0U;
/* Close Command IN EP */
(void)USBD_LL_CloseEP(pdev, CDCCmdEpAdd);
pdev->ep_in[CDCCmdEpAdd & 0xFU].is_used = 0U;
pdev->ep_in[CDCCmdEpAdd & 0xFU].bInterval = 0U;
/* DeInit physical Interface components */
if (pdev->pClassDataCmsit[pdev->classId] != NULL) {
((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->DeInit();
(void)USBD_free(pdev->pClassDataCmsit[pdev->classId]);
pdev->pClassDataCmsit[pdev->classId] = NULL;
pdev->pClassData = NULL;
}
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_CDC_Setup
* Handle the CDC specific requests
* @param pdev: instance
* @param req: usb requests
* @retval status
*/
static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
USBD_SetupReqTypedef *req)
{
USBD_CDC_HandleTypeDef *hcdc =
(USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
uint16_t len;
uint8_t ifalt = 0U;
uint16_t status_info = 0U;
USBD_StatusTypeDef ret = USBD_OK;
if (hcdc == NULL) {
return (uint8_t)USBD_FAIL;
}
switch (req->bmRequest & USB_REQ_TYPE_MASK) {
case USB_REQ_TYPE_CLASS:
if (req->wLength != 0U) {
if ((req->bmRequest & 0x80U) != 0U) {
((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])
->Control(req->bRequest, (uint8_t *)hcdc->data,
req->wLength);
len = MIN(CDC_REQ_MAX_DATA_SIZE, req->wLength);
(void)USBD_CtlSendData(pdev, (uint8_t *)hcdc->data, len);
} else {
hcdc->CmdOpCode = req->bRequest;
hcdc->CmdLength = (uint8_t)MIN(req->wLength, USB_MAX_EP0_SIZE);
(void)USBD_CtlPrepareRx(pdev, (uint8_t *)hcdc->data,
hcdc->CmdLength);
}
} else {
((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])
->Control(req->bRequest, (uint8_t *)req, 0U);
}
break;
case USB_REQ_TYPE_STANDARD:
switch (req->bRequest) {
case USB_REQ_GET_STATUS:
if (pdev->dev_state == USBD_STATE_CONFIGURED) {
(void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U);
} else {
USBD_CtlError(pdev, req);
ret = USBD_FAIL;
}
break;
case USB_REQ_GET_INTERFACE:
if (pdev->dev_state == USBD_STATE_CONFIGURED) {
(void)USBD_CtlSendData(pdev, &ifalt, 1U);
} else {
USBD_CtlError(pdev, req);
ret = USBD_FAIL;
}
break;
case USB_REQ_SET_INTERFACE:
if (pdev->dev_state != USBD_STATE_CONFIGURED) {
USBD_CtlError(pdev, req);
ret = USBD_FAIL;
}
break;
case USB_REQ_CLEAR_FEATURE:
break;
default:
USBD_CtlError(pdev, req);
ret = USBD_FAIL;
break;
}
break;
default:
USBD_CtlError(pdev, req);
ret = USBD_FAIL;
break;
}
return (uint8_t)ret;
}
/**
* @brief USBD_CDC_DataIn
* Data sent on non-control IN endpoint
* @param pdev: device instance
* @param epnum: endpoint number
* @retval status
*/
static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
USBD_CDC_HandleTypeDef *hcdc;
PCD_HandleTypeDef *hpcd = (PCD_HandleTypeDef *)pdev->pData;
if (pdev->pClassDataCmsit[pdev->classId] == NULL) {
return (uint8_t)USBD_FAIL;
}
hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if ((pdev->ep_in[epnum & 0xFU].total_length > 0U) &&
((pdev->ep_in[epnum & 0xFU].total_length %
hpcd->IN_ep[epnum & 0xFU].maxpacket) == 0U)) {
/* Update the packet total length */
pdev->ep_in[epnum & 0xFU].total_length = 0U;
/* Send ZLP */
(void)USBD_LL_Transmit(pdev, epnum, NULL, 0U);
} else {
hcdc->TxState = 0U;
if (((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])
->TransmitCplt != NULL) {
((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])
->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum);
}
}
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_CDC_DataOut
* Data received on non-control Out endpoint
* @param pdev: device instance
* @param epnum: endpoint number
* @retval status
*/
static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
USBD_CDC_HandleTypeDef *hcdc =
(USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (pdev->pClassDataCmsit[pdev->classId] == NULL) {
return (uint8_t)USBD_FAIL;
}
/* Get the received data length */
hcdc->RxLength = USBD_LL_GetRxDataSize(pdev, epnum);
/* USB data will be immediately processed, this allow next USB traffic being
NAKed till the end of the application Xfer */
((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])
->Receive(hcdc->RxBuffer, &hcdc->RxLength);
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &hcdc->RxBuffer[0]);
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_CDC_EP0_RxReady
* Handle EP0 Rx Ready event
* @param pdev: device instance
* @retval status
*/
static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev)
{
USBD_CDC_HandleTypeDef *hcdc =
(USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hcdc == NULL) {
return (uint8_t)USBD_FAIL;
}
if ((pdev->pUserData[pdev->classId] != NULL) &&
(hcdc->CmdOpCode != 0xFFU)) {
((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])
->Control(hcdc->CmdOpCode, (uint8_t *)hcdc->data,
(uint16_t)hcdc->CmdLength);
hcdc->CmdOpCode = 0xFFU;
}
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_CDC_GetFSCfgDesc
* Return configuration descriptor
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length)
{
USBD_EpDescTypeDef *pEpCmdDesc =
USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_CMD_EP);
USBD_EpDescTypeDef *pEpOutDesc =
USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_OUT_EP);
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_IN_EP);
if (pEpCmdDesc != NULL) {
pEpCmdDesc->bInterval = CDC_FS_BINTERVAL;
}
if (pEpOutDesc != NULL) {
pEpOutDesc->wMaxPacketSize = CDC_DATA_FS_MAX_PACKET_SIZE;
}
if (pEpInDesc != NULL) {
pEpInDesc->wMaxPacketSize = CDC_DATA_FS_MAX_PACKET_SIZE;
}
*length = (uint16_t)sizeof(USBD_CDC_CfgDesc);
return USBD_CDC_CfgDesc;
}
/**
* @brief USBD_CDC_GetHSCfgDesc
* Return configuration descriptor
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length)
{
// USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc,
// CDC_CMD_EP); USBD_EpDescTypeDef *pEpOutDesc =
// USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_OUT_EP); USBD_EpDescTypeDef
// *pEpInDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_IN_EP);
// if (pEpCmdDesc != NULL)
// {
// pEpCmdDesc->bInterval = CDC_HS_BINTERVAL;
// }
// if (pEpOutDesc != NULL)
// {
// pEpOutDesc->wMaxPacketSize = CDC_DATA_HS_MAX_PACKET_SIZE;
// }
// if (pEpInDesc != NULL)
// {
// pEpInDesc->wMaxPacketSize = CDC_DATA_HS_MAX_PACKET_SIZE;
// }
// *length = (uint16_t)sizeof(USBD_CDC_CfgDesc);
return USBD_CDC_CfgDesc;
}
/**
* @brief USBD_CDC_GetOtherSpeedCfgDesc
* Return configuration descriptor
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length)
{
USBD_EpDescTypeDef *pEpCmdDesc =
USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_CMD_EP);
USBD_EpDescTypeDef *pEpOutDesc =
USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_OUT_EP);
USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_IN_EP);
if (pEpCmdDesc != NULL) {
pEpCmdDesc->bInterval = CDC_FS_BINTERVAL;
}
if (pEpOutDesc != NULL) {
pEpOutDesc->wMaxPacketSize = CDC_DATA_FS_MAX_PACKET_SIZE;
}
if (pEpInDesc != NULL) {
pEpInDesc->wMaxPacketSize = CDC_DATA_FS_MAX_PACKET_SIZE;
}
*length = (uint16_t)sizeof(USBD_CDC_CfgDesc);
return USBD_CDC_CfgDesc;
}
/**
* @brief USBD_CDC_GetDeviceQualifierDescriptor
* return Device Qualifier descriptor
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length)
{
*length = (uint16_t)sizeof(USBD_CDC_DeviceQualifierDesc);
return USBD_CDC_DeviceQualifierDesc;
}
/**
* @brief USBD_CDC_RegisterInterface
* @param pdev: device instance
* @param fops: CD Interface callback
* @retval status
*/
uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev,
USBD_CDC_ItfTypeDef *fops)
{
if (fops == NULL) {
return (uint8_t)USBD_FAIL;
}
pdev->pUserData[pdev->classId] = fops;
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_CDC_SetTxBuffer
* @param pdev: device instance
* @param pbuff: Tx Buffer
* @param length: Tx Buffer length
* @retval status
*/
uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff,
uint32_t length)
{
USBD_CDC_HandleTypeDef *hcdc =
(USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hcdc == NULL) {
return (uint8_t)USBD_FAIL;
}
hcdc->TxBuffer = pbuff;
hcdc->TxLength = length;
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_CDC_SetRxBuffer
* @param pdev: device instance
* @param pbuff: Rx Buffer
* @retval status
*/
uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff)
{
USBD_CDC_HandleTypeDef *hcdc =
(USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hcdc == NULL) {
return (uint8_t)USBD_FAIL;
}
hcdc->RxBuffer = pbuff;
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_CDC_TransmitPacket
* Transmit packet on IN endpoint
* @param pdev: device instance
* @retval status
*/
extern volatile uint32_t epnum_change;
uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
USBD_CDC_HandleTypeDef *hcdc =
(USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
USBD_StatusTypeDef ret = USBD_BUSY;
if (pdev->pClassDataCmsit[pdev->classId] == NULL) {
return (uint8_t)USBD_FAIL;
}
if (hcdc->TxState == 0U) {
/* Tx Transfer in progress */
hcdc->TxState = 1U;
/* Update the packet total length */
pdev->ep_in[epnum & 0xFU].total_length = hcdc->TxLength;
epnum_change = (epnum & 0xFU);
/* Transmit next packet */
(void)USBD_LL_Transmit(pdev, epnum, hcdc->TxBuffer, hcdc->TxLength);
// /* Update the packet total length */
// pdev->ep_in[CDCInEpAdd & 0xFU].total_length = hcdc->TxLength;
// /* Transmit next packet */
// (void)USBD_LL_Transmit(pdev, CDCInEpAdd, hcdc->TxBuffer,
// hcdc->TxLength);
ret = USBD_OK;
}
return (uint8_t)ret;
}
/**
* @brief USBD_CDC_ReceivePacket
* prepare OUT Endpoint for reception
* @param pdev: device instance
* @retval status
*/
uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev)
{
USBD_CDC_HandleTypeDef *hcdc =
(USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (pdev->pClassDataCmsit[pdev->classId] == NULL) {
return (uint8_t)USBD_FAIL;
}
/* Prepare Out endpoint to receive next packet */
(void)USBD_LL_PrepareReceive(pdev, CDCOutEpAdd, hcdc->RxBuffer,
CDC_DATA_FS_OUT_PACKET_SIZE);
return (uint8_t)USBD_OK;
}
@@ -0,0 +1,162 @@
/*!
* \file usbd_cdc.h
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author MCD Application Team
*
* \author ( XinChip ) Alex-J
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_CDC_H
#define __USB_CDC_H
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_ioreq.h"
/*------------------------------------------------------------------------------------
Macros
-------------------------------------------------------------------------------------*/
/** @defgroup usbd_cdc_Exported_Defines
* @{
*/
#ifndef CDC_IN_EP
#define CDC_IN_EP 0x81U /* EP1 for data IN */
#endif /* CDC_IN_EP */
#ifndef CDC_OUT_EP
#define CDC_OUT_EP 0x01U /* EP1 for data OUT */
#endif /* CDC_OUT_EP */
#ifndef CDC_CMD_EP
#define CDC_CMD_EP 0x82U /* EP2 for CDC commands */
#endif /* CDC_CMD_EP */
#ifndef CDC_FS_BINTERVAL
#define CDC_FS_BINTERVAL 0x10U
#endif /* CDC_FS_BINTERVAL */
/* CDC Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */
#define CDC_DATA_FS_MAX_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */
#define CDC_CMD_PACKET_SIZE 8U /* Control Endpoint Packet size */
#define USB_CDC_CONFIG_DESC_SIZ 67U
#define CDC_DATA_FS_IN_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE
#define CDC_DATA_FS_OUT_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE
#define CDC_REQ_MAX_DATA_SIZE 0x7U
/*---------------------------------------------------------------------*/
/* CDC definitions */
/*---------------------------------------------------------------------*/
#define CDC_SEND_ENCAPSULATED_COMMAND 0x00U
#define CDC_GET_ENCAPSULATED_RESPONSE 0x01U
#define CDC_SET_COMM_FEATURE 0x02U
#define CDC_GET_COMM_FEATURE 0x03U
#define CDC_CLEAR_COMM_FEATURE 0x04U
#define CDC_SET_LINE_CODING 0x20U
#define CDC_GET_LINE_CODING 0x21U
#define CDC_SET_CONTROL_LINE_STATE 0x22U
#define CDC_SEND_BREAK 0x23U
/**
* @}
*/
/*------------------------------------------------------------------------------------
Typedef
-------------------------------------------------------------------------------------*/
/** @defgroup USBD_CORE_Exported_TypesDefinitions
* @{
*/
typedef struct
{
uint32_t bitrate;
uint8_t format;
uint8_t paritytype;
uint8_t datatype;
} USBD_CDC_LineCodingTypeDef;
typedef struct _USBD_CDC_Itf
{
int8_t (* Init)(void);
int8_t (* DeInit)(void);
int8_t (* Control)(uint8_t cmd, uint8_t *pbuf, uint16_t length);
int8_t (* Receive)(uint8_t *Buf, uint32_t *Len);
int8_t (* TransmitCplt)(uint8_t *Buf, uint32_t *Len, uint8_t epnum);
} USBD_CDC_ItfTypeDef;
typedef struct
{
uint32_t data[CDC_DATA_FS_MAX_PACKET_SIZE * 2U]; /* Force 32-bit alignment */
uint8_t CmdOpCode;
uint8_t CmdLength;
uint8_t *RxBuffer;
uint8_t *TxBuffer;
uint32_t RxLength;
uint32_t TxLength;
__IO uint32_t TxState;
__IO uint32_t RxState;
} USBD_CDC_HandleTypeDef;
/**
* @}
*/
/*------------------------------------------------------------------------------------
Global Variables
-------------------------------------------------------------------------------------*/
/** @defgroup USBD_CORE_Exported_Variables
* @{
*/
extern USBD_ClassTypeDef USBD_CDC;
/**
* @}
*/
/*------------------------------------------------------------------------------------
Exported Functions
-------------------------------------------------------------------------------------*/
/** @defgroup USB_CORE_Exported_Functions
* @{
*/
uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev,
USBD_CDC_ItfTypeDef *fops);
uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff,
uint32_t length);
uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff);
uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev);
uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev, uint8_t epnum);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USB_CDC_H */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,270 @@
/*!
* \file usbd_hid.h
*
* \brief This file provides the HID core functions.
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author MCD Application Team
*
* \author ( XinChip ) Alex-J
*
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_HID_H
#define __USB_HID_H
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_ioreq.h"
/*------------------------------------------------------------------------------------
Macros
-------------------------------------------------------------------------------------*/
/** @defgroup USBD_HID_Exported_Defines
* @{
*/
#if (HID_CLASS_MODE == HID_MOUSE) /* HID_MOUSE */
#define HID_EPIN_ADDR 0x81U
#define HID_EPIN_SIZE 0x04U
#define USB_HID_CONFIG_DESC_SIZ 34U
#elif (HID_CLASS_MODE == HID_KEYBOARD) /* HID_KEYBOARD */
#define HID_EP1_OUTPUT 0U
#define HID_EPIN_ADDR 0x81U
#define HID_EPIN_SIZE 0x08U
#define HID_EPOUT_ADDR 0x01U
#define HID_EPOUT_SIZE 0x01U
#if HID_EP1_OUTPUT
#define USB_HID_CONFIG_DESC_SIZ 41U
#else
#define USB_HID_CONFIG_DESC_SIZ 34U
#endif
#define USBD_HID_OUTREPORT_BUF_SIZE 1U
#elif (HID_CLASS_MODE == HID_CUSTOM) /* HID_CUSTOM */
#define HID_EPIN_ADDR 0x81U
#define HID_EPIN_SIZE 0x40U
#define HID_EPOUT_ADDR 0x01U
#define HID_EPOUT_SIZE 0x40U
#define USB_HID_CONFIG_DESC_SIZ 41U
#define USBD_HID_OUTREPORT_BUF_SIZE 0x40U
#elif ((HID_CLASS_MODE == (HID_MOUSE | HID_CUSTOM)) || \
(HID_CLASS_MODE == (HID_KEYBOARD | HID_CUSTOM)))/* (HID_MOUSE | HID_CUSTOM) */
#if ((HID_CLASS_MODE & HID_MOUSE) == HID_MOUSE)
#define HID_EPIN_ADDR 0x81U
#define HID_EPIN_SIZE 0x04U
#endif
#if ((HID_CLASS_MODE & HID_KEYBOARD) == HID_KEYBOARD)
#define HID_EPIN_ADDR 0x81U
#define HID_EPIN_SIZE 0x08U
#define HID_EPOUT_ADDR 0x01U
#define HID_EPOUT_SIZE 0x01U
#define USBD_HID_OUTREPORT_BUF_SIZE 1U
#endif
#define CUSTOM_HID_EPIN_ADDR 0x82U
#define CUSTOM_HID_EPIN_SIZE 0x40U
#define CUSTOM_HID_EPOUT_ADDR 0x02U
#define CUSTOM_HID_EPOUT_SIZE 0x40U
#define CUSTOM_HID_FS_BINTERVAL 0x5U
#define USBD_CUSTOMHID_OUTREPORT_BUF_SIZE 0x40U
#if ((HID_CLASS_MODE & HID_MOUSE) == HID_MOUSE)
#define USB_HID_CONFIG_DESC_SIZ 66U
#endif
#if ((HID_CLASS_MODE & HID_KEYBOARD) == HID_KEYBOARD)
#define USB_HID_CONFIG_DESC_SIZ 73U
#endif
#define HID_DATAIN_EPNUM (HID_EPIN_ADDR & 0x0FU)
#define CUSTOM_HID_DATAIN_EPNUM (CUSTOM_HID_EPIN_ADDR & 0x0FU)
#elif (HID_CLASS_MODE == (HID_KEYBOARD | HID_MOUSE))
#define HID_EP1IN_ADDR 0x81U
#define HID_EP1IN_SIZE 0x08U
#define HID_EP1OUT_ADDR 0x01U
#define HID_EP1OUT_SIZE 0x01U
#define USBD_HID_OUTREPORT_BUF_SIZE 1U
#define HID_EP2IN_ADDR 0x82U
#define HID_EP2IN_SIZE 0x04U
#define USB_HID_CONFIG_DESC_SIZ 66U
#define HID_DATAIN_EPNUM_1 (HID_EP1IN_ADDR & 0x0FU)
#define HID_DATAIN_EPNUM_2 (HID_EP2IN_ADDR & 0x0FU)
#endif
#define USB_HID_DESC_SIZ 9U
#define HID_MOUSE_REPORT_DESC_SIZE 74U
#define HID_KEYBOARD_REPORT_DESC_SIZE 63U
#define USBD_CUSTOM_REPORT_DESC_SIZE 34U//43U //39U//34U
#define HID_DESCRIPTOR_TYPE 0x21U
#define HID_REPORT_DESC 0x22U
#ifndef HID_HS_BINTERVAL
#define HID_HS_BINTERVAL 0x07U
#endif /* HID_HS_BINTERVAL */
#ifndef HID_FS_BINTERVAL
#if ((HID_CLASS_MODE== HID_MOUSE) || \
(HID_CLASS_MODE == HID_KEYBOARD))
#define HID_FS_BINTERVAL 0x01U
#else
#define HID_FS_BINTERVAL 0x01U
#endif
#endif /* HID_FS_BINTERVAL */
#define HID_REQ_SET_PROTOCOL 0x0BU
#define HID_REQ_GET_PROTOCOL 0x03U
#define HID_REQ_SET_IDLE 0x0AU
#define HID_REQ_GET_IDLE 0x02U
#define HID_REQ_SET_REPORT 0x09U
#define HID_REQ_GET_REPORT 0x01U
/**
* @}
*/
/*------------------------------------------------------------------------------------
Typedef
-------------------------------------------------------------------------------------*/
/** @defgroup USBD_CORE_Exported_TypesDefinitions
* @{
*/
typedef enum
{
HID_IDLE = 0,
HID_BUSY,
} HID_StateTypeDef;
#if (HID_CLASS_MODE == HID_MOUSE)
typedef struct
{
uint32_t Protocol;
uint32_t IdleState;
uint32_t AltSetting;
HID_StateTypeDef state;
} USBD_HID_HandleTypeDef;
#else
typedef struct
{
uint8_t Report_buf[USBD_HID_OUTREPORT_BUF_SIZE];
uint32_t Protocol;
uint32_t IdleState;
uint32_t AltSetting;
uint32_t IsReportAvailable;
HID_StateTypeDef state;
} USBD_HID_HandleTypeDef;
#endif
//#if ((HID_CLASS_MODE & HID_CUSTOM) == HID_CUSTOM)
///** @defgroup USBD_CORE_Exported_TypesDefinitions
// * @{
// */
//typedef enum
//{
// CUSTOM_HID_IDLE = 0U,
// CUSTOM_HID_BUSY,
//} CUSTOM_HID_StateTypeDef;
//typedef struct
//{
// uint8_t Report_buf[USBD_CUSTOMHID_OUTREPORT_BUF_SIZE];
// uint32_t Protocol;
// uint32_t IdleState;
// uint32_t AltSetting;
// uint32_t IsReportAvailable;
// CUSTOM_HID_StateTypeDef state;
//} USBD_CUSTOM_HID_HandleTypeDef;
//#endif
/*
* HID Class specification version 1.1
* 6.2.1 HID Descriptor
*/
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bcdHID;
uint8_t bCountryCode;
uint8_t bNumDescriptors;
uint8_t bHIDDescriptorType;
uint16_t wItemLength;
} __PACKED USBD_HIDDescTypeDef;
/**
* @}
*/
/*------------------------------------------------------------------------------------
Global Variables
-------------------------------------------------------------------------------------*/
extern USBD_ClassTypeDef USBD_HID;
#if (HID_CLASS_MODE == HID_KEYBOARD)
extern uint8_t Report_buff[1];
#endif
extern uint8_t DataOut_Finished;
/*------------------------------------------------------------------------------------
Global Functions
-------------------------------------------------------------------------------------*/
uint8_t USBD_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t *report, uint16_t len);
uint8_t USBD_HID_ReceivePacket(USBD_HandleTypeDef *pdev);
uint32_t USBD_HID_GetPollingInterval(USBD_HandleTypeDef *pdev);
#ifdef __cplusplus
}
#endif
#endif /* __USB_HID_H */
/**
* @}
*/
@@ -0,0 +1,275 @@
/*!
* \file usbd_hid.h
*
* \brief This file provides the HID core functions.
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author MCD Application Team
*
* \author ( XinChip ) Alex-J
*
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_HID_H
#define __USB_HID_H
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_ioreq.h"
/*------------------------------------------------------------------------------------
Macros
-------------------------------------------------------------------------------------*/
/** @defgroup USBD_HID_Exported_Defines
* @{
*/
#if (HID_CLASS_MODE == (HID_KEYBOARD | HID_MOUSE))
#define HID_EP1IN_ADDR 0x81U
#define HID_EP1IN_SIZE 0x08U
#define HID_EP1OUT_ADDR 0x01U
#define HID_EP1OUT_SIZE 0x01U
#define USBD_HID_OUTREPORT_BUF_SIZE 1U
#define HID_EP2IN_ADDR 0x82U
#define HID_EP2IN_SIZE 0x04U
#define USB_HID_CONFIG_DESC_SIZ 66U
#define HID_DATAIN_EPNUM_1 (HID_EP1IN_ADDR & 0x0FU)
#define HID_DATAIN_EPNUM_2 (HID_EP2IN_ADDR & 0x0FU)
#endif
#if (HID_CLASS_MODE == (HID_MOUSE | HID_CUSTOM))
#define HID_EPIN_ADDR 0x81U
#define HID_EPIN_SIZE 0x04U
#define CUSTOM_HID_EPIN_ADDR 0x82U
#define CUSTOM_HID_EPIN_SIZE 0x40U
#define CUSTOM_HID_EPOUT_ADDR 0x02U
#define CUSTOM_HID_EPOUT_SIZE 0x40U
#define CUSTOM_HID_FS_BINTERVAL 0x5U
#define USBD_CUSTOMHID_OUTREPORT_BUF_SIZE 0x40U
#define HID_DATAIN_EPNUM (HID_EPIN_ADDR & 0x0FU)
#define CUSTOM_HID_DATAIN_EPNUM (CUSTOM_HID_EPIN_ADDR & 0x0FU)
#define USB_HID_CONFIG_DESC_SIZ 66U
#endif
#if (HID_CLASS_MODE == HID_DOUBLE_CUSTOM)
#define HID_EPIN_ADDR 0x81U
#define HID_EPIN_SIZE 0x40U
#define HID_EPOUT_ADDR 0x01U
#define HID_EPOUT_SIZE 0x40U
#define HID_EP2IN_ADDR 0x82U
#define HID_EP2IN_SIZE 0x40U
#define HID_EP2OUT_ADDR 0x02U
#define HID_EP2OUT_SIZE 0x40U
#define USB_HID_CONFIG_DESC_SIZ 73U
//#define USB_HID_DOUBLE_CUSTOM_CONFIG_DESC_SIZ 82U
#define USBD_HID_OUTREPORT_BUF_SIZE 0x40U
#define HID_DATAIN_EPNUM_1 (HID_EPIN_ADDR & 0x0FU)
#define HID_DATAIN_EPNUM_2 (HID_EP2IN_ADDR & 0x0FU)
#endif
#define USB_HID_DESC_SIZ 9U
#define HID_MOUSE_REPORT_DESC_SIZE 74U
#define HID_KEYBOARD_REPORT_DESC_SIZE 63U
#define USBD_CUSTOM_REPORT_DESC_SIZE 34U
#define HID_DESCRIPTOR_TYPE 0x21U
#define HID_REPORT_DESC 0x22U
#ifndef HID_HS_BINTERVAL
#define HID_HS_BINTERVAL 0x07U
#endif /* HID_HS_BINTERVAL */
#ifndef HID_FS_BINTERVAL
#define HID_FS_BINTERVAL 0x01U
#endif /* HID_FS_BINTERVAL */
#ifndef HID_FS_K_BINTERVAL
#define HID_FS_K_BINTERVAL 0x0AU
#endif /* HID_FS_BINTERVAL */
#ifndef HID_FS_M_BINTERVAL
#define HID_FS_M_BINTERVAL 0x01U
#endif /* HID_FS_BINTERVAL */
#define HID_REQ_SET_PROTOCOL 0x0BU
#define HID_REQ_GET_PROTOCOL 0x03U
#define HID_REQ_SET_IDLE 0x0AU
#define HID_REQ_GET_IDLE 0x02U
#define HID_REQ_SET_REPORT 0x09U
#define HID_REQ_GET_REPORT 0x01U
/**
* @}
*/
/*------------------------------------------------------------------------------------
Typedef
-------------------------------------------------------------------------------------*/
/** @defgroup USBD_CORE_Exported_TypesDefinitions
* @{
*/
typedef enum
{
HID_IDLE = 0,
HID_BUSY,
} HID_StateTypeDef;
#if ((HID_CLASS_MODE & HID_MOUSE) == HID_MOUSE)
typedef struct
{
uint32_t Protocol;
uint32_t IdleState;
uint32_t AltSetting;
HID_StateTypeDef state;
} USBD_HID_HandleTypeDef;
#endif
#if ((HID_CLASS_MODE & HID_CUSTOM) == HID_CUSTOM)
/** @defgroup USBD_CORE_Exported_TypesDefinitions
* @{
*/
typedef enum
{
CUSTOM_HID_IDLE = 0U,
CUSTOM_HID_BUSY,
} CUSTOM_HID_StateTypeDef;
typedef struct
{
uint8_t Report_buf[USBD_CUSTOMHID_OUTREPORT_BUF_SIZE];
uint32_t Protocol;
uint32_t IdleState;
uint32_t AltSetting;
uint32_t IsReportAvailable;
CUSTOM_HID_StateTypeDef state;
} USBD_CUSTOM_HID_HandleTypeDef;
#endif
#if (HID_CLASS_MODE == HID_DOUBLE_CUSTOM)
typedef struct
{
uint8_t Report_buf[USBD_HID_OUTREPORT_BUF_SIZE];
uint32_t Protocol;
uint32_t IdleState;
uint32_t AltSetting;
uint32_t IsReportAvailable;
HID_StateTypeDef state;
} USBD_HID_HandleTypeDef;
#endif
//#if ((HID_CLASS_MODE & HID_CUSTOM) == HID_CUSTOM)
///** @defgroup USBD_CORE_Exported_TypesDefinitions
// * @{
// */
//typedef enum
//{
// CUSTOM_HID_IDLE = 0U,
// CUSTOM_HID_BUSY,
//} CUSTOM_HID_StateTypeDef;
//typedef struct
//{
// uint8_t Report_buf[USBD_CUSTOMHID_OUTREPORT_BUF_SIZE];
// uint32_t Protocol;
// uint32_t IdleState;
// uint32_t AltSetting;
// uint32_t IsReportAvailable;
// CUSTOM_HID_StateTypeDef state;
//} USBD_CUSTOM_HID_HandleTypeDef;
//#endif
/*
* HID Class specification version 1.1
* 6.2.1 HID Descriptor
*/
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bcdHID;
uint8_t bCountryCode;
uint8_t bNumDescriptors;
uint8_t bHIDDescriptorType;
uint16_t wItemLength;
} __PACKED USBD_HIDDescTypeDef;
/**
* @}
*/
/*------------------------------------------------------------------------------------
Global Variables
-------------------------------------------------------------------------------------*/
extern USBD_ClassTypeDef USBD_HID;
#if ((HID_CLASS_MODE & HID_KEYBOARD) == HID_KEYBOARD)
extern uint8_t Report_buff[1];
#endif
/*------------------------------------------------------------------------------------
Global Functions
-------------------------------------------------------------------------------------*/
#if (HID_CLASS_MODE == (HID_MOUSE | HID_KEYBOARD))
uint8_t USBD_Mouse_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len);
uint8_t USBD_Keyboard_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len);
#elif (HID_CLASS_MODE == (HID_MOUSE | HID_CUSTOM))
uint8_t USBD_Mouse_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len);
uint8_t USBD_Custom_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len);
#elif (HID_CLASS_MODE == HID_DOUBLE_CUSTOM)
uint8_t USBD_Custom1_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len);
uint8_t USBD_Custom2_HID_SendReport(USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len);
#endif
uint32_t USBD_HID_GetPollingInterval(USBD_HandleTypeDef *pdev);
#ifdef __cplusplus
}
#endif
#endif /* __USB_HID_H */
/**
* @}
*/
@@ -0,0 +1,493 @@
/*!
* \file usbd_msc.c
*
* \brief This file provides all the MSC core functions.
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author MCD Application Team
*
* \author ( XinChip ) Alex-J
* @verbatim
*
* ===================================================================
* MSC Class Description
* ===================================================================
* This module manages the MSC class V1.0 following the "Universal
* Serial Bus Mass Storage Class (MSC) Bulk-Only Transport (BOT)
Version 1.0
* Sep. 31, 1999".
* This driver implements the following aspects of the specification:
* - Bulk-Only Transport protocol
* - Subclass : SCSI transparent command set (ref. SCSI Primary
Commands - 3 (SPC-3))
*
* @endverbatim
*/
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_msc.h"
/*------------------------------------------------------------------------------------
Func Prototype
-------------------------------------------------------------------------------------*/
/** @defgroup MSC_CORE_Private_FunctionPrototypes
* @{
*/
uint8_t USBD_MSC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
uint8_t USBD_MSC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
uint8_t USBD_MSC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
uint8_t USBD_MSC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
uint8_t *USBD_MSC_GetHSCfgDesc(uint16_t *length);
uint8_t *USBD_MSC_GetFSCfgDesc(uint16_t *length);
uint8_t *USBD_MSC_GetOtherSpeedCfgDesc(uint16_t *length);
uint8_t *USBD_MSC_GetDeviceQualifierDescriptor(uint16_t *length);
/**
* @}
*/
/*------------------------------------------------------------------------------------
Local Variables
-------------------------------------------------------------------------------------*/
/** @defgroup MSC_CORE_Private_Variables
* @{
*/
USBD_ClassTypeDef USBD_MSC = {
USBD_MSC_Init,
USBD_MSC_DeInit,
USBD_MSC_Setup,
NULL, /*EP0_TxSent*/
NULL, /*EP0_RxReady*/
USBD_MSC_DataIn,
USBD_MSC_DataOut,
NULL, /*SOF */
NULL,
NULL,
USBD_MSC_GetHSCfgDesc,
USBD_MSC_GetFSCfgDesc,
USBD_MSC_GetOtherSpeedCfgDesc,
USBD_MSC_GetDeviceQualifierDescriptor,
};
/* USB Mass storage device Configuration Descriptor */
/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
__ALIGN_BEGIN static uint8_t
USBD_MSC_CfgDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END = {
0x09, /* bLength: Configuration Descriptor size */
USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
USB_MSC_CONFIG_DESC_SIZ,
0x00, 0x01, /* bNumInterfaces: 1 interface */
0x01, /* bConfigurationValue */
0x04, /* iConfiguration */
#if (USBD_SELF_POWERED == 1U)
0xC0, /* bmAttributes: Bus Powered according to user configuration */
#else
0x80, /* bmAttributes: Bus Powered according to user configuration */
#endif /* USBD_SELF_POWERED */
USBD_MAX_POWER, /* MaxPower (mA) */
/******************** Mass Storage interface ********************/
0x09, /* bLength: Interface Descriptor size */
0x04, /* bDescriptorType: */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x02, /* bNumEndpoints */
0x08, /* bInterfaceClass: MSC Class */
0x06, /* bInterfaceSubClass : SCSI transparent*/
0x50, /* nInterfaceProtocol */
0x05, /* iInterface: */
/******************** Mass Storage Endpoints ********************/
0x07, /* Endpoint descriptor length = 7 */
0x05, /* Endpoint descriptor type */
MSC_EPIN_ADDR, /* Endpoint address (IN, address 1) */
0x02, /* Bulk endpoint type */
LOBYTE(MSC_MAX_FS_PACKET), HIBYTE(MSC_MAX_FS_PACKET),
0x00, /* Polling interval in milliseconds */
0x07, /* Endpoint descriptor length = 7 */
0x05, /* Endpoint descriptor type */
MSC_EPOUT_ADDR, /* Endpoint address (OUT, address 1) */
0x02, /* Bulk endpoint type */
LOBYTE(MSC_MAX_FS_PACKET), HIBYTE(MSC_MAX_FS_PACKET),
0x00 /* Polling interval in milliseconds */
};
/* USB Standard Device Descriptor */
__ALIGN_BEGIN static uint8_t
USBD_MSC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = {
USB_LEN_DEV_QUALIFIER_DESC,
USB_DESC_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
0x00,
0x00,
0x00,
MSC_MAX_FS_PACKET,
0x01,
0x00,
};
uint8_t MSCInEpAdd = MSC_EPIN_ADDR;
uint8_t MSCOutEpAdd = MSC_EPOUT_ADDR;
/**
* @}
*/
/*------------------------------------------------------------------------------------
Functions
-------------------------------------------------------------------------------------*/
/**
* @brief USBD_MSC_Init
* Initialize the mass storage configuration
* @param pdev: device instance
* @param cfgidx: configuration index
* @retval status
*/
uint8_t USBD_MSC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
UNUSED(cfgidx);
USBD_MSC_BOT_HandleTypeDef *hmsc;
hmsc = (USBD_MSC_BOT_HandleTypeDef *)USBD_malloc(
sizeof(USBD_MSC_BOT_HandleTypeDef));
if (hmsc == NULL) {
pdev->pClassDataCmsit[pdev->classId] = NULL;
return (uint8_t)USBD_EMEM;
}
pdev->pClassDataCmsit[pdev->classId] = (void *)hmsc;
pdev->pClassData = pdev->pClassDataCmsit[pdev->classId];
if (pdev->dev_speed == USBD_SPEED_HIGH) {
/* Open EP OUT */
(void)USBD_LL_OpenEP(pdev, MSCOutEpAdd, USBD_EP_TYPE_BULK,
MSC_MAX_HS_PACKET);
pdev->ep_out[MSCOutEpAdd & 0xFU].is_used = 1U;
/* Open EP IN */
(void)USBD_LL_OpenEP(pdev, MSCInEpAdd, USBD_EP_TYPE_BULK,
MSC_MAX_HS_PACKET);
pdev->ep_in[MSCInEpAdd & 0xFU].is_used = 1U;
} else {
/* Open EP OUT */
(void)USBD_LL_OpenEP(pdev, MSCOutEpAdd, USBD_EP_TYPE_BULK,
MSC_MAX_FS_PACKET);
pdev->ep_out[MSCOutEpAdd & 0xFU].is_used = 1U;
/* Open EP IN */
(void)USBD_LL_OpenEP(pdev, MSCInEpAdd, USBD_EP_TYPE_BULK,
MSC_MAX_FS_PACKET);
pdev->ep_in[MSCInEpAdd & 0xFU].is_used = 1U;
}
/* Init the BOT layer */
MSC_BOT_Init(pdev);
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_MSC_DeInit
* DeInitialize the mass storage configuration
* @param pdev: device instance
* @param cfgidx: configuration index
* @retval status
*/
uint8_t USBD_MSC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
UNUSED(cfgidx);
/* Close MSC EPs */
(void)USBD_LL_CloseEP(pdev, MSCOutEpAdd);
pdev->ep_out[MSCOutEpAdd & 0xFU].is_used = 0U;
/* Close EP IN */
(void)USBD_LL_CloseEP(pdev, MSCInEpAdd);
pdev->ep_in[MSCInEpAdd & 0xFU].is_used = 0U;
/* Free MSC Class Resources */
if (pdev->pClassDataCmsit[pdev->classId] != NULL) {
/* De-Init the BOT layer */
MSC_BOT_DeInit(pdev);
(void)USBD_free(pdev->pClassDataCmsit[pdev->classId]);
pdev->pClassDataCmsit[pdev->classId] = NULL;
pdev->pClassData = NULL;
}
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_MSC_Setup
* Handle the MSC specific requests
* @param pdev: device instance
* @param req: USB request
* @retval status
*/
uint8_t USBD_MSC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
USBD_MSC_BOT_HandleTypeDef *hmsc =
(USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
USBD_StatusTypeDef ret = USBD_OK;
uint16_t status_info = 0U;
if (hmsc == NULL) {
return (uint8_t)USBD_FAIL;
}
switch (req->bmRequest & USB_REQ_TYPE_MASK) {
/* Class request */
case USB_REQ_TYPE_CLASS:
switch (req->bRequest) {
case BOT_GET_MAX_LUN:
if ((req->wValue == 0U) && (req->wLength == 1U) &&
((req->bmRequest & 0x80U) == 0x80U)) {
hmsc->max_lun = (uint32_t)((USBD_StorageTypeDef *)
pdev->pUserData[pdev->classId])
->GetMaxLun();
(void)USBD_CtlSendData(pdev, (uint8_t *)&hmsc->max_lun, 1U);
} else {
USBD_CtlError(pdev, req);
ret = USBD_FAIL;
}
break;
case BOT_RESET:
if ((req->wValue == 0U) && (req->wLength == 0U) &&
((req->bmRequest & 0x80U) != 0x80U)) {
MSC_BOT_Reset(pdev);
} else {
USBD_CtlError(pdev, req);
ret = USBD_FAIL;
}
break;
default:
USBD_CtlError(pdev, req);
ret = USBD_FAIL;
break;
}
break;
/* Interface & Endpoint request */
case USB_REQ_TYPE_STANDARD:
switch (req->bRequest) {
case USB_REQ_GET_STATUS:
if (pdev->dev_state == USBD_STATE_CONFIGURED) {
(void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U);
} else {
USBD_CtlError(pdev, req);
ret = USBD_FAIL;
}
break;
case USB_REQ_GET_INTERFACE:
if (pdev->dev_state == USBD_STATE_CONFIGURED) {
(void)USBD_CtlSendData(pdev, (uint8_t *)&hmsc->interface, 1U);
} else {
USBD_CtlError(pdev, req);
ret = USBD_FAIL;
}
break;
case USB_REQ_SET_INTERFACE:
if (pdev->dev_state == USBD_STATE_CONFIGURED) {
hmsc->interface = (uint8_t)(req->wValue);
} else {
USBD_CtlError(pdev, req);
ret = USBD_FAIL;
}
break;
case USB_REQ_CLEAR_FEATURE:
if (pdev->dev_state == USBD_STATE_CONFIGURED) {
if (req->wValue == USB_FEATURE_EP_HALT) {
/* Flush the FIFO */
(void)USBD_LL_FlushEP(pdev, (uint8_t)req->wIndex);
/* Handle BOT error */
MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex);
}
}
break;
default:
USBD_CtlError(pdev, req);
ret = USBD_FAIL;
break;
}
break;
default:
USBD_CtlError(pdev, req);
ret = USBD_FAIL;
break;
}
return (uint8_t)ret;
}
/**
* @brief USBD_MSC_DataIn
* handle data IN Stage
* @param pdev: device instance
* @param epnum: endpoint index
* @retval status
*/
uint8_t USBD_MSC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
MSC_BOT_DataIn(pdev, epnum);
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_MSC_DataOut
* handle data OUT Stage
* @param pdev: device instance
* @param epnum: endpoint index
* @retval status
*/
uint8_t USBD_MSC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
MSC_BOT_DataOut(pdev, epnum);
return (uint8_t)USBD_OK;
}
/**
* @brief USBD_MSC_GetHSCfgDesc
* return configuration descriptor
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
uint8_t *USBD_MSC_GetHSCfgDesc(uint16_t *length)
{
USBD_EpDescTypeDef *pEpInDesc =
USBD_GetEpDesc(USBD_MSC_CfgDesc, MSC_EPIN_ADDR);
USBD_EpDescTypeDef *pEpOutDesc =
USBD_GetEpDesc(USBD_MSC_CfgDesc, MSC_EPOUT_ADDR);
if (pEpInDesc != NULL) {
pEpInDesc->wMaxPacketSize = MSC_MAX_HS_PACKET;
}
if (pEpOutDesc != NULL) {
pEpOutDesc->wMaxPacketSize = MSC_MAX_HS_PACKET;
}
*length = (uint16_t)sizeof(USBD_MSC_CfgDesc);
return USBD_MSC_CfgDesc;
}
/**
* @brief USBD_MSC_GetFSCfgDesc
* return configuration descriptor
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
uint8_t *USBD_MSC_GetFSCfgDesc(uint16_t *length)
{
USBD_EpDescTypeDef *pEpInDesc =
USBD_GetEpDesc(USBD_MSC_CfgDesc, MSC_EPIN_ADDR);
USBD_EpDescTypeDef *pEpOutDesc =
USBD_GetEpDesc(USBD_MSC_CfgDesc, MSC_EPOUT_ADDR);
if (pEpInDesc != NULL) {
pEpInDesc->wMaxPacketSize = MSC_MAX_FS_PACKET;
}
if (pEpOutDesc != NULL) {
pEpOutDesc->wMaxPacketSize = MSC_MAX_FS_PACKET;
}
*length = (uint16_t)sizeof(USBD_MSC_CfgDesc);
return USBD_MSC_CfgDesc;
}
/**
* @brief USBD_MSC_GetOtherSpeedCfgDesc
* return other speed configuration descriptor
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
uint8_t *USBD_MSC_GetOtherSpeedCfgDesc(uint16_t *length)
{
USBD_EpDescTypeDef *pEpInDesc =
USBD_GetEpDesc(USBD_MSC_CfgDesc, MSC_EPIN_ADDR);
USBD_EpDescTypeDef *pEpOutDesc =
USBD_GetEpDesc(USBD_MSC_CfgDesc, MSC_EPOUT_ADDR);
if (pEpInDesc != NULL) {
pEpInDesc->wMaxPacketSize = MSC_MAX_FS_PACKET;
}
if (pEpOutDesc != NULL) {
pEpOutDesc->wMaxPacketSize = MSC_MAX_FS_PACKET;
}
*length = (uint16_t)sizeof(USBD_MSC_CfgDesc);
return USBD_MSC_CfgDesc;
}
/**
* @brief DeviceQualifierDescriptor
* return Device Qualifier descriptor
* @param length : pointer data length
* @retval pointer to descriptor buffer
*/
uint8_t *USBD_MSC_GetDeviceQualifierDescriptor(uint16_t *length)
{
*length = (uint16_t)sizeof(USBD_MSC_DeviceQualifierDesc);
return USBD_MSC_DeviceQualifierDesc;
}
/**
* @brief USBD_MSC_RegisterStorage
* @param fops: storage callback
* @retval status
*/
uint8_t USBD_MSC_RegisterStorage(USBD_HandleTypeDef *pdev,
USBD_StorageTypeDef *fops)
{
if (fops == NULL) {
return (uint8_t)USBD_FAIL;
}
pdev->pUserData[pdev->classId] = fops;
return (uint8_t)USBD_OK;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
@@ -0,0 +1,134 @@
/*!
* \file usbd_msc.h
*
* \brief Header for the usbd_msc.c file
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author MCD Application Team
*
* \author ( XinChip ) Alex-J
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_MSC_H
#define __USBD_MSC_H
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_msc_bot.h"
#include "usbd_msc_scsi.h"
#include "usbd_ioreq.h"
/*------------------------------------------------------------------------------------
Macros
------------------------------------------- -----------------------------------------*/
/** @defgroup USBD_BOT_Exported_Defines
* @{
*/
/* MSC Class Config */
#ifndef MSC_MEDIA_PACKET
#define MSC_MEDIA_PACKET 512U
#endif /* MSC_MEDIA_PACKET */
#define MSC_MAX_FS_PACKET 0x40U
#define MSC_MAX_HS_PACKET 0x200U
#define BOT_GET_MAX_LUN 0xFE
#define BOT_RESET 0xFF
#define USB_MSC_CONFIG_DESC_SIZ 32
#ifndef MSC_EPIN_ADDR
#define MSC_EPIN_ADDR 0x81U
#endif /* MSC_EPIN_ADDR */
#ifndef MSC_EPOUT_ADDR
#define MSC_EPOUT_ADDR 0x01U
#endif /* MSC_EPOUT_ADDR */
/**
* @}
*/
/*------------------------------------------------------------------------------------
Typedef
------------------------------------------------------------------------------------*/
/** @defgroup USB_CORE_Exported_Types
* @{
*/
typedef struct _USBD_STORAGE
{
int8_t (* Init)(uint8_t lun);
int8_t (* GetCapacity)(uint8_t lun, uint32_t *block_num, uint16_t *block_size);
int8_t (* IsReady)(uint8_t lun);
int8_t (* IsWriteProtected)(uint8_t lun);
int8_t (* Read)(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
int8_t (* Write)(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
int8_t (* GetMaxLun)(void);
int8_t *pInquiry;
} USBD_StorageTypeDef;
typedef struct
{
uint32_t max_lun;
uint32_t interface;
uint8_t bot_state;
uint8_t bot_status;
uint32_t bot_data_length;
uint8_t bot_data[MSC_MEDIA_PACKET];
USBD_MSC_BOT_CBWTypeDef cbw;
USBD_MSC_BOT_CSWTypeDef csw;
USBD_SCSI_SenseTypeDef scsi_sense [SENSE_LIST_DEEPTH];
uint8_t scsi_sense_head;
uint8_t scsi_sense_tail;
uint8_t scsi_medium_state;
uint16_t scsi_blk_size;
uint32_t scsi_blk_nbr;
uint32_t scsi_blk_addr;
uint32_t scsi_blk_len;
} USBD_MSC_BOT_HandleTypeDef;
/*------------------------------------------------------------------------------------
Global Variables
-------------------------------------------------------------------------------------*/
/* Structure for MSC process */
extern USBD_ClassTypeDef USBD_MSC;
/*------------------------------------------------------------------------------------
Exported Functions
-------------------------------------------------------------------------------------*/
uint8_t USBD_MSC_RegisterStorage(USBD_HandleTypeDef *pdev,
USBD_StorageTypeDef *fops);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBD_MSC_H */
@@ -0,0 +1,381 @@
/*!
* \file usbd_msc_bot.c
*
* \brief This file provides all the BOT protocol core functions.
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author MCD Application Team
*
* \author ( XinChip ) Alex-J
*/
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_msc_bot.h"
#include "usbd_ioreq.h"
#include "usbd_msc.h"
#include "usbd_msc_scsi.h"
/*------------------------------------------------------------------------------------
Global Variables
-------------------------------------------------------------------------------------*/
extern uint8_t MSCInEpAdd;
extern uint8_t MSCOutEpAdd;
/**
* @}
*/
/*------------------------------------------------------------------------------------
Func Prototype
-------------------------------------------------------------------------------------*/
/** @defgroup MSC_BOT_Private_FunctionPrototypes
* @{
*/
static void MSC_BOT_SendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf,
uint32_t len);
static void MSC_BOT_CBW_Decode(USBD_HandleTypeDef *pdev);
static void MSC_BOT_Abort(USBD_HandleTypeDef *pdev);
/**
* @}
*/
/*------------------------------------------------------------------------------------
Functions
-------------------------------------------------------------------------------------*/
/**
* @brief MSC_BOT_Init
* Initialize the BOT Process
* @param pdev: device instance
* @retval None
*/
void MSC_BOT_Init(USBD_HandleTypeDef *pdev)
{
USBD_MSC_BOT_HandleTypeDef *hmsc =
(USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hmsc == NULL) {
return;
}
hmsc->bot_state = USBD_BOT_IDLE;
hmsc->bot_status = USBD_BOT_STATUS_NORMAL;
hmsc->scsi_sense_tail = 0U;
hmsc->scsi_sense_head = 0U;
hmsc->scsi_medium_state = SCSI_MEDIUM_UNLOCKED;
((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->Init(0U);
(void)USBD_LL_FlushEP(pdev, MSCOutEpAdd);
(void)USBD_LL_FlushEP(pdev, MSCInEpAdd);
/* Prepare EP to Receive First BOT Cmd */
(void)USBD_LL_PrepareReceive(pdev, MSCOutEpAdd, (uint8_t *)&hmsc->cbw,
USBD_BOT_CBW_LENGTH);
}
/**
* @brief MSC_BOT_Reset
* Reset the BOT Machine
* @param pdev: device instance
* @retval None
*/
void MSC_BOT_Reset(USBD_HandleTypeDef *pdev)
{
USBD_MSC_BOT_HandleTypeDef *hmsc =
(USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hmsc == NULL) {
return;
}
hmsc->bot_state = USBD_BOT_IDLE;
hmsc->bot_status = USBD_BOT_STATUS_RECOVERY;
(void)USBD_LL_ClearStallEP(pdev, MSCInEpAdd);
(void)USBD_LL_ClearStallEP(pdev, MSCOutEpAdd);
/* Prepare EP to Receive First BOT Cmd */
(void)USBD_LL_PrepareReceive(pdev, MSCOutEpAdd, (uint8_t *)&hmsc->cbw,
USBD_BOT_CBW_LENGTH);
}
/**
* @brief MSC_BOT_DeInit
* DeInitialize the BOT Machine
* @param pdev: device instance
* @retval None
*/
void MSC_BOT_DeInit(USBD_HandleTypeDef *pdev)
{
USBD_MSC_BOT_HandleTypeDef *hmsc =
(USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hmsc != NULL) {
hmsc->bot_state = USBD_BOT_IDLE;
}
}
/**
* @brief MSC_BOT_DataIn
* Handle BOT IN data stage
* @param pdev: device instance
* @param epnum: endpoint index
* @retval None
*/
void MSC_BOT_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
UNUSED(epnum);
USBD_MSC_BOT_HandleTypeDef *hmsc =
(USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hmsc == NULL) {
return;
}
switch (hmsc->bot_state) {
case USBD_BOT_DATA_IN:
if (SCSI_ProcessCmd(pdev, hmsc->cbw.bLUN, &hmsc->cbw.CB[0]) < 0) {
MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_FAILED);
}
break;
case USBD_BOT_SEND_DATA:
case USBD_BOT_LAST_DATA_IN:
MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_PASSED);
break;
default:
break;
}
}
/**
* @brief MSC_BOT_DataOut
* Process MSC OUT data
* @param pdev: device instance
* @param epnum: endpoint index
* @retval None
*/
void MSC_BOT_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
UNUSED(epnum);
USBD_MSC_BOT_HandleTypeDef *hmsc =
(USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hmsc == NULL) {
return;
}
switch (hmsc->bot_state) {
case USBD_BOT_IDLE:
MSC_BOT_CBW_Decode(pdev);
break;
case USBD_BOT_DATA_OUT:
if (SCSI_ProcessCmd(pdev, hmsc->cbw.bLUN, &hmsc->cbw.CB[0]) < 0) {
MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_FAILED);
}
break;
default:
break;
}
}
/**
* @brief MSC_BOT_CBW_Decode
* Decode the CBW command and set the BOT state machine accordingly
* @param pdev: device instance
* @retval None
*/
static void MSC_BOT_CBW_Decode(USBD_HandleTypeDef *pdev)
{
USBD_MSC_BOT_HandleTypeDef *hmsc =
(USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hmsc == NULL) {
return;
}
hmsc->csw.dTag = hmsc->cbw.dTag;
hmsc->csw.dDataResidue = hmsc->cbw.dDataLength;
if ((USBD_LL_GetRxDataSize(pdev, MSCOutEpAdd) != USBD_BOT_CBW_LENGTH) ||
(hmsc->cbw.dSignature != USBD_BOT_CBW_SIGNATURE) ||
(hmsc->cbw.bLUN > 1U) || (hmsc->cbw.bCBLength < 1U) ||
(hmsc->cbw.bCBLength > 16U)) {
SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
hmsc->bot_status = USBD_BOT_STATUS_ERROR;
MSC_BOT_Abort(pdev);
} else {
if (SCSI_ProcessCmd(pdev, hmsc->cbw.bLUN, &hmsc->cbw.CB[0]) < 0) {
// if (hmsc->bot_state == USBD_BOT_NO_DATA)
// {
// MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_FAILED);
// }
// else
{
MSC_BOT_Abort(pdev);
}
}
/* Burst xfer handled internally */
else if ((hmsc->bot_state != USBD_BOT_DATA_IN) &&
(hmsc->bot_state != USBD_BOT_DATA_OUT) &&
(hmsc->bot_state != USBD_BOT_LAST_DATA_IN)) {
if (hmsc->bot_data_length > 0U) {
MSC_BOT_SendData(pdev, hmsc->bot_data, hmsc->bot_data_length);
} else if (hmsc->bot_data_length == 0U) {
MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_PASSED);
} else {
MSC_BOT_Abort(pdev);
}
}
// else
// {
// return;
// }
}
}
/**
* @brief MSC_BOT_SendData
* Send the requested data
* @param pdev: device instance
* @param buf: pointer to data buffer
* @param len: Data Length
* @retval None
*/
static void MSC_BOT_SendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf,
uint32_t len)
{
USBD_MSC_BOT_HandleTypeDef *hmsc =
(USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
uint32_t length;
if (hmsc == NULL) {
return;
}
length = MIN(hmsc->cbw.dDataLength, len);
hmsc->csw.dDataResidue -= len;
hmsc->csw.bStatus = USBD_CSW_CMD_PASSED;
hmsc->bot_state = USBD_BOT_SEND_DATA;
(void)USBD_LL_Transmit(pdev, MSCInEpAdd, pbuf, length);
}
/**
* @brief MSC_BOT_SendCSW
* Send the Command Status Wrapper
* @param pdev: device instance
* @param status : CSW status
* @retval None
*/
void MSC_BOT_SendCSW(USBD_HandleTypeDef *pdev, uint8_t CSW_Status)
{
USBD_MSC_BOT_HandleTypeDef *hmsc =
(USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hmsc == NULL) {
return;
}
hmsc->csw.dSignature = USBD_BOT_CSW_SIGNATURE;
hmsc->csw.bStatus = CSW_Status;
hmsc->bot_state = USBD_BOT_IDLE;
(void)USBD_LL_Transmit(pdev, MSCInEpAdd, (uint8_t *)&hmsc->csw,
USBD_BOT_CSW_LENGTH);
/* Prepare EP to Receive next Cmd */
(void)USBD_LL_PrepareReceive(pdev, MSCOutEpAdd, (uint8_t *)&hmsc->cbw,
USBD_BOT_CBW_LENGTH);
}
/**
* @brief MSC_BOT_Abort
* Abort the current transfer
* @param pdev: device instance
* @retval status
*/
static void MSC_BOT_Abort(USBD_HandleTypeDef *pdev)
{
USBD_MSC_BOT_HandleTypeDef *hmsc =
(USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hmsc == NULL) {
return;
}
if ((hmsc->cbw.bmFlags == 0U) && (hmsc->cbw.dDataLength != 0U) &&
(hmsc->bot_status == USBD_BOT_STATUS_NORMAL)) {
(void)USBD_LL_StallEP(pdev, MSCOutEpAdd);
}
(void)USBD_LL_StallEP(pdev, MSCInEpAdd);
if (hmsc->bot_status == USBD_BOT_STATUS_ERROR) {
(void)USBD_LL_StallEP(pdev, MSCInEpAdd);
(void)USBD_LL_StallEP(pdev, MSCOutEpAdd);
}
}
/**
* @brief MSC_BOT_CplClrFeature
* Complete the clear feature request
* @param pdev: device instance
* @param epnum: endpoint index
* @retval None
*/
void MSC_BOT_CplClrFeature(USBD_HandleTypeDef *pdev, uint8_t epnum)
{
USBD_MSC_BOT_HandleTypeDef *hmsc =
(USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
if (hmsc == NULL) {
return;
}
if (hmsc->bot_status == USBD_BOT_STATUS_ERROR) /* Bad CBW Signature */
{
(void)USBD_LL_StallEP(pdev, MSCInEpAdd);
(void)USBD_LL_StallEP(pdev, MSCOutEpAdd);
} else if (((epnum & 0x80U) == 0x80U) &&
(hmsc->bot_status != USBD_BOT_STATUS_RECOVERY)) {
MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_FAILED);
} else {
return;
}
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
@@ -0,0 +1,138 @@
/*!
* \file usbd_msc_bot.h
*
* \brief Header for the usbd_msc_bot.c file.
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author MCD Application Team
*
* \author ( XinChip ) Alex-J
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_MSC_BOT_H
#define __USBD_MSC_BOT_H
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_core.h"
/*------------------------------------------------------------------------------------
Macros
------------------------------------------- -----------------------------------------*/
/** @defgroup USBD_CORE_Exported_Defines
* @{
*/
#define USBD_BOT_IDLE 0U /* Idle state */
#define USBD_BOT_DATA_OUT 1U /* Data Out state */
#define USBD_BOT_DATA_IN 2U /* Data In state */
#define USBD_BOT_LAST_DATA_IN 3U /* Last Data In Last */
#define USBD_BOT_SEND_DATA 4U /* Send Immediate data */
#define USBD_BOT_NO_DATA 5U /* No data Stage */
#define USBD_BOT_CBW_SIGNATURE 0x43425355U
#define USBD_BOT_CSW_SIGNATURE 0x53425355U
#define USBD_BOT_CBW_LENGTH 31U
#define USBD_BOT_CSW_LENGTH 13U
#define USBD_BOT_MAX_DATA 256U
/* CSW Status Definitions */
#define USBD_CSW_CMD_PASSED 0x00U
#define USBD_CSW_CMD_FAILED 0x01U
#define USBD_CSW_PHASE_ERROR 0x02U
/* BOT Status */
#define USBD_BOT_STATUS_NORMAL 0U
#define USBD_BOT_STATUS_RECOVERY 1U
#define USBD_BOT_STATUS_ERROR 2U
#define USBD_DIR_IN 0U
#define USBD_DIR_OUT 1U
#define USBD_BOTH_DIR 2U
/**
* @}
*/
/*------------------------------------------------------------------------------------
Typedef
------------------------------------------- -----------------------------------------*/
/** @defgroup MSC_CORE_Private_TypesDefinitions
* @{
*/
typedef struct
{
uint32_t dSignature;
uint32_t dTag;
uint32_t dDataLength;
uint8_t bmFlags;
uint8_t bLUN;
uint8_t bCBLength;
uint8_t CB[16];
uint8_t ReservedForAlign;
} USBD_MSC_BOT_CBWTypeDef;
typedef struct
{
uint32_t dSignature;
uint32_t dTag;
uint32_t dDataResidue;
uint8_t bStatus;
uint8_t ReservedForAlign[3];
} USBD_MSC_BOT_CSWTypeDef;
/**
* @}
*/
/*------------------------------------------------------------------------------------
Exported Functions
-------------------------------------------------------------------------------------*/
/** @defgroup USBD_CORE_Exported_FunctionsPrototypes
* @{
*/
void MSC_BOT_Init(USBD_HandleTypeDef *pdev);
void MSC_BOT_Reset(USBD_HandleTypeDef *pdev);
void MSC_BOT_DeInit(USBD_HandleTypeDef *pdev);
void MSC_BOT_DataIn(USBD_HandleTypeDef *pdev,
uint8_t epnum);
void MSC_BOT_DataOut(USBD_HandleTypeDef *pdev,
uint8_t epnum);
void MSC_BOT_SendCSW(USBD_HandleTypeDef *pdev,
uint8_t CSW_Status);
void MSC_BOT_CplClrFeature(USBD_HandleTypeDef *pdev,
uint8_t epnum);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBD_MSC_BOT_H */
@@ -0,0 +1,58 @@
/*!
* \file usbd_msc_data.c
*
* \brief This file provides all the vital inquiry pages and sense data.
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author MCD Application Team
*
* \author ( XinChip ) Alex-J
*/
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_msc_data.h"
/*------------------------------------------------------------------------------------
Global Variables
-------------------------------------------------------------------------------------*/
/* USB Mass storage Page 0 Inquiry Data */
uint8_t MSC_Page00_Inquiry_Data[LENGTH_INQUIRY_PAGE00] = {
0x00, 0x00, 0x00, (LENGTH_INQUIRY_PAGE00 - 4U),
0x00, 0x80
// 0x83 //alex revise
};
/* USB Mass storage VPD Page 0x80 Inquiry Data for Unit Serial Number */
uint8_t MSC_Page80_Inquiry_Data[LENGTH_INQUIRY_PAGE80] = {
0x00, 0x80, 0x00, LENGTH_INQUIRY_PAGE80,
0x20, /* Put Product Serial number */
0x20, 0x20, 0x20};
/* USB Mass storage sense 6 Data */
uint8_t MSC_Mode_Sense6_data[MODE_SENSE6_LEN] = {
0x22, 0x00, 0x00, 0x00, 0x08, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
/* USB Mass storage sense 10 Data */
uint8_t MSC_Mode_Sense10_data[MODE_SENSE10_LEN] = {
0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
/**
* @}
*/
@@ -0,0 +1,74 @@
/*!
* \file usbd_msc_data.h
*
* \brief Header for the usbd_msc_data.c file.
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author MCD Application Team
*
* \author ( XinChip ) Alex-J
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_MSC_DATA_H
#define __USBD_MSC_DATA_H
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_conf.h"
/*------------------------------------------------------------------------------------
Macros
------------------------------------------- -----------------------------------------*/
/** @defgroup USB_INFO_Exported_Defines
* @{
*/
#define MODE_SENSE6_LEN 0x17U
#define MODE_SENSE10_LEN 0x1BU
#define LENGTH_INQUIRY_PAGE00 0x06U //0x07U//0x06U alex revise
#define LENGTH_INQUIRY_PAGE80 0x08U
#define LENGTH_FORMAT_CAPACITIES 0x14U
/**
* @}
*/
/*------------------------------------------------------------------------------------
Exported Functions
-------------------------------------------------------------------------------------*/
/** @defgroup USBD_INFO_Exported_Variables
* @{
*/
extern uint8_t MSC_Page00_Inquiry_Data[LENGTH_INQUIRY_PAGE00];
extern uint8_t MSC_Page80_Inquiry_Data[LENGTH_INQUIRY_PAGE80];
extern uint8_t MSC_Mode_Sense6_data[MODE_SENSE6_LEN];
extern uint8_t MSC_Mode_Sense10_data[MODE_SENSE10_LEN];
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBD_MSC_DATA_H */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,163 @@
/*!
* \file usbd_msc_scsi.h
*
* \brief Header for the usbd_msc_scsi.c file.
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author MCD Application Team
*
* \author ( XinChip ) Alex-J
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_MSC_SCSI_H
#define __USBD_MSC_SCSI_H
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_def.h"
/*------------------------------------------------------------------------------------
Macros
------------------------------------------- -----------------------------------------*/
/** @defgroup USBD_SCSI_Exported_Defines
* @{
*/
#define SENSE_LIST_DEEPTH 4U
/* SCSI Commands */
#define SCSI_FORMAT_UNIT 0x04U
#define SCSI_INQUIRY 0x12U
#define SCSI_MODE_SELECT6 0x15U
#define SCSI_MODE_SELECT10 0x55U
#define SCSI_MODE_SENSE6 0x1AU
#define SCSI_MODE_SENSE10 0x5AU
#define SCSI_ALLOW_MEDIUM_REMOVAL 0x1EU
#define SCSI_READ6 0x08U
#define SCSI_READ10 0x28U
#define SCSI_READ12 0xA8U
#define SCSI_READ16 0x88U
#define SCSI_READ_CAPACITY10 0x25U
#define SCSI_READ_CAPACITY16 0x9EU
#define SCSI_REQUEST_SENSE 0x03U
#define SCSI_START_STOP_UNIT 0x1BU
#define SCSI_TEST_UNIT_READY 0x00U
#define SCSI_WRITE6 0x0AU
#define SCSI_WRITE10 0x2AU
#define SCSI_WRITE12 0xAAU
#define SCSI_WRITE16 0x8AU
#define SCSI_VERIFY10 0x2FU
#define SCSI_VERIFY12 0xAFU
#define SCSI_VERIFY16 0x8FU
#define SCSI_SEND_DIAGNOSTIC 0x1DU
#define SCSI_READ_FORMAT_CAPACITIES 0x23U
#define NO_SENSE 0U
#define RECOVERED_ERROR 1U
#define NOT_READY 2U
#define MEDIUM_ERROR 3U
#define HARDWARE_ERROR 4U
#define ILLEGAL_REQUEST 5U
#define UNIT_ATTENTION 6U
#define DATA_PROTECT 7U
#define BLANK_CHECK 8U
#define VENDOR_SPECIFIC 9U
#define COPY_ABORTED 10U
#define ABORTED_COMMAND 11U
#define VOLUME_OVERFLOW 13U
#define MISCOMPARE 14U
#define INVALID_CDB 0x20U
#define INVALID_FIELED_IN_COMMAND 0x24U
#define PARAMETER_LIST_LENGTH_ERROR 0x1AU
#define INVALID_FIELD_IN_PARAMETER_LIST 0x26U
#define ADDRESS_OUT_OF_RANGE 0x21U
#define MEDIUM_NOT_PRESENT 0x3AU
#define MEDIUM_HAVE_CHANGED 0x28U
#define WRITE_PROTECTED 0x27U
#define UNRECOVERED_READ_ERROR 0x11U
#define WRITE_FAULT 0x03U
#define READ_FORMAT_CAPACITY_DATA_LEN 0x0CU
#define READ_CAPACITY10_DATA_LEN 0x08U
#define REQUEST_SENSE_DATA_LEN 0x12U
#define STANDARD_INQUIRY_DATA_LEN 0x24U
#define BLKVFY 0x04U
#define SCSI_MEDIUM_UNLOCKED 0x00U
#define SCSI_MEDIUM_LOCKED 0x01U
#define SCSI_MEDIUM_EJECTED 0x02U
/**
* @}
*/
/*------------------------------------------------------------------------------------
Typedef
------------------------------------------- -----------------------------------------*/
/** @defgroup USBD_SCSI_Exported_TypesDefinitions
* @{
*/
typedef struct _SENSE_ITEM
{
uint8_t Skey;
union
{
struct _ASCs
{
uint8_t ASC;
uint8_t ASCQ;
} b;
uint8_t ASC;
uint8_t *pData;
} w;
} USBD_SCSI_SenseTypeDef;
/**
* @}
*/
/*------------------------------------------------------------------------------------
Exported Functions
-------------------------------------------------------------------------------------*/
/** @defgroup USBD_SCSI_Exported_FunctionsPrototype
* @{
*/
int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *cmd);
void SCSI_SenseCode(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t sKey,
uint8_t ASC);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBD_MSC_SCSI_H */
@@ -0,0 +1,732 @@
/*!
* \file usbd_core.c
*
* \brief This file provides all the USBD core functions.
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author MCD Application Team
*
* \author ( XinChip ) Alex-J
*/
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_core.h"
/*------------------------------------------------------------------------------------
Global Variables
-------------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------------
Functions
-------------------------------------------------------------------------------------*/
/**
* @brief USBD_Init
* Initializes the device stack and load the class driver
* @param pdev: device instance
* @param pdesc: Descriptor structure address
* @param id: Low level core index
* @retval None
*/
USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev,
USBD_DescriptorsTypeDef *pdesc, uint8_t id)
{
USBD_StatusTypeDef ret;
/* Check whether the USB Host handle is valid */
if (pdev == NULL) {
#if (USBD_DEBUG_LEVEL > 1U)
USBD_ErrLog("Invalid Device handle");
#endif /* (USBD_DEBUG_LEVEL > 1U) */
return USBD_FAIL;
}
/* Unlink previous class*/
pdev->pClass[0] = NULL;
pdev->pUserData[0] = NULL;
pdev->pConfDesc = NULL;
/* Assign USBD Descriptors */
if (pdesc != NULL) {
pdev->pDesc = pdesc;
}
/* Set Device initial State */
pdev->dev_state = USBD_STATE_DEFAULT;
pdev->id = id;
/* Initialize low level driver */
ret = USBD_LL_Init(pdev);
return ret;
}
/**
* @brief USBD_DeInit
* Re-Initialize the device library
* @param pdev: device instance
* @retval status: status
*/
USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev)
{
USBD_StatusTypeDef ret;
/* Disconnect the USB Device */
(void)USBD_LL_Stop(pdev);
/* Set Default State */
pdev->dev_state = USBD_STATE_DEFAULT;
/* Free Class Resources */
if (pdev->pClass[0] != NULL) {
pdev->pClass[0]->DeInit(pdev, (uint8_t)pdev->dev_config);
}
pdev->pUserData[0] = NULL;
/* Free Device descriptors resources */
pdev->pDesc = NULL;
pdev->pConfDesc = NULL;
/* DeInitialize low level driver */
ret = USBD_LL_DeInit(pdev);
return ret;
}
/**
* @brief USBD_RegisterClass
* Link class driver to Device Core.
* @param pDevice : Device Handle
* @param pclass: Class handle
* @retval USBD Status
*/
USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev,
USBD_ClassTypeDef *pclass)
{
uint16_t len = 0U;
if (pclass == NULL) {
#if (USBD_DEBUG_LEVEL > 1U)
USBD_ErrLog("Invalid Class handle");
#endif /* (USBD_DEBUG_LEVEL > 1U) */
return USBD_FAIL;
}
/* link the class to the USB Device handle */
pdev->pClass[0] = pclass;
/* Get Device Configuration Descriptor */
if (pdev->pClass[pdev->classId]->GetFSConfigDescriptor != NULL) {
pdev->pConfDesc =
(void *)pdev->pClass[pdev->classId]->GetFSConfigDescriptor(&len);
}
/* Increment the NumClasses */
pdev->NumClasses++;
return USBD_OK;
}
/**
* @brief USBD_Start
* Start the USB Device Core.
* @param pdev: Device Handle
* @retval USBD Status
*/
USBD_StatusTypeDef USBD_Start(USBD_HandleTypeDef *pdev)
{
/* Start the low level driver */
return USBD_LL_Start(pdev);
}
/**
* @brief USBD_Stop
* Stop the USB Device Core.
* @param pdev: Device Handle
* @retval USBD Status
*/
USBD_StatusTypeDef USBD_Stop(USBD_HandleTypeDef *pdev)
{
/* Disconnect USB Device */
(void)USBD_LL_Stop(pdev);
if (pdev->pClass[0] != NULL) {
(void)pdev->pClass[0]->DeInit(pdev, (uint8_t)pdev->dev_config);
}
return USBD_OK;
}
/**
* @brief USBD_RunTestMode
* Launch test mode process
* @param pdev: device instance
* @retval status
*/
USBD_StatusTypeDef USBD_RunTestMode(USBD_HandleTypeDef *pdev)
{
#ifdef USBD_HS_TESTMODE_ENABLE
USBD_StatusTypeDef ret;
/* Run USB HS test mode */
ret = USBD_LL_SetTestMode(pdev, pdev->dev_test_mode);
return ret;
#else
/* Prevent unused argument compilation warning */
UNUSED(pdev);
return USBD_OK;
#endif /* USBD_HS_TESTMODE_ENABLE */
}
/**
* @brief USBD_SetClassConfig
* Configure device and start the interface
* @param pdev: device instance
* @param cfgidx: configuration index
* @retval status
*/
USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
USBD_StatusTypeDef ret = USBD_OK;
if (pdev->pClass[0] != NULL) {
/* Set configuration and Start the Class */
ret = (USBD_StatusTypeDef)pdev->pClass[0]->Init(pdev, cfgidx);
}
return ret;
}
/**
* @brief USBD_ClrClassConfig
* Clear current configuration
* @param pdev: device instance
* @param cfgidx: configuration index
* @retval status: USBD_StatusTypeDef
*/
USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
{
USBD_StatusTypeDef ret = USBD_OK;
/* Clear configuration and De-initialize the Class process */
if (pdev->pClass[0]->DeInit(pdev, cfgidx) != 0U) {
ret = USBD_FAIL;
}
return ret;
}
/**
* @brief USBD_LL_SetupStage
* Handle the setup stage
* @param pdev: device instance
* @retval status
*/
USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup)
{
USBD_StatusTypeDef ret;
USBD_ParseSetupRequest(&pdev->request, psetup);
pdev->ep0_state = USBD_EP0_SETUP;
pdev->ep0_data_len = pdev->request.wLength;
switch (pdev->request.bmRequest & 0x1FU) {
case USB_REQ_RECIPIENT_DEVICE:
ret = USBD_StdDevReq(pdev, &pdev->request);
break;
case USB_REQ_RECIPIENT_INTERFACE:
ret = USBD_StdItfReq(pdev, &pdev->request);
break;
case USB_REQ_RECIPIENT_ENDPOINT:
ret = USBD_StdEPReq(pdev, &pdev->request);
break;
default:
ret = USBD_LL_StallEP(pdev, (pdev->request.bmRequest & 0x80U));
break;
}
return ret;
}
/**
* @brief USBD_LL_DataOutStage
* Handle data OUT stage
* @param pdev: device instance
* @param epnum: endpoint index
* @param pdata: data pointer
* @retval status
*/
USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev, uint8_t epnum,
uint8_t *pdata)
{
USBD_EndpointTypeDef *pep;
USBD_StatusTypeDef ret = USBD_OK;
uint8_t idx;
if (epnum == 0U) {
pep = &pdev->ep_out[0];
if (pdev->ep0_state == USBD_EP0_DATA_OUT) {
if (pep->rem_length > pep->maxpacket) {
pep->rem_length -= pep->maxpacket;
(void)USBD_CtlContinueRx(pdev, pdata,
MIN(pep->rem_length, pep->maxpacket));
} else {
// alex revise
/* Find the class ID relative to the current request */
switch (pdev->request.bmRequest & 0x1FU) {
case USB_REQ_RECIPIENT_DEVICE:
/* Device requests must be managed by the first instantiated
class (or duplicated by all classes for simplicity) */
idx = 0U;
break;
case USB_REQ_RECIPIENT_INTERFACE:
idx = USBD_CoreFindIF(pdev, LOBYTE(pdev->request.wIndex));
break;
case USB_REQ_RECIPIENT_ENDPOINT:
idx = USBD_CoreFindEP(pdev, LOBYTE(pdev->request.wIndex));
break;
default:
/* Back to the first class in case of doubt */
idx = 0U;
break;
}
if (idx < USBD_MAX_SUPPORTED_CLASS) {
/* Setup the class ID and route the request to the relative
* class function */
if (pdev->dev_state == USBD_STATE_CONFIGURED) {
if (pdev->pClass[idx]->EP0_RxReady != NULL) {
pdev->classId = idx;
pdev->pClass[idx]->EP0_RxReady(pdev);
}
}
}
(void)USBD_CtlSendStatus(pdev);
}
} else {
#if 0
if (pdev->ep0_state == USBD_EP0_STATUS_OUT)
{
/*
* STATUS PHASE completed, update ep0_state to idle
*/
pdev->ep0_state = USBD_EP0_IDLE;
(void)USBD_LL_StallEP(pdev, 0U);
}
#endif
}
} else {
/* Get the class index relative to this interface */
idx = USBD_CoreFindEP(pdev, (epnum & 0x7FU));
if (((uint16_t)idx != 0xFFU) && (idx < USBD_MAX_SUPPORTED_CLASS)) {
/* Call the class data out function to manage the request */
if (pdev->dev_state == USBD_STATE_CONFIGURED) {
if (pdev->pClass[idx]->DataOut != NULL) {
pdev->classId = idx;
ret = (USBD_StatusTypeDef)pdev->pClass[idx]->DataOut(pdev,
epnum);
}
}
if (ret != USBD_OK) {
return ret;
}
}
}
return USBD_OK;
}
/**
* @brief USBD_LL_DataInStage
* Handle data in stage
* @param pdev: device instance
* @param epnum: endpoint index
* @retval status
*/
USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, uint8_t epnum,
uint8_t *pdata)
{
USBD_EndpointTypeDef *pep;
USBD_StatusTypeDef ret;
uint8_t idx;
if (epnum == 0U) {
pep = &pdev->ep_in[0];
if (pdev->ep0_state == USBD_EP0_DATA_IN) {
if (pep->rem_length > pep->maxpacket) {
pep->rem_length -= pep->maxpacket;
(void)USBD_CtlContinueSendData(pdev, pdata, pep->rem_length);
/* Prepare endpoint for premature end of transfer */
// (void)USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U);
} else {
/* last packet is MPS multiple, so send ZLP packet */
if ((pep->total_length % pep->maxpacket == 0) &&
(pep->total_length >= pep->maxpacket) &&
(pep->total_length < pdev->ep0_data_len)) {
(void)USBD_CtlContinueSendData(pdev, NULL, 0U);
pdev->ep0_data_len = 0U;
/* Prepare endpoint for premature end of transfer */
// (void)USBD_LL_PrepareReceive(pdev, 0U, NULL,
// 0U);
} else {
// if (pdev->dev_state == USBD_STATE_CONFIGURED)
// {
// if (pdev->pClass[0]->EP0_TxSent != NULL)
// {
// pdev->classId = 0U;
// pdev->pClass[0]->EP0_TxSent(pdev);
// }
// }
// (void)USBD_LL_StallEP(pdev, 0x80U);
(void)USBD_CtlReceiveStatus(pdev);
}
}
} else {
#if 0
if ((pdev->ep0_state == USBD_EP0_STATUS_IN) ||
(pdev->ep0_state == USBD_EP0_IDLE))
{
(void)USBD_LL_StallEP(pdev, 0x80U);
}
#endif
}
if (pdev->dev_test_mode != 0U) {
(void)USBD_RunTestMode(pdev);
pdev->dev_test_mode = 0U;
}
} else {
/* Get the class index relative to this interface */
idx = USBD_CoreFindEP(pdev, ((uint8_t)epnum | 0x80U));
if (((uint16_t)idx != 0xFFU) && (idx < USBD_MAX_SUPPORTED_CLASS)) {
/* Call the class data out function to manage the request */
if (pdev->dev_state == USBD_STATE_CONFIGURED) {
if (pdev->pClass[idx]->DataIn != NULL) {
pdev->classId = idx;
ret = (USBD_StatusTypeDef)pdev->pClass[idx]->DataIn(pdev,
epnum);
if (ret != USBD_OK) {
return ret;
}
}
}
}
}
return USBD_OK;
}
/**
* @brief USBD_LL_Reset
* Handle Reset event
* @param pdev: device instance
* @retval status
*/
USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev)
{
USBD_StatusTypeDef ret = USBD_OK;
/* Upon Reset call user call back */
pdev->dev_state = USBD_STATE_DEFAULT;
pdev->ep0_state = USBD_EP0_IDLE;
pdev->dev_config = 0U;
pdev->dev_remote_wakeup = 0U;
pdev->dev_test_mode = 0U;
if (pdev->pClass[0] != NULL) {
if (pdev->pClass[0]->DeInit != NULL) {
if (pdev->pClass[0]->DeInit(pdev, (uint8_t)pdev->dev_config) !=
USBD_OK) {
ret = USBD_FAIL;
}
}
}
/* Open EP0 OUT */
(void)USBD_LL_OpenEP(pdev, 0x00U, USBD_EP_TYPE_CTRL, USB_MAX_EP0_SIZE);
pdev->ep_out[0x00U & 0xFU].is_used = 1U;
pdev->ep_out[0].maxpacket = USB_MAX_EP0_SIZE;
/* Open EP0 IN */
(void)USBD_LL_OpenEP(pdev, 0x80U, USBD_EP_TYPE_CTRL, USB_MAX_EP0_SIZE);
pdev->ep_in[0x80U & 0xFU].is_used = 1U;
pdev->ep_in[0].maxpacket = USB_MAX_EP0_SIZE;
return ret;
}
/**
* @brief USBD_LL_SetSpeed
* Handle Reset event
* @param pdev: device instance
* @retval status
*/
USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev,
USBD_SpeedTypeDef speed)
{
pdev->dev_speed = speed;
return USBD_OK;
}
/**
* @brief USBD_LL_Suspend
* Handle Suspend event
* @param pdev: device instance
* @retval status
*/
USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev)
{
pdev->dev_old_state = pdev->dev_state;
pdev->dev_state = USBD_STATE_SUSPENDED;
return USBD_OK;
}
/**
* @brief USBD_LL_Resume
* Handle Resume event
* @param pdev: device instance
* @retval status
*/
USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev)
{
if (pdev->dev_state == USBD_STATE_SUSPENDED) {
pdev->dev_state = pdev->dev_old_state;
}
return USBD_OK;
}
/**
* @brief USBD_LL_SOF
* Handle SOF event
* @param pdev: device instance
* @retval status
*/
USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev)
{
/* The SOF event can be distributed for all classes that support it */
if (pdev->dev_state == USBD_STATE_CONFIGURED) {
if (pdev->pClass[0] != NULL) {
if (pdev->pClass[0]->SOF != NULL) {
(void)pdev->pClass[0]->SOF(pdev);
}
}
}
return USBD_OK;
}
/**
* @brief USBD_LL_IsoINIncomplete
* Handle iso in incomplete event
* @param pdev: device instance
* @retval status
*/
USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev,
uint8_t epnum)
{
if (pdev->pClass[pdev->classId] == NULL) {
return USBD_FAIL;
}
if (pdev->dev_state == USBD_STATE_CONFIGURED) {
if (pdev->pClass[pdev->classId]->IsoINIncomplete != NULL) {
(void)pdev->pClass[pdev->classId]->IsoINIncomplete(pdev, epnum);
}
}
return USBD_OK;
}
/**
* @brief USBD_LL_IsoOUTIncomplete
* Handle iso out incomplete event
* @param pdev: device instance
* @retval status
*/
USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev,
uint8_t epnum)
{
if (pdev->pClass[pdev->classId] == NULL) {
return USBD_FAIL;
}
if (pdev->dev_state == USBD_STATE_CONFIGURED) {
if (pdev->pClass[pdev->classId]->IsoOUTIncomplete != NULL) {
(void)pdev->pClass[pdev->classId]->IsoOUTIncomplete(pdev, epnum);
}
}
return USBD_OK;
}
/**
* @brief USBD_LL_DevConnected
* Handle device connection event
* @param pdev: device instance
* @retval status
*/
USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev)
{
/* Prevent unused argument compilation warning */
UNUSED(pdev);
return USBD_OK;
}
/**
* @brief USBD_LL_DevDisconnected
* Handle device disconnection event
* @param pdev: device instance
* @retval status
*/
USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev)
{
USBD_StatusTypeDef ret = USBD_OK;
/* Free Class Resources */
pdev->dev_state = USBD_STATE_DEFAULT;
if (pdev->pClass[0] != NULL) {
if (pdev->pClass[0]->DeInit(pdev, (uint8_t)pdev->dev_config) != 0U) {
ret = USBD_FAIL;
}
}
return ret;
}
/**
* @brief USBD_CoreFindIF
* return the class index relative to the selected interface
* @param pdev: device instance
* @param index : selected interface number
* @retval index of the class using the selected interface number. OxFF if no
* class found.
*/
uint8_t USBD_CoreFindIF(USBD_HandleTypeDef *pdev, uint8_t index)
{
UNUSED(pdev);
UNUSED(index);
return 0x00U;
}
/**
* @brief USBD_CoreFindEP
* return the class index relative to the selected endpoint
* @param pdev: device instance
* @param index : selected endpoint number
* @retval index of the class using the selected endpoint number. 0xFF if no
* class found.
*/
uint8_t USBD_CoreFindEP(USBD_HandleTypeDef *pdev, uint8_t index)
{
UNUSED(pdev);
UNUSED(index);
return 0x00U;
}
/**
* @brief USBD_GetEpDesc
* This function return the Endpoint descriptor
* @param pdev: device instance
* @param pConfDesc: pointer to Bos descriptor
* @param EpAddr: endpoint address
* @retval pointer to video endpoint descriptor
*/
void *USBD_GetEpDesc(uint8_t *pConfDesc, uint8_t EpAddr)
{
USBD_DescHeaderTypeDef *pdesc = (USBD_DescHeaderTypeDef *)(void *)pConfDesc;
USBD_ConfigDescTypeDef *desc = (USBD_ConfigDescTypeDef *)(void *)pConfDesc;
USBD_EpDescTypeDef *pEpDesc = NULL;
uint16_t ptr;
if (desc->wTotalLength > desc->bLength) {
ptr = desc->bLength;
while (ptr < desc->wTotalLength) {
pdesc = USBD_GetNextDesc((uint8_t *)pdesc, &ptr);
if (pdesc->bDescriptorType == USB_DESC_TYPE_ENDPOINT) {
pEpDesc = (USBD_EpDescTypeDef *)(void *)pdesc;
if (pEpDesc->bEndpointAddress == EpAddr) {
break;
} else {
pEpDesc = NULL;
}
}
}
}
return (void *)pEpDesc;
}
/**
* @brief USBD_GetNextDesc
* This function return the next descriptor header
* @param buf: Buffer where the descriptor is available
* @param ptr: data pointer inside the descriptor
* @retval next header
*/
USBD_DescHeaderTypeDef *USBD_GetNextDesc(uint8_t *pbuf, uint16_t *ptr)
{
USBD_DescHeaderTypeDef *pnext = (USBD_DescHeaderTypeDef *)(void *)pbuf;
*ptr += pnext->bLength;
pnext = (USBD_DescHeaderTypeDef *)(void *)(pbuf + pnext->bLength);
return (pnext);
}
/**
* @}
*/
@@ -0,0 +1,130 @@
/*!
* \file usbd_core.h
*
* \brief Header file for usbd_core.c file.
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author MCD Application Team
*
* \author ( XinChip ) Alex-J
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_CORE_H
#define __USBD_CORE_H
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_conf.h"
#include "usbd_def.h"
#include "usbd_ioreq.h"
#include "usbd_ctlreq.h"
/*------------------------------------------------------------------------------------
Macros
------------------------------------------- -----------------------------------------*/
/** @defgroup USBD_CORE_Exported_Variables
* @{
*/
#define USBD_SOF USBD_LL_SOF
/**
* @}
*/
/*------------------------------------------------------------------------------------
Exported Functions
-------------------------------------------------------------------------------------*/
/** @defgroup USBD_CORE_Exported_FunctionsPrototype
* @{
*/
USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, USBD_DescriptorsTypeDef *pdesc, uint8_t id);
USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef USBD_Start(USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef USBD_Stop(USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass);
uint8_t USBD_CoreFindIF(USBD_HandleTypeDef *pdev, uint8_t index);
uint8_t USBD_CoreFindEP(USBD_HandleTypeDef *pdev, uint8_t index);
USBD_StatusTypeDef USBD_RunTestMode(USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup);
USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev, uint8_t epnum, uint8_t *pdata);
USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, uint8_t epnum, uint8_t *pdata);
USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev, USBD_SpeedTypeDef speed);
USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum);
USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum);
USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev);
/* USBD Low Level Driver */
USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr,
uint8_t ep_type, uint16_t ep_mps);
USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr);
USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr);
USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr);
USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr);
USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr);
USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, uint8_t ep_addr,
uint8_t *pbuf, uint32_t size);
USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, uint8_t ep_addr,
uint8_t *pbuf, uint32_t size);
#ifdef USBD_HS_TESTMODE_ENABLE
USBD_StatusTypeDef USBD_LL_SetTestMode(USBD_HandleTypeDef *pdev, uint8_t testmode);
#endif /* USBD_HS_TESTMODE_ENABLE */
uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr);
uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr);
void USBD_LL_Delay(uint32_t Delay);
void *USBD_GetEpDesc(uint8_t *pConfDesc, uint8_t EpAddr);
USBD_DescHeaderTypeDef *USBD_GetNextDesc(uint8_t *pbuf, uint16_t *ptr);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBD_CORE_H */
@@ -0,0 +1,886 @@
/*!
* \file usbd_ctlreq.c
*
* \brief This file provides the standard USB requests following chapter 9.
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author MCD Application Team
*
* \author ( XinChip ) Alex-J
*/
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_ctlreq.h"
#include "usbd_ioreq.h"
/*------------------------------------------------------------------------------------
Global Variables
-------------------------------------------------------------------------------------*/
// volatile uint32_t rec_type = 0;
/*------------------------------------------------------------------------------------
Func Prototype
-------------------------------------------------------------------------------------*/
/** @defgroup USBD_REQ_Private_FunctionPrototypes
* @{
*/
static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev,
USBD_SetupReqTypedef *req);
static void USBD_SetAddress(USBD_HandleTypeDef *pdev,
USBD_SetupReqTypedef *req);
static USBD_StatusTypeDef USBD_SetConfig(USBD_HandleTypeDef *pdev,
USBD_SetupReqTypedef *req);
static void USBD_GetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
static void USBD_GetStatus(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
static void USBD_SetFeature(USBD_HandleTypeDef *pdev,
USBD_SetupReqTypedef *req);
static void USBD_ClrFeature(USBD_HandleTypeDef *pdev,
USBD_SetupReqTypedef *req);
static uint8_t USBD_GetLen(uint8_t *buf);
/**
* @}
*/
/*------------------------------------------------------------------------------------
Functions
-------------------------------------------------------------------------------------*/
/**
* @brief USBD_StdDevReq
* Handle standard usb device requests
* @param pdev: device instance
* @param req: usb request
* @retval status
*/
USBD_StatusTypeDef USBD_StdDevReq(USBD_HandleTypeDef *pdev,
USBD_SetupReqTypedef *req)
{
USBD_StatusTypeDef ret = USBD_OK;
switch (req->bmRequest & USB_REQ_TYPE_MASK) {
case USB_REQ_TYPE_CLASS:
case USB_REQ_TYPE_VENDOR:
ret = (USBD_StatusTypeDef)pdev->pClass[pdev->classId]->Setup(pdev, req);
break;
case USB_REQ_TYPE_STANDARD:
switch (req->bRequest) {
case USB_REQ_GET_DESCRIPTOR:
USBD_GetDescriptor(pdev, req);
break;
case USB_REQ_SET_ADDRESS:
USBD_SetAddress(pdev, req);
break;
case USB_REQ_SET_CONFIGURATION:
ret = USBD_SetConfig(pdev, req);
break;
case USB_REQ_GET_CONFIGURATION:
USBD_GetConfig(pdev, req);
break;
case USB_REQ_GET_STATUS:
USBD_GetStatus(pdev, req);
break;
case USB_REQ_SET_FEATURE:
USBD_SetFeature(pdev, req);
break;
case USB_REQ_CLEAR_FEATURE:
USBD_ClrFeature(pdev, req);
break;
default:
USBD_CtlError(pdev, req);
break;
}
break;
default:
USBD_CtlError(pdev, req);
break;
}
return ret;
}
/**
* @brief USBD_StdItfReq
* Handle standard usb interface requests
* @param pdev: device instance
* @param req: usb request
* @retval status
*/
USBD_StatusTypeDef USBD_StdItfReq(USBD_HandleTypeDef *pdev,
USBD_SetupReqTypedef *req)
{
USBD_StatusTypeDef ret = USBD_OK;
uint8_t idx;
switch (req->bmRequest & USB_REQ_TYPE_MASK) {
case USB_REQ_TYPE_CLASS:
case USB_REQ_TYPE_VENDOR:
case USB_REQ_TYPE_STANDARD:
switch (pdev->dev_state) {
case USBD_STATE_DEFAULT:
case USBD_STATE_ADDRESSED:
case USBD_STATE_CONFIGURED:
if (LOBYTE(req->wIndex) <= USBD_MAX_NUM_INTERFACES) {
/* Get the class index relative to this interface */
idx = USBD_CoreFindIF(pdev, LOBYTE(req->wIndex));
if (((uint8_t)idx != 0xFFU) &&
(idx < USBD_MAX_SUPPORTED_CLASS)) {
/* Call the class data out function to manage the request */
if (pdev->pClass[idx]->Setup != NULL) {
pdev->classId = idx;
ret = (USBD_StatusTypeDef)(pdev->pClass[idx]->Setup(
pdev, req));
} else {
/* should never reach this condition */
ret = USBD_FAIL;
}
} else {
/* No relative interface found */
ret = USBD_FAIL;
}
if ((req->wLength == 0U) && (ret == USBD_OK)) {
(void)USBD_CtlSendStatus(pdev);
}
} else {
USBD_CtlError(pdev, req);
}
break;
default:
USBD_CtlError(pdev, req);
break;
}
break;
default:
USBD_CtlError(pdev, req);
break;
}
return ret;
}
/**
* @brief USBD_StdEPReq
* Handle standard usb endpoint requests
* @param pdev: device instance
* @param req: usb request
* @retval status
*/
USBD_StatusTypeDef USBD_StdEPReq(USBD_HandleTypeDef *pdev,
USBD_SetupReqTypedef *req)
{
USBD_EndpointTypeDef *pep;
uint8_t ep_addr;
uint8_t idx;
USBD_StatusTypeDef ret = USBD_OK;
ep_addr = LOBYTE(req->wIndex);
switch (req->bmRequest & USB_REQ_TYPE_MASK) {
case USB_REQ_TYPE_CLASS:
case USB_REQ_TYPE_VENDOR:
/* Get the class index relative to this endpoint */
idx = USBD_CoreFindEP(pdev, ep_addr);
if (((uint8_t)idx != 0xFFU) && (idx < USBD_MAX_SUPPORTED_CLASS)) {
pdev->classId = idx;
/* Call the class data out function to manage the request */
if (pdev->pClass[idx]->Setup != NULL) {
ret = (USBD_StatusTypeDef)pdev->pClass[idx]->Setup(pdev, req);
}
}
break;
case USB_REQ_TYPE_STANDARD:
switch (req->bRequest) {
case USB_REQ_SET_FEATURE:
switch (pdev->dev_state) {
case USBD_STATE_ADDRESSED:
if ((ep_addr != 0x00U) && (ep_addr != 0x80U)) {
(void)USBD_LL_StallEP(pdev, ep_addr);
(void)USBD_LL_StallEP(pdev, 0x80U);
} else {
USBD_CtlError(pdev, req);
}
break;
case USBD_STATE_CONFIGURED:
if (req->wValue == USB_FEATURE_EP_HALT) {
if ((ep_addr != 0x00U) && (ep_addr != 0x80U) &&
(req->wLength == 0x00U)) {
(void)USBD_LL_StallEP(pdev, ep_addr);
}
}
(void)USBD_CtlSendStatus(pdev);
break;
default:
USBD_CtlError(pdev, req);
break;
}
break;
case USB_REQ_CLEAR_FEATURE:
switch (pdev->dev_state) {
case USBD_STATE_ADDRESSED:
if ((ep_addr != 0x00U) && (ep_addr != 0x80U)) {
(void)USBD_LL_StallEP(pdev, ep_addr);
(void)USBD_LL_StallEP(pdev, 0x80U);
} else {
USBD_CtlError(pdev, req);
}
break;
case USBD_STATE_CONFIGURED:
if (req->wValue == USB_FEATURE_EP_HALT) {
if ((ep_addr & 0x7FU) != 0x00U) {
(void)USBD_LL_ClearStallEP(pdev, ep_addr);
}
(void)USBD_CtlSendStatus(pdev);
/* Get the class index relative to this interface */
idx = USBD_CoreFindEP(pdev, ep_addr);
if (((uint8_t)idx != 0xFFU) &&
(idx < USBD_MAX_SUPPORTED_CLASS)) {
pdev->classId = idx;
/* Call the class data out function to manage the
* request */
if (pdev->pClass[idx]->Setup != NULL) {
ret = (USBD_StatusTypeDef)(pdev->pClass[idx]->Setup(
pdev, req));
}
}
}
break;
default:
USBD_CtlError(pdev, req);
break;
}
break;
case USB_REQ_GET_STATUS:
switch (pdev->dev_state) {
case USBD_STATE_ADDRESSED:
if ((ep_addr != 0x00U) && (ep_addr != 0x80U)) {
USBD_CtlError(pdev, req);
break;
}
pep = ((ep_addr & 0x80U) == 0x80U)
? &pdev->ep_in[ep_addr & 0x7FU]
: &pdev->ep_out[ep_addr & 0x7FU];
pep->status = 0x0000U;
(void)USBD_CtlSendData(pdev, (uint8_t *)&pep->status, 2U);
break;
case USBD_STATE_CONFIGURED:
if ((ep_addr & 0x80U) == 0x80U) {
if (pdev->ep_in[ep_addr & 0xFU].is_used == 0U) {
USBD_CtlError(pdev, req);
break;
}
} else {
if (pdev->ep_out[ep_addr & 0xFU].is_used == 0U) {
USBD_CtlError(pdev, req);
break;
}
}
pep = ((ep_addr & 0x80U) == 0x80U)
? &pdev->ep_in[ep_addr & 0x7FU]
: &pdev->ep_out[ep_addr & 0x7FU];
if ((ep_addr == 0x00U) || (ep_addr == 0x80U)) {
pep->status = 0x0000U;
} else if (USBD_LL_IsStallEP(pdev, ep_addr) != 0U) {
pep->status = 0x0001U;
} else {
pep->status = 0x0000U;
}
(void)USBD_CtlSendData(pdev, (uint8_t *)&pep->status, 2U);
break;
default:
USBD_CtlError(pdev, req);
break;
}
break;
default:
USBD_CtlError(pdev, req);
break;
}
break;
default:
USBD_CtlError(pdev, req);
break;
}
return ret;
}
/**
* @brief USBD_GetDescriptor
* Handle Get Descriptor requests
* @param pdev: device instance
* @param req: usb request
* @retval status
*/
static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev,
USBD_SetupReqTypedef *req)
{
uint16_t len = 0U;
uint8_t *pbuf = NULL;
uint8_t err = 0U;
switch (req->wValue >> 8) {
#if ((USBD_LPM_ENABLED == 1U) || (USBD_CLASS_BOS_ENABLED == 1U))
case USB_DESC_TYPE_BOS:
if (pdev->pDesc->GetBOSDescriptor != NULL) {
pbuf = pdev->pDesc->GetBOSDescriptor(pdev->dev_speed, &len);
} else {
USBD_CtlError(pdev, req);
err++;
}
break;
#endif /* (USBD_LPM_ENABLED == 1U) || (USBD_CLASS_BOS_ENABLED == 1U) */
case USB_DESC_TYPE_DEVICE:
pbuf = pdev->pDesc->GetDeviceDescriptor(pdev->dev_speed, &len);
// rec_type = DESC_TYPE_DEVICE;
if ((req->wLength == 64) || (pdev->dev_state == USBD_STATE_DEFAULT)) {
// len = 8;
}
break;
case USB_DESC_TYPE_CONFIGURATION:
// if (pdev->dev_speed == USBD_SPEED_HIGH)
// {
// pbuf = (uint8_t
// *)pdev->pClass[0]->GetHSConfigDescriptor(&len); pbuf[1] =
// USB_DESC_TYPE_CONFIGURATION;
// }
// else
{
pbuf = (uint8_t *)pdev->pClass[0]->GetFSConfigDescriptor(&len);
// rec_type = DESC_TYPE_CONFIGURATION;
pbuf[1] = USB_DESC_TYPE_CONFIGURATION;
}
break;
case USB_DESC_TYPE_STRING:
switch ((uint8_t)(req->wValue)) {
case USBD_IDX_LANGID_STR:
if (pdev->pDesc->GetLangIDStrDescriptor != NULL) {
pbuf =
pdev->pDesc->GetLangIDStrDescriptor(pdev->dev_speed, &len);
// rec_type = DESC_TYPE_LANGID_STR;
} else {
USBD_CtlError(pdev, req);
err++;
}
break;
case USBD_IDX_MFC_STR:
if (pdev->pDesc->GetManufacturerStrDescriptor != NULL) {
pbuf = pdev->pDesc->GetManufacturerStrDescriptor(
pdev->dev_speed, &len);
// rec_type = DESC_TYPE_MFC_STR;
} else {
USBD_CtlError(pdev, req);
err++;
}
break;
case USBD_IDX_PRODUCT_STR:
if (pdev->pDesc->GetProductStrDescriptor != NULL) {
pbuf =
pdev->pDesc->GetProductStrDescriptor(pdev->dev_speed, &len);
// rec_type = DESC_TYPE_PRODUCT_STR;
} else {
USBD_CtlError(pdev, req);
err++;
}
break;
case USBD_IDX_SERIAL_STR:
if (pdev->pDesc->GetSerialStrDescriptor != NULL) {
pbuf =
pdev->pDesc->GetSerialStrDescriptor(pdev->dev_speed, &len);
// rec_type = DESC_TYPE_SERIAL_STR;
} else {
USBD_CtlError(pdev, req);
err++;
}
break;
case USBD_IDX_CONFIG_STR:
if (pdev->pDesc->GetConfigurationStrDescriptor != NULL) {
pbuf = pdev->pDesc->GetConfigurationStrDescriptor(
pdev->dev_speed, &len);
// rec_type = DESC_TYPE_CONFIG_STR;
} else {
USBD_CtlError(pdev, req);
err++;
}
break;
case USBD_IDX_INTERFACE_STR:
if (pdev->pDesc->GetInterfaceStrDescriptor != NULL) {
pbuf = pdev->pDesc->GetInterfaceStrDescriptor(pdev->dev_speed,
&len);
// rec_type = DESC_TYPE_INTERFACE_STR;
} else {
USBD_CtlError(pdev, req);
err++;
}
break;
default:
#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
pbuf = NULL;
for (uint32_t idx = 0U; (idx < pdev->NumClasses); idx++) {
if (pdev->pClass[idx]->GetUsrStrDescriptor != NULL) {
pdev->classId = idx;
pbuf = pdev->pClass[idx]->GetUsrStrDescriptor(
pdev, LOBYTE(req->wValue), &len);
if (pbuf == NULL) /* This means that no class recognized the
string index */
{
continue;
} else {
break;
}
}
}
#endif /* USBD_SUPPORT_USER_STRING_DESC */
#if (USBD_CLASS_USER_STRING_DESC == 1U)
if (pdev->pDesc->GetUserStrDescriptor != NULL) {
pbuf = pdev->pDesc->GetUserStrDescriptor(pdev->dev_speed,
(req->wValue), &len);
} else {
USBD_CtlError(pdev, req);
err++;
}
#endif /* USBD_SUPPORT_USER_STRING_DESC */
#if ((USBD_CLASS_USER_STRING_DESC == 0U) && \
(USBD_SUPPORT_USER_STRING_DESC == 0U))
USBD_CtlError(pdev, req);
err++;
#endif /* (USBD_CLASS_USER_STRING_DESC == 0U) && \
(USBD_SUPPORT_USER_STRING_DESC == 0U) */
break;
}
break;
case USB_DESC_TYPE_DEVICE_QUALIFIER:
if (pdev->dev_speed == USBD_SPEED_HIGH) {
pbuf =
(uint8_t *)pdev->pClass[0]->GetDeviceQualifierDescriptor(&len);
// rec_type = DESC_TYPE_DEVICE_QUALIFIER;
} else {
USBD_CtlError(pdev, req);
err++;
}
break;
case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION:
if (pdev->dev_speed == USBD_SPEED_HIGH) {
pbuf =
(uint8_t *)pdev->pClass[0]->GetOtherSpeedConfigDescriptor(&len);
// rec_type = DESC_TYPE_OTHER_SPEED_CONFIGURATION;
pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION;
} else {
USBD_CtlError(pdev, req);
err++;
}
break;
default:
USBD_CtlError(pdev, req);
err++;
break;
}
if (err != 0U) {
// (void)USBD_CtlSendData(pdev, NULL, 0);
return;
}
if (req->wLength != 0U) {
if (len != 0U) {
len = MIN(len, req->wLength);
(void)USBD_CtlSendData(pdev, pbuf, len);
}
// else
// {
// USBD_CtlError(pdev, req);
// }
}
// else
// {
// (void)USBD_CtlSendStatus(pdev);
// }
}
/**
* @brief USBD_SetAddress
* Set device address
* @param pdev: device instance
* @param req: usb request
* @retval status
*/
static void USBD_SetAddress(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
uint8_t dev_addr;
if ((req->wIndex == 0U) && (req->wLength == 0U) && (req->wValue < 128U)) {
dev_addr = (uint8_t)(req->wValue) & 0x7FU;
if (pdev->dev_state == USBD_STATE_CONFIGURED) {
USBD_CtlError(pdev, req);
} else {
pdev->dev_address = dev_addr;
(void)USBD_LL_SetUSBAddress(pdev, dev_addr);
(void)USBD_CtlSendStatus(pdev);
if (dev_addr != 0U) {
pdev->dev_state = USBD_STATE_ADDRESSED;
} else {
pdev->dev_state = USBD_STATE_DEFAULT;
}
}
} else {
USBD_CtlError(pdev, req);
}
}
/**
* @brief USBD_SetConfig
* Handle Set device configuration request
* @param pdev: device instance
* @param req: usb request
* @retval status
*/
static USBD_StatusTypeDef USBD_SetConfig(USBD_HandleTypeDef *pdev,
USBD_SetupReqTypedef *req)
{
USBD_StatusTypeDef ret = USBD_OK;
static uint8_t cfgidx;
cfgidx = (uint8_t)(req->wValue);
if (cfgidx > USBD_MAX_NUM_CONFIGURATION) {
USBD_CtlError(pdev, req);
return USBD_FAIL;
}
switch (pdev->dev_state) {
case USBD_STATE_ADDRESSED:
if (cfgidx != 0U) {
pdev->dev_config = cfgidx;
ret = USBD_SetClassConfig(pdev, cfgidx);
if (ret != USBD_OK) {
USBD_CtlError(pdev, req);
pdev->dev_state = USBD_STATE_ADDRESSED;
} else {
(void)USBD_CtlSendStatus(pdev);
pdev->dev_state = USBD_STATE_CONFIGURED;
}
} else {
(void)USBD_CtlSendStatus(pdev);
}
break;
case USBD_STATE_CONFIGURED:
if (cfgidx == 0U) {
pdev->dev_state = USBD_STATE_ADDRESSED;
pdev->dev_config = cfgidx;
(void)USBD_ClrClassConfig(pdev, cfgidx);
(void)USBD_CtlSendStatus(pdev);
} else if (cfgidx != pdev->dev_config) {
/* Clear old configuration */
(void)USBD_ClrClassConfig(pdev, (uint8_t)pdev->dev_config);
/* set new configuration */
pdev->dev_config = cfgidx;
ret = USBD_SetClassConfig(pdev, cfgidx);
if (ret != USBD_OK) {
USBD_CtlError(pdev, req);
(void)USBD_ClrClassConfig(pdev, (uint8_t)pdev->dev_config);
pdev->dev_state = USBD_STATE_ADDRESSED;
} else {
(void)USBD_CtlSendStatus(pdev);
}
} else {
(void)USBD_CtlSendStatus(pdev);
}
break;
default:
USBD_CtlError(pdev, req);
(void)USBD_ClrClassConfig(pdev, cfgidx);
ret = USBD_FAIL;
break;
}
return ret;
}
/**
* @brief USBD_GetConfig
* Handle Get device configuration request
* @param pdev: device instance
* @param req: usb request
* @retval status
*/
static void USBD_GetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
if (req->wLength != 1U) {
USBD_CtlError(pdev, req);
} else {
switch (pdev->dev_state) {
case USBD_STATE_DEFAULT:
case USBD_STATE_ADDRESSED:
pdev->dev_default_config = 0U;
(void)USBD_CtlSendData(pdev, (uint8_t *)&pdev->dev_default_config,
1U);
break;
case USBD_STATE_CONFIGURED:
(void)USBD_CtlSendData(pdev, (uint8_t *)&pdev->dev_config, 1U);
break;
default:
USBD_CtlError(pdev, req);
break;
}
}
}
/**
* @brief USBD_GetStatus
* Handle Get Status request
* @param pdev: device instance
* @param req: usb request
* @retval status
*/
static void USBD_GetStatus(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
switch (pdev->dev_state) {
case USBD_STATE_DEFAULT:
case USBD_STATE_ADDRESSED:
case USBD_STATE_CONFIGURED:
if (req->wLength != 0x2U) {
USBD_CtlError(pdev, req);
break;
}
#if (USBD_SELF_POWERED == 1U)
pdev->dev_config_status = USB_CONFIG_SELF_POWERED;
#else
pdev->dev_config_status = 0U;
#endif /* USBD_SELF_POWERED */
if (pdev->dev_remote_wakeup != 0U) {
pdev->dev_config_status |= USB_CONFIG_REMOTE_WAKEUP;
}
(void)USBD_CtlSendData(pdev, (uint8_t *)&pdev->dev_config_status, 2U);
break;
default:
USBD_CtlError(pdev, req);
break;
}
}
/**
* @brief USBD_SetFeature
* Handle Set device feature request
* @param pdev: device instance
* @param req: usb request
* @retval status
*/
static void USBD_SetFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) {
pdev->dev_remote_wakeup = 1U;
(void)USBD_CtlSendStatus(pdev);
} else if (req->wValue == USB_FEATURE_TEST_MODE) {
pdev->dev_test_mode = req->wIndex >> 8;
(void)USBD_CtlSendStatus(pdev);
} else {
USBD_CtlError(pdev, req);
}
}
/**
* @brief USBD_ClrFeature
* Handle clear device feature request
* @param pdev: device instance
* @param req: usb request
* @retval status
*/
static void USBD_ClrFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
switch (pdev->dev_state) {
case USBD_STATE_DEFAULT:
case USBD_STATE_ADDRESSED:
case USBD_STATE_CONFIGURED:
if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) {
pdev->dev_remote_wakeup = 0U;
(void)USBD_CtlSendStatus(pdev);
}
break;
default:
USBD_CtlError(pdev, req);
break;
}
}
/**
* @brief USBD_ParseSetupRequest
* Copy buffer into setup structure
* @param pdev: device instance
* @param req: usb request
* @retval None
*/
void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata)
{
uint8_t *pbuff = pdata;
req->bmRequest = *(uint8_t *)(pbuff);
pbuff++;
req->bRequest = *(uint8_t *)(pbuff);
pbuff++;
req->wValue = SWAPBYTE(pbuff);
pbuff++;
pbuff++;
req->wIndex = SWAPBYTE(pbuff);
pbuff++;
pbuff++;
req->wLength = SWAPBYTE(pbuff);
}
/**
* @brief USBD_CtlError
* Handle USB low level Error
* @param pdev: device instance
* @param req: usb request
* @retval None
*/
void USBD_CtlError(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
{
UNUSED(req);
(void)USBD_LL_StallEP(pdev, 0x80U);
(void)USBD_LL_StallEP(pdev, 0U);
// alex revise
(void)USB_EP0_OutStart(pdev->pData, 0, NULL);
// DEBUG("USBD_CtlError\r\n");
// DEBUG("TODO: \r\n");
// DEBUG("\r\n");
}
/**
* @brief USBD_GetString
* Convert Ascii string into unicode one
* @param desc : descriptor buffer
* @param unicode : Formatted string buffer (unicode)
* @param len : descriptor length
* @retval None
*/
void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len)
{
uint8_t idx = 0U;
uint8_t *pdesc;
if (desc == NULL) {
return;
}
pdesc = desc;
*len = ((uint16_t)USBD_GetLen(pdesc) * 2U) + 2U;
unicode[idx] = *(uint8_t *)len;
idx++;
unicode[idx] = USB_DESC_TYPE_STRING;
idx++;
while (*pdesc != (uint8_t)'\0') {
unicode[idx] = *pdesc;
pdesc++;
idx++;
unicode[idx] = 0U;
idx++;
}
}
/**
* @brief USBD_GetLen
* return the string length
* @param buf : pointer to the ascii string buffer
* @retval string length
*/
static uint8_t USBD_GetLen(uint8_t *buf)
{
uint8_t len = 0U;
uint8_t *pbuff = buf;
while (*pbuff != (uint8_t)'\0') {
len++;
pbuff++;
}
return len;
}
/**
* @}
*/
@@ -0,0 +1,58 @@
/*!
* \file usbd_ctlreq.h
*
* \brief Header file for the usbd_req.c file
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author MCD Application Team
*
* \author ( XinChip ) Alex-J
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_REQUEST_H
#define __USB_REQUEST_H
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_def.h"
/*------------------------------------------------------------------------------------
Exported Functions
-------------------------------------------------------------------------------------*/
USBD_StatusTypeDef USBD_StdDevReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
USBD_StatusTypeDef USBD_StdItfReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
USBD_StatusTypeDef USBD_StdEPReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
void USBD_CtlError(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata);
void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USB_REQUEST_H */
@@ -0,0 +1,428 @@
/*!
* \file usbd_def.h
*
* \brief General defines for the usb device library
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author MCD Application Team
*
* \author ( XinChip ) Alex-J
*/
#ifndef __USBD_DEF_H
#define __USBD_DEF_H
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "xc_hal_pcd_np.h"
#include "usbd_conf.h"
/*------------------------------------------------------------------------------------
Macros
------------------------------------------- -----------------------------------------*/
/** @defgroup USB_DEF_Exported_Defines
* @{
*/
#if USB_HID
#define HID_MOUSE 0x01
#define HID_KEYBOARD 0x02
#define HID_CUSTOM 0x04
#define HID_DOUBLE_CUSTOM 0X08
#endif
#if USB_SINGLE_DEVICE
//#define HID_CLASS_MODE HID_MOUSE
#elif USB_COMPOSITE_DEVICE
#endif
#ifndef NULL
#define NULL 0U
#endif /* NULL */
#ifndef USBD_MAX_NUM_CONFIGURATION
#define USBD_MAX_NUM_CONFIGURATION 1U
#endif /* USBD_MAX_NUM_CONFIGURATION */
#ifndef USBD_MAX_SUPPORTED_CLASS
#define USBD_MAX_SUPPORTED_CLASS 1U
#endif /* USBD_MAX_SUPPORTED_CLASS */
#ifndef USBD_MAX_CLASS_ENDPOINTS
#define USBD_MAX_CLASS_ENDPOINTS 5U
#endif /* USBD_MAX_CLASS_ENDPOINTS */
#ifndef USBD_MAX_CLASS_INTERFACES
#define USBD_MAX_CLASS_INTERFACES 5U
#endif /* USBD_MAX_CLASS_INTERFACES */
#ifndef USBD_LPM_ENABLED
#define USBD_LPM_ENABLED 0U
#endif /* USBD_LPM_ENABLED */
#ifndef USBD_SELF_POWERED
#define USBD_SELF_POWERED 1U
#endif /*USBD_SELF_POWERED */
#ifndef USBD_MAX_POWER
#define USBD_MAX_POWER 0x32U /* 100 mA */
#endif /* USBD_MAX_POWER */
#ifndef USBD_SUPPORT_USER_STRING_DESC
#define USBD_SUPPORT_USER_STRING_DESC 0U
#endif /* USBD_SUPPORT_USER_STRING_DESC */
#ifndef USBD_CLASS_USER_STRING_DESC
#define USBD_CLASS_USER_STRING_DESC 0U
#endif /* USBD_CLASS_USER_STRING_DESC */
#define USB_LEN_DEV_QUALIFIER_DESC 0x0AU
#define USB_LEN_DEV_DESC 0x12U
#define USB_LEN_CFG_DESC 0x09U
#define USB_LEN_IF_DESC 0x09U
#define USB_LEN_EP_DESC 0x07U
#define USB_LEN_OTG_DESC 0x03U
#define USB_LEN_LANGID_STR_DESC 0x04U
#define USB_LEN_OTHER_SPEED_DESC_SIZ 0x09U
#define USBD_IDX_LANGID_STR 0x00U
#define USBD_IDX_MFC_STR 0x01U
#define USBD_IDX_PRODUCT_STR 0x02U
#define USBD_IDX_SERIAL_STR 0x03U
#define USBD_IDX_CONFIG_STR 0x04U
#define USBD_IDX_INTERFACE_STR 0x05U
#define USB_REQ_TYPE_STANDARD 0x00U
#define USB_REQ_TYPE_CLASS 0x20U
#define USB_REQ_TYPE_VENDOR 0x40U
#define USB_REQ_TYPE_MASK 0x60U
#define USB_REQ_RECIPIENT_DEVICE 0x00U
#define USB_REQ_RECIPIENT_INTERFACE 0x01U
#define USB_REQ_RECIPIENT_ENDPOINT 0x02U
#define USB_REQ_RECIPIENT_MASK 0x03U
#define USB_REQ_GET_STATUS 0x00U
#define USB_REQ_CLEAR_FEATURE 0x01U
#define USB_REQ_SET_FEATURE 0x03U
#define USB_REQ_SET_ADDRESS 0x05U
#define USB_REQ_GET_DESCRIPTOR 0x06U
#define USB_REQ_SET_DESCRIPTOR 0x07U
#define USB_REQ_GET_CONFIGURATION 0x08U
#define USB_REQ_SET_CONFIGURATION 0x09U
#define USB_REQ_GET_INTERFACE 0x0AU
#define USB_REQ_SET_INTERFACE 0x0BU
#define USB_REQ_SYNCH_FRAME 0x0CU
#define USB_DESC_TYPE_DEVICE 0x01U
#define USB_DESC_TYPE_CONFIGURATION 0x02U
#define USB_DESC_TYPE_STRING 0x03U
#define USB_DESC_TYPE_INTERFACE 0x04U
#define USB_DESC_TYPE_ENDPOINT 0x05U
#define USB_DESC_TYPE_DEVICE_QUALIFIER 0x06U
#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 0x07U
#define USB_DESC_TYPE_IAD 0x0BU
#define USB_DESC_TYPE_BOS 0x0FU
#define USB_CONFIG_REMOTE_WAKEUP 0x02U
#define USB_CONFIG_SELF_POWERED 0x01U
#define USB_FEATURE_EP_HALT 0x00U
#define USB_FEATURE_REMOTE_WAKEUP 0x01U
#define USB_FEATURE_TEST_MODE 0x02U
#define USB_DEVICE_CAPABITY_TYPE 0x10U
#define USB_CONF_DESC_SIZE 0x09U
#define USB_IF_DESC_SIZE 0x09U
#define USB_EP_DESC_SIZE 0x07U
#define USB_IAD_DESC_SIZE 0x08U
#define USB_HS_MAX_PACKET_SIZE 512U
#define USB_FS_MAX_PACKET_SIZE 64U
#define USB_MAX_EP0_SIZE 64U
/* Device Status */
#define USBD_STATE_DEFAULT 0x01U
#define USBD_STATE_ADDRESSED 0x02U
#define USBD_STATE_CONFIGURED 0x03U
#define USBD_STATE_SUSPENDED 0x04U
/* EP0 State */
#define USBD_EP0_IDLE 0x00U
#define USBD_EP0_SETUP 0x01U
#define USBD_EP0_DATA_IN 0x02U
#define USBD_EP0_DATA_OUT 0x03U
#define USBD_EP0_STATUS_IN 0x04U
#define USBD_EP0_STATUS_OUT 0x05U
#define USBD_EP0_STALL 0x06U
#define USBD_EP_TYPE_CTRL 0x00U
#define USBD_EP_TYPE_ISOC 0x01U
#define USBD_EP_TYPE_BULK 0x02U
#define USBD_EP_TYPE_INTR 0x03U
#ifndef LOBYTE
#define LOBYTE(x) ((uint8_t)((x) & 0x00FFU))
#endif /* LOBYTE */
#ifndef HIBYTE
#define HIBYTE(x) ((uint8_t)(((x) & 0xFF00U) >> 8U))
#endif /* HIBYTE */
#ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif /* MIN */
#ifndef MAX
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif /* MAX */
/*------------------------------------------------------------------------------------
Typedef
------------------------------------------------------------------------------------*/
//typedef enum
//{
// RESET = 0U,
// SET = !RESET
//} FlagStatus, ITStatus;
typedef enum
{
F_DISABLE = 0U,
F_ENABLE = !F_DISABLE
} FunctionalState;
typedef enum
{
SUCCESS = 0U,
ERROR = !SUCCESS
} ErrorStatus;
typedef enum
{
DESC_TYPE_DEVICE = 1,
DESC_TYPE_CONFIGURATION,
DESC_TYPE_LANGID_STR,
DESC_TYPE_MFC_STR,
DESC_TYPE_PRODUCT_STR,
DESC_TYPE_SERIAL_STR,
DESC_TYPE_CONFIG_STR,
DESC_TYPE_INTERFACE_STR,
DESC_TYPE_DEVICE_QUALIFIER,
DESC_TYPE_OTHER_SPEED_CONFIGURATION
} eDescriptor_Idx;
/** @defgroup USBD_DEF_Exported_TypesDefinitions
* @{
*/
typedef struct usb_setup_req
{
uint8_t bmRequest;
uint8_t bRequest;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
} USBD_SetupReqTypedef;
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t wTotalLength;
uint8_t bNumInterfaces;
uint8_t bConfigurationValue;
uint8_t iConfiguration;
uint8_t bmAttributes;
uint8_t bMaxPower;
} __PACKED USBD_ConfigDescTypeDef;
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t wTotalLength;
uint8_t bNumDeviceCaps;
} USBD_BosDescTypeDef;
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bEndpointAddress;
uint8_t bmAttributes;
uint16_t wMaxPacketSize;
uint8_t bInterval;
} __PACKED USBD_EpDescTypeDef;
typedef struct
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubType;
} USBD_DescHeaderTypeDef;
struct _USBD_HandleTypeDef;
typedef struct _Device_cb
{
uint8_t (*Init)(struct _USBD_HandleTypeDef *pdev, uint8_t cfgidx);
uint8_t (*DeInit)(struct _USBD_HandleTypeDef *pdev, uint8_t cfgidx);
/* Control Endpoints*/
uint8_t (*Setup)(struct _USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
uint8_t (*EP0_TxSent)(struct _USBD_HandleTypeDef *pdev);
uint8_t (*EP0_RxReady)(struct _USBD_HandleTypeDef *pdev);
/* Class Specific Endpoints*/
uint8_t (*DataIn)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum);
uint8_t (*DataOut)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum);
uint8_t (*SOF)(struct _USBD_HandleTypeDef *pdev);
uint8_t (*IsoINIncomplete)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum);
uint8_t (*IsoOUTIncomplete)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum);
uint8_t *(*GetHSConfigDescriptor)(uint16_t *length);
uint8_t *(*GetFSConfigDescriptor)(uint16_t *length);
uint8_t *(*GetOtherSpeedConfigDescriptor)(uint16_t *length);
uint8_t *(*GetDeviceQualifierDescriptor)(uint16_t *length);
#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
uint8_t *(*GetUsrStrDescriptor)(struct _USBD_HandleTypeDef *pdev, uint8_t index, uint16_t *length);
#endif /* USBD_SUPPORT_USER_STRING_DESC */
} USBD_ClassTypeDef;
/* Following USB Device Speed */
typedef enum
{
USBD_SPEED_HIGH = 0U,
USBD_SPEED_FULL = 1U,
USBD_SPEED_LOW = 2U,
} USBD_SpeedTypeDef;
/* Following USB Device status */
typedef enum
{
USBD_OK = 0U,
USBD_BUSY,
USBD_EMEM,
USBD_FAIL,
} USBD_StatusTypeDef;
/* USB Device descriptors structure */
typedef struct
{
uint8_t *(*GetDeviceDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *(*GetLangIDStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *(*GetManufacturerStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *(*GetProductStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *(*GetSerialStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *(*GetConfigurationStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *(*GetInterfaceStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
#if (USBD_CLASS_USER_STRING_DESC == 1)
uint8_t *(*GetUserStrDescriptor)(USBD_SpeedTypeDef speed, uint8_t idx, uint16_t *length);
#endif /* USBD_CLASS_USER_STRING_DESC */
#if ((USBD_LPM_ENABLED == 1U) || (USBD_CLASS_BOS_ENABLED == 1))
uint8_t *(*GetBOSDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
#endif /* (USBD_LPM_ENABLED == 1U) || (USBD_CLASS_BOS_ENABLED == 1) */
} USBD_DescriptorsTypeDef;
/* USB Device handle structure */
typedef struct
{
uint32_t status;
uint32_t total_length;
uint32_t rem_length;
uint32_t maxpacket;
uint16_t is_used;
uint16_t bInterval;
} USBD_EndpointTypeDef;
/* USB Device handle structure */
typedef struct _USBD_HandleTypeDef
{
uint8_t id;
uint32_t dev_config;
uint32_t dev_default_config;
uint32_t dev_config_status;
USBD_SpeedTypeDef dev_speed;
USBD_EndpointTypeDef ep_in[16];
USBD_EndpointTypeDef ep_out[16];
__IO uint32_t ep0_state;
uint32_t ep0_data_len;
__IO uint8_t dev_state;
__IO uint8_t dev_old_state;
uint8_t dev_address;
uint8_t dev_connection_status;
uint8_t dev_test_mode;
uint32_t dev_remote_wakeup;
uint8_t ConfIdx;
USBD_SetupReqTypedef request;
USBD_DescriptorsTypeDef *pDesc;
USBD_ClassTypeDef *pClass[USBD_MAX_SUPPORTED_CLASS];
void *pClassData;
void *pClassDataCmsit[USBD_MAX_SUPPORTED_CLASS];
void *pUserData[USBD_MAX_SUPPORTED_CLASS];
void *pData;
void *pBosDesc;
void *pConfDesc;
uint32_t classId;
uint32_t NumClasses;
} USBD_HandleTypeDef;
/* USB Device endpoint direction */
typedef enum
{
OUT = 0x00,
IN = 0x80,
} USBD_EPDirectionTypeDef;
typedef enum
{
NETWORK_CONNECTION = 0x00,
RESPONSE_AVAILABLE = 0x01,
CONNECTION_SPEED_CHANGE = 0x2A
} USBD_CDC_NotifCodeTypeDef;
/**
* @}
*/
/** @defgroup USBD_DEF_Exported_Macros
* @{
*/
__STATIC_INLINE uint16_t SWAPBYTE(uint8_t *addr)
{
uint16_t _SwapVal, _Byte1, _Byte2;
uint8_t *_pbuff = addr;
_Byte1 = *(uint8_t *)_pbuff;
_pbuff++;
_Byte2 = *(uint8_t *)_pbuff;
_SwapVal = (_Byte2 << 8) | _Byte1;
return _SwapVal;
}
/*------------------------------------------------------------------------------------
Global Variables
-------------------------------------------------------------------------------------*/
extern PCD_HandleTypeDef hpcd_USB_OTG_FS;
#endif /* __USBD_DEF_H */
@@ -0,0 +1,172 @@
/*!
* \file usbd_ioreq.c
*
* \brief This file provides the IO requests APIs for control endpoints.
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author MCD Application Team
*
* \author ( XinChip ) Alex-J
*/
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_ioreq.h"
/*------------------------------------------------------------------------------------
Functions
-------------------------------------------------------------------------------------*/
/**
* @brief USBD_CtlSendData
* send data on the ctl pipe
* @param pdev: device instance
* @param buff: pointer to data buffer
* @param len: length of data to be sent
* @retval status
*/
USBD_StatusTypeDef USBD_CtlSendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf,
uint32_t len)
{
/* Set EP0 State */
pdev->ep0_state = USBD_EP0_DATA_IN;
pdev->ep_in[0].total_length = len;
pdev->ep_in[0].rem_length = len;
/* Start the transfer */
(void)USBD_LL_Transmit(pdev, 0x00U, pbuf, len);
return USBD_OK;
}
/**
* @brief USBD_CtlContinueSendData
* continue sending data on the ctl pipe
* @param pdev: device instance
* @param buff: pointer to data buffer
* @param len: length of data to be sent
* @retval status
*/
USBD_StatusTypeDef USBD_CtlContinueSendData(USBD_HandleTypeDef *pdev,
uint8_t *pbuf, uint32_t len)
{
/* Start the next transfer */
(void)USBD_LL_Transmit(pdev, 0x00U, pbuf, len);
return USBD_OK;
}
/**
* @brief USBD_CtlPrepareRx
* receive data on the ctl pipe
* @param pdev: device instance
* @param buff: pointer to data buffer
* @param len: length of data to be received
* @retval status
*/
USBD_StatusTypeDef USBD_CtlPrepareRx(USBD_HandleTypeDef *pdev, uint8_t *pbuf,
uint32_t len)
{
/* Set EP0 State */
pdev->ep0_state = USBD_EP0_DATA_OUT;
pdev->ep_out[0].total_length = len;
pdev->ep_out[0].rem_length = len;
/* Start the transfer */
(void)USBD_LL_PrepareReceive(pdev, 0U, pbuf, len);
return USBD_OK;
}
/**
* @brief USBD_CtlContinueRx
* continue receive data on the ctl pipe
* @param pdev: device instance
* @param buff: pointer to data buffer
* @param len: length of data to be received
* @retval status
*/
USBD_StatusTypeDef USBD_CtlContinueRx(USBD_HandleTypeDef *pdev, uint8_t *pbuf,
uint32_t len)
{
(void)USBD_LL_PrepareReceive(pdev, 0U, pbuf, len);
return USBD_OK;
}
/**
* @brief USBD_CtlSendStatus
* send zero lzngth packet on the ctl pipe
* @param pdev: device instance
* @retval status
*/
USBD_StatusTypeDef USBD_CtlSendStatus(USBD_HandleTypeDef *pdev)
{
/* Set EP0 State */
pdev->ep0_state = USBD_EP0_STATUS_IN;
/* Start the transfer */
(void)USBD_LL_Transmit(pdev, 0x00U, NULL, 0U);
// alex revise
(void)USB_EP0_OutStart(pdev->pData, 0, NULL);
return USBD_OK;
}
/**
* @brief USBD_CtlReceiveStatus
* receive zero lzngth packet on the ctl pipe
* @param pdev: device instance
* @retval status
*/
USBD_StatusTypeDef USBD_CtlReceiveStatus(USBD_HandleTypeDef *pdev)
{
/* Set EP0 State */
pdev->ep0_state = USBD_EP0_STATUS_OUT;
/* Start the transfer */
(void)USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U);
(void)USB_EP0_OutStart(pdev->pData, 0, NULL);
return USBD_OK;
}
/**
* @brief USBD_GetRxCount
* returns the received data length
* @param pdev: device instance
* @param ep_addr: endpoint address
* @retval Rx Data blength
*/
uint32_t USBD_GetRxCount(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
{
return USBD_LL_GetRxDataSize(pdev, ep_addr);
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
@@ -0,0 +1,69 @@
/*!
* \file usbd_ioreq.h
*
* \brief Header file for the usbd_ioreq.c file.
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author MCD Application Team
*
* \author ( XinChip ) Alex-J
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_IOREQ_H
#define __USBD_IOREQ_H
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_def.h"
#include "usbd_core.h"
/*------------------------------------------------------------------------------------
Exported Functions
-------------------------------------------------------------------------------------*/
USBD_StatusTypeDef USBD_CtlSendData(USBD_HandleTypeDef *pdev,
uint8_t *pbuf, uint32_t len);
USBD_StatusTypeDef USBD_CtlContinueSendData(USBD_HandleTypeDef *pdev,
uint8_t *pbuf, uint32_t len);
USBD_StatusTypeDef USBD_CtlPrepareRx(USBD_HandleTypeDef *pdev,
uint8_t *pbuf, uint32_t len);
USBD_StatusTypeDef USBD_CtlContinueRx(USBD_HandleTypeDef *pdev,
uint8_t *pbuf, uint32_t len);
USBD_StatusTypeDef USBD_CtlSendStatus(USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef USBD_CtlReceiveStatus(USBD_HandleTypeDef *pdev);
uint32_t USBD_GetRxCount(USBD_HandleTypeDef *pdev, uint8_t ep_addr);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBD_IOREQ_H */
@@ -0,0 +1,593 @@
/*!
* \file usbd_conf.c
*
* \brief This file implements the board support package for the USB device
* library
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "usbd_core.h"
#include "usbd_def.h"
#include "xc_hal_usb.h"
#if USB_MSC
#include "usbd_msc.h"
#elif USB_HID
#include "usbd_hid.h"
#elif USB_CDC
#include "usbd_cdc.h"
#endif
/*------------------------------------------------------------------------------------
Global Variables
-------------------------------------------------------------------------------------*/
PCD_HandleTypeDef hpcd_USB_OTG_FS;
/*------------------------------------------------------------------------------------
Func Prototypes
------------------------------------------------------------------------------------*/
void Error_Handler(void);
USBD_StatusTypeDef USBD_Get_USB_Status(HAL_StatusTypeDef hal_status);
/*------------------------------------------------------------------------------------
Functions
-------------------------------------------------------------------------------------*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state
*/
__disable_irq();
while (1) {
}
/* USER CODE END Error_Handler_Debug */
}
/*******************************************************************************
LL Driver Callbacks (PCD -> USB Device Library)
*******************************************************************************/
/* MSP Init */
void HAL_PCD_MspInit(PCD_HandleTypeDef *pcdHandle)
{
USB_Phy_Init();
USB_Phy_Enable();
USB_Current_Ctrl(0);
// NVIC_SetPriority(USB_IRQn, 0); // MSC mode do not SET!!!!
USB_Phy_DP_Oprt(PULL_UP);
// HAL_Delay(100); // for(int i = 0; i < 0x455000*2; i++);
NVIC_EnableIRQ(USB_IRQn);
}
/* MSP DeInit */
void HAL_PCD_MspDeInit(PCD_HandleTypeDef *pcdHandle) { USB_Phy_Deinit(); }
/**
* @brief Setup stage callback
* @param hpcd: PCD handle
* @retval None
*/
void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
{
USBD_LL_SetupStage((USBD_HandleTypeDef *)hpcd->pData,
(uint8_t *)hpcd->Setup);
}
/**
* @brief Data Out stage callback.
* @param hpcd: PCD handle
* @param epnum: Endpoint number
* @retval None
*/
void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
{
USBD_LL_DataOutStage((USBD_HandleTypeDef *)hpcd->pData, epnum,
hpcd->OUT_ep[epnum].xfer_buff);
}
/**
* @brief Data In stage callback.
* @param hpcd: PCD handle
* @param epnum: Endpoint number
* @retval None
*/
void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
{
USBD_LL_DataInStage((USBD_HandleTypeDef *)hpcd->pData, epnum,
hpcd->IN_ep[epnum].xfer_buff);
}
/**
* @brief SOF callback.
* @param hpcd: PCD handle
* @retval None
*/
void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
{
USBD_LL_SOF((USBD_HandleTypeDef *)hpcd->pData);
}
/**
* @brief Reset callback.
* @param hpcd: PCD handle
* @retval None
*/
void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
{
USBD_SpeedTypeDef speed = USBD_SPEED_FULL;
// if ( hpcd->Init.speed == PCD_SPEED_HIGH)
// {
// speed = USBD_SPEED_HIGH;
// }
if (hpcd->Init.speed == PCD_SPEED_FULL) {
speed = USBD_SPEED_FULL;
} else {
Error_Handler();
}
/* Set Speed. */
USBD_LL_SetSpeed((USBD_HandleTypeDef *)hpcd->pData, speed);
/* Reset Device. */
USBD_LL_Reset((USBD_HandleTypeDef *)hpcd->pData);
}
/**
* @brief Suspend callback.
* When Low power mode is enabled the debug cannot be used (IAR, Keil doesn't
* support it)
* @param hpcd: PCD handle
* @retval None
*/
void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
{
/* Inform USB library that core enters in suspend Mode. */
USBD_LL_Suspend((USBD_HandleTypeDef *)hpcd->pData);
__HAL_PCD_GATE_PHYCLOCK(hpcd);
/* Enter in STOP mode. */
/* USER CODE BEGIN 2 */
if (hpcd->Init.low_power_enable) {
/* Set SLEEPDEEP bit and SleepOnExit of Cortex System Control Register.
*/
SCB->SCR |= (uint32_t)((uint32_t)(SCB_SCR_SLEEPDEEP_Msk |
SCB_SCR_SLEEPONEXIT_Msk));
}
/* USER CODE END 2 */
}
/**
* @brief Resume callback.
* When Low power mode is enabled the debug cannot be used (IAR, Keil doesn't
* support it)
* @param hpcd: PCD handle
* @retval None
*/
void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
{
/* USER CODE BEGIN 3 */
/* USER CODE END 3 */
USBD_LL_Resume((USBD_HandleTypeDef *)hpcd->pData);
}
/**
* @brief ISOOUTIncomplete callback.
* @param hpcd: PCD handle
* @param epnum: Endpoint number
* @retval None
*/
void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
{
USBD_LL_IsoOUTIncomplete((USBD_HandleTypeDef *)hpcd->pData, epnum);
}
/**
* @brief ISOINIncomplete callback.
* @param hpcd: PCD handle
* @param epnum: Endpoint number
* @retval None
*/
void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
{
USBD_LL_IsoINIncomplete((USBD_HandleTypeDef *)hpcd->pData, epnum);
}
/**
* @brief Connect callback.
* @param hpcd: PCD handle
* @retval None
*/
void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
{
USBD_LL_DevConnected((USBD_HandleTypeDef *)hpcd->pData);
}
/**
* @brief Disconnect callback.
* @param hpcd: PCD handle
* @retval None
*/
void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
{
USBD_LL_DevDisconnected((USBD_HandleTypeDef *)hpcd->pData);
}
/*******************************************************************************
LL Driver Interface (USB Device Library --> PCD)
*******************************************************************************/
/**
* @brief Initializes the low level portion of the device driver.
* @param pdev: Device handle
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)
{
/* Init USB Ip. */
if (pdev->id == DEVICE_FS) {
/* Link the driver to the stack. */
hpcd_USB_OTG_FS.pData = pdev;
pdev->pData = &hpcd_USB_OTG_FS;
hpcd_USB_OTG_FS.Instance = XC_USB_OTG_FS;
hpcd_USB_OTG_FS.Init.dev_endpoints = 2; // 4;
hpcd_USB_OTG_FS.Init.speed = PCD_SPEED_FULL;
hpcd_USB_OTG_FS.Init.dma_enable = F_DISABLE;
hpcd_USB_OTG_FS.Init.phy_itface = PCD_PHY_EMBEDDED;
hpcd_USB_OTG_FS.Init.Sof_enable = F_DISABLE;
hpcd_USB_OTG_FS.Init.low_power_enable = F_DISABLE;
hpcd_USB_OTG_FS.Init.lpm_enable = F_DISABLE;
hpcd_USB_OTG_FS.Init.vbus_sensing_enable = F_DISABLE;
hpcd_USB_OTG_FS.Init.use_dedicated_ep1 = F_DISABLE;
if (HAL_PCD_Init(&hpcd_USB_OTG_FS) != HAL_OK) {
Error_Handler();
}
HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x28);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 0x10);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x10);
}
return USBD_OK;
}
/**
* @brief De-Initializes the low level portion of the device driver.
* @param pdev: Device handle
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_DeInit(pdev->pData);
usb_status = USBD_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Starts the low level portion of the device driver.
* @param pdev: Device handle
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_Start(pdev->pData);
usb_status = USBD_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Stops the low level portion of the device driver.
* @param pdev: Device handle
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_Stop(pdev->pData);
usb_status = USBD_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Opens an endpoint of the low level driver.
* @param pdev: Device handle
* @param ep_addr: Endpoint number
* @param ep_type: Endpoint type
* @param ep_mps: Endpoint max packet size
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr,
uint8_t ep_type, uint16_t ep_mps)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_EP_Open(pdev->pData, ep_addr, ep_mps, ep_type);
usb_status = USBD_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Closes an endpoint of the low level driver.
* @param pdev: Device handle
* @param ep_addr: Endpoint number
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_EP_Close(pdev->pData, ep_addr);
usb_status = USBD_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Flushes an endpoint of the Low Level Driver.
* @param pdev: Device handle
* @param ep_addr: Endpoint number
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_EP_Flush(pdev->pData, ep_addr);
usb_status = USBD_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Sets a Stall condition on an endpoint of the Low Level Driver.
* @param pdev: Device handle
* @param ep_addr: Endpoint number
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_EP_SetStall(pdev->pData, ep_addr);
usb_status = USBD_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Clears a Stall condition on an endpoint of the Low Level Driver.
* @param pdev: Device handle
* @param ep_addr: Endpoint number
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev,
uint8_t ep_addr)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_EP_ClrStall(pdev->pData, ep_addr);
usb_status = USBD_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Returns Stall condition.
* @param pdev: Device handle
* @param ep_addr: Endpoint number
* @retval Stall (1: Yes, 0: No)
*/
uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
{
PCD_HandleTypeDef *hpcd = (PCD_HandleTypeDef *)pdev->pData;
if ((ep_addr & 0x80) == 0x80) {
return hpcd->IN_ep[ep_addr & 0x7F].is_stall;
} else {
return hpcd->OUT_ep[ep_addr & 0x7F].is_stall;
}
}
/**
* @brief Assigns a USB address to the device.
* @param pdev: Device handle
* @param dev_addr: Device address
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev,
uint8_t dev_addr)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_SetAddress(pdev->pData, dev_addr);
usb_status = USBD_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Transmits data over an endpoint.
* @param pdev: Device handle
* @param ep_addr: Endpoint number
* @param pbuf: Pointer to data to be sent
* @param size: Data size
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, uint8_t ep_addr,
uint8_t *pbuf, uint32_t size)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_EP_Transmit(pdev->pData, ep_addr, pbuf, size);
usb_status = USBD_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Prepares an endpoint for reception.
* @param pdev: Device handle
* @param ep_addr: Endpoint number
* @param pbuf: Pointer to data to be received
* @param size: Data size
* @retval USBD status
*/
USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev,
uint8_t ep_addr, uint8_t *pbuf,
uint32_t size)
{
HAL_StatusTypeDef hal_status = HAL_OK;
USBD_StatusTypeDef usb_status = USBD_OK;
hal_status = HAL_PCD_EP_Receive(pdev->pData, ep_addr, pbuf, size);
usb_status = USBD_Get_USB_Status(hal_status);
return usb_status;
}
/**
* @brief Returns the last transferred packet size.
* @param pdev: Device handle
* @param ep_addr: Endpoint number
* @retval Received Data Size
*/
uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
{
return HAL_PCD_EP_GetRxCount((PCD_HandleTypeDef *)pdev->pData, ep_addr);
}
#ifdef USBD_HS_TESTMODE_ENABLE
/**
* @brief Set High speed Test mode.
* @param pdev: Device handle
* @param testmode: test mode
* @retval USBD Status
*/
USBD_StatusTypeDef USBD_LL_SetTestMode(USBD_HandleTypeDef *pdev,
uint8_t testmode)
{
UNUSED(pdev);
UNUSED(testmode);
return USBD_OK;
}
#endif /* USBD_HS_TESTMODE_ENABLE */
/**
* @brief Static single allocation.
* @param size: Size of allocated memory
* @retval None
*/
void *USBD_static_malloc(uint32_t size)
{
#if USB_MSC
static uint32_t mem[(sizeof(USBD_MSC_BOT_HandleTypeDef) / 4) +
1]; /* On 32-bit boundary */
#elif USB_CDC
static uint32_t
mem[(sizeof(USBD_CDC_HandleTypeDef) / 4) + 1]; /* On 32-bit boundary */
#elif USB_HID
static uint32_t
mem[(sizeof(USBD_HID_HandleTypeDef) / 4) + 1]; /* On 32-bit boundary */
#else
static uint32_t mem[1];
#endif
return mem;
}
/**
* @brief Dummy memory free
* @param p: Pointer to allocated memory address
* @retval None
*/
void USBD_static_free(void *p) {}
/**
* @brief Delays routine for the USB Device Library.
* @param Delay: Delay in ms
* @retval None
*/
void USBD_LL_Delay(uint32_t Delay) { HAL_Delay(Delay); }
/**
* @brief Returns the USB status depending on the HAL status:
* @param hal_status: HAL status
* @retval USB status
*/
USBD_StatusTypeDef USBD_Get_USB_Status(HAL_StatusTypeDef hal_status)
{
USBD_StatusTypeDef usb_status = USBD_OK;
switch (hal_status) {
case HAL_OK:
usb_status = USBD_OK;
break;
case HAL_ERROR:
usb_status = USBD_FAIL;
break;
case HAL_BUSY:
usb_status = USBD_BUSY;
break;
case HAL_TIMEOUT:
usb_status = USBD_FAIL;
break;
default:
usb_status = USBD_FAIL;
break;
}
return usb_status;
}
@@ -0,0 +1,127 @@
/*!
* \file usbd_conf.h
*
* \brief Header for usbd_conf.c file.
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_CONF__H
#define __USBD_CONF__H
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "usbd_def.h"
/*------------------------------------------------------------------------------------
Macros
------------------------------------------- -----------------------------------------*/
/** @defgroup USBD_CONF_Exported_Defines USBD_CONF_Exported_Defines
* @brief Defines for configuration of the Usb device.
* @{
*/
/*---------- -----------*/
#if USB_SINGLE_DEVICE
#define USBD_MAX_NUM_INTERFACES 1U
#elif USB_COMPOSITE_DEVICE
#define USBD_MAX_NUM_INTERFACES 2U
#endif
/*---------- -----------*/
#define USBD_MAX_NUM_CONFIGURATION 1U
/*---------- -----------*/
#define USBD_MAX_STR_DESC_SIZ 512U
/*---------- -----------*/
#define USBD_DEBUG_LEVEL 0U
/*---------- -----------*/
#define USBD_LPM_ENABLED 0U
/*---------- -----------*/
#define USBD_SELF_POWERED 1U
/*---------- -----------*/
#define MSC_MEDIA_PACKET 512U
/****************************************/
/* #define for FS and HS identification */
#define DEVICE_FS 0
//#define DEVICE_HS 1
/* Memory management macros make sure to use static memory allocation */
/** Alias for memory allocation. */
#define USBD_malloc (void *)USBD_static_malloc
/** Alias for memory release. */
#define USBD_free USBD_static_free
/** Alias for memory set. */
#define USBD_memset memset
/** Alias for memory copy. */
#define USBD_memcpy memcpy
/** Alias for delay. */
#define USBD_Delay HAL_Delay
/* DEBUG macros */
#if (USBD_DEBUG_LEVEL > 0)
#define USBD_UsrLog(...) DEBUG(__VA_ARGS__);\
DEBUG("\n");
#else
#define USBD_UsrLog(...)
#endif /* (USBD_DEBUG_LEVEL > 0U) */
#if (USBD_DEBUG_LEVEL > 1)
#define USBD_ErrLog(...) DEBUG("ERROR: ") ;\
DEBUG(__VA_ARGS__);\
DEBUG("\n");
#else
#define USBD_ErrLog(...)
#endif /* (USBD_DEBUG_LEVEL > 1U) */
#if (USBD_DEBUG_LEVEL > 2)
#define USBD_DbgLog(...) DEBUG("DEBUG : ") ;\
DEBUG(__VA_ARGS__);\
DEBUG("\n");
#else
#define USBD_DbgLog(...)
#endif /* (USBD_DEBUG_LEVEL > 2U) */
/*------------------------------------------------------------------------------------
Exported Functions
-------------------------------------------------------------------------------------*/
void *USBD_static_malloc(uint32_t size);
void USBD_static_free(void *p);
#ifdef __cplusplus
}
#endif
#endif /* __USBD_CONF__H__ */
@@ -0,0 +1,57 @@
/*!
* \file rtc.h
*
* \brief Target rtc implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __RTC_H__
#define __RTC_H__
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include <stdint.h>
#include "xc6xxx.h"
/*------------------------------------------------------------------------------------
Global Variables
-------------------------------------------------------------------------------------*/
extern volatile uint32_t Utc_TotalSec;
// Test val
extern uint8_t Sec_Flag;
/*------------------------------------------------------------------------------------
Exported Functions
------------------------------------------- -----------------------------------------*/
void rtc_sec_handler(void);
void RTC_Config( void );
#ifdef __cplusplus
}
#endif
#endif /* __RTC_H__ */
@@ -0,0 +1,86 @@
/*!
* \file time_conv.h
*
* \brief Target time convert implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __TIME_CONV_H__
#define __TIME_CONV_H__
#ifdef __cplusplus
extern "C" {
#endif
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include <stdint.h>
#include <time.h>
#include "rtc.h"
/*------------------------------------------------------------------------------------
Macros
------------------------------------------- -----------------------------------------*/
#define YEAR_BASE 2000U
#define TIME_ZONE (8)
#define M_JAN 1U
#define M_FEB 2U
#define M_MAR 3U
#define M_APR 4U
#define M_MAY 5U
#define M_JUN 6U
#define M_JUL 7U
#define M_AUG 8U
#define M_SEP 9U
#define M_OCT 10U
#define M_NOV 11U
#define M_DEC 12U
/*------------------------------------------------------------------------------------
Typedef
-------------------------------------------------------------------------------------*/
typedef struct tm Utc_Date_t;
typedef struct
{
uint8_t year;
uint8_t month;
uint8_t day;
uint8_t hour;
uint8_t min;
uint8_t sec;
uint8_t week;
} DateTime_t;
/*------------------------------------------------------------------------------------
Exported Functions
------------------------------------------- -----------------------------------------*/
DateTime_t UTC_SecToDate( uint32_t utc_sec );
DateTime_t UTC_DateToZoneDate(int8_t zone_num, uint16_t year_base, uint8_t u_year, uint8_t u_month,
uint8_t u_day, uint8_t u_hour, uint8_t u_min, uint8_t u_sec, uint8_t u_week);
#ifdef __cplusplus
}
#endif
#endif /* __TIME_CONV_H__ */
@@ -0,0 +1,103 @@
/*!
* \file rtc.c
*
* \brief Target rtc implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "rtc.h"
/*------------------------------------------------------------------------------------
Macros
-------------------------------------------
-----------------------------------------*/
#define MANUF_UTC_SEC 1680516516 // rtc start time
/*------------------------------------------------------------------------------------
Constant
-------------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------------
Local Variables
-------------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------------
Global Variables
-------------------------------------------------------------------------------------*/
volatile uint32_t Utc_TotalSec = MANUF_UTC_SEC;
// Test val
uint8_t Sec_Flag = false;
/*------------------------------------------------------------------------------------
Functions
------------------------------------------------------------------------------------*/
/**
* @brief RTC handler func
* @param xinc_drv_rtc_int_type_t - type
* @retval void
*/
uint8_t Sec_Callback(void)
{
Utc_TotalSec += 1;
Sec_Flag = true;
return 0;
}
/**
* @brief RTC config func
* @param void
* @retval void
*/
void RTC_Config(void)
{
// Initialize RTC instance
RTC_InitTypeDef rtc_cfg = {0};
NVIC_DisableIRQ(RTC_IRQn);
// rtc_cfg.Date.Sec = 0;
// rtc_cfg.Date.Min = 0;
// rtc_cfg.Date.Hour = 18;
// rtc_cfg.Date.Day = 93;
// rtc_cfg.Date.Week = 1;
rtc_cfg.Date.Sec = 0;
rtc_cfg.Date.Min = 45;
rtc_cfg.Date.Hour = 19;
rtc_cfg.Date.Day = 340;
rtc_cfg.Date.Week = 2;
rtc_cfg.DateLimit.SecLimit = 60;
rtc_cfg.DateLimit.MinLimit = 60;
rtc_cfg.DateLimit.HourLimit = 24;
rtc_cfg.MatchTimeEnable = false;
rtc_cfg.SecIT_Enable = true;
rtc_cfg.MinIT_Enable = false;
rtc_cfg.HourIT_Enable = false;
rtc_cfg.DayIT_Enable = false;
// Rtc enable
RTC_Init(XC_RTC, &rtc_cfg);
RTC_Start(XC_RTC);
NVIC_EnableIRQ(RTC_IRQn);
}
@@ -0,0 +1,168 @@
/*!
* \file time_conv.c
*
* \brief Target time convert implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "time_conv.h"
/*------------------------------------------------------------------------------------
Functions
------------------------------------------------------------------------------------*/
/**
* @brief UTC second convert to date and time.
* @details
* @param[in] uint32_t - utc_sec
* @param[out] void
* @retval DateTime_t
* @retval void
* @par identifier
* reserve
* @par other
* void
* @par change log
* Alex created on 2022-09-09
*/
DateTime_t UTC_SecToDate(uint32_t utc_sec)
{
Utc_Date_t tmp;
DateTime_t ret;
tmp = *localtime(&utc_sec);
ret.year = tmp.tm_year;
ret.month = tmp.tm_mon;
ret.day = tmp.tm_mday;
ret.hour = tmp.tm_hour;
ret.min = tmp.tm_min;
ret.sec = tmp.tm_sec;
ret.week = tmp.tm_wday;
return ret;
}
/**
* @brief Convert the date in the UTC time zone to the date in the
* corresponding time zone.
* @details
* @param[in] int8_t - zone_num
* uint16_t - year_base
* uint8_t - u_year, u_month, u_day, u_hour, u_min, u_sec, u_week
* @param[out] void
* @retval DateTime_t
* @retval void
* @par identifier
* reserve
* @par other
* void
* @par change log
* Alex created on 2022-09-09
*/
DateTime_t UTC_DateToZoneDate(int8_t zone_num, uint16_t year_base,
uint8_t u_year, uint8_t u_month, uint8_t u_day,
uint8_t u_hour, uint8_t u_min, uint8_t u_sec,
uint8_t u_week)
{
DateTime_t zonedate;
int t_year = 0;
int lastday = 0; // last day of the month
int lastmon_lastday = 0; // last day of last month
int8_t t_hour = 0;
t_year = u_year - 100 + year_base;
zonedate.month = u_month + 1;
zonedate.day = u_day;
zonedate.hour = u_hour;
zonedate.min = u_min;
zonedate.sec = u_sec;
zonedate.week = u_week;
// Determine days by month
if (M_JAN == zonedate.month || M_MAR == zonedate.month ||
M_MAY == zonedate.month || M_JUL == zonedate.month ||
M_AUG == zonedate.month || M_OCT == zonedate.month ||
M_DEC == zonedate.month) {
lastday = 31;
if (M_MAR == zonedate.month) {
// leap year determination
if ((t_year % 400 == 0) || (t_year % 4 == 0 && t_year % 100 != 0))
lastmon_lastday = 29;
else
lastmon_lastday = 28;
}
if (M_AUG == zonedate.month)
lastmon_lastday = 31;
} else if (M_APR == zonedate.month || M_JUN == zonedate.month ||
M_SEP == zonedate.month || M_NOV == zonedate.month) {
lastday = 30;
lastmon_lastday = 31;
} else {
lastmon_lastday = 31;
// leap year determination
if ((t_year % 400 == 0) || (t_year % 4 == 0 && t_year % 100 != 0))
lastday = 29;
else
lastday = 28;
}
t_hour = (int8_t)zonedate.hour + zone_num;
if (t_hour >= 24) {
zonedate.hour = (uint8_t)t_hour - 24;
zonedate.day += 1;
if (zonedate.day > lastday) {
zonedate.day -= lastday;
zonedate.month += 1;
if (zonedate.month > M_DEC) {
zonedate.month -= M_DEC;
t_year += 1;
}
}
if (zonedate.week < 6)
zonedate.week += 1;
else
zonedate.week = 0;
} else if (t_hour < 0) {
zonedate.hour = (uint8_t)(t_hour + 24);
zonedate.day -= 1;
if (zonedate.day == 0) {
zonedate.day = lastmon_lastday;
zonedate.month -= 1;
if (zonedate.month == 0) {
zonedate.month = M_DEC;
t_year -= 1;
}
}
if ((zonedate.week > 0) && (zonedate.week <= 6))
zonedate.week -= 1;
else
zonedate.week = 6;
} else
zonedate.hour = t_hour;
zonedate.year = t_year - year_base;
return zonedate;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,625 @@
/*!
* \file xc_hal_ll_usb_np.h
*
* \brief USB Low Layer HAL module driver.(use non-periodic fifo)
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author MCD Application Team
*
* \author ( XinChip ) Alex-J
*/
#ifndef __XC_HAL_LL_USB_NP_H
#define __XC_HAL_LL_USB_NP_H
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "xc_usb_bitfields.h"
#include "xc6xxx.h"
/*------------------------------------------------------------------------------------
Typedef
------------------------------------------------------------------------------------*/
#if defined (USB_OTG_FS)
/**
* @brief USB Mode definition
*/
typedef enum
{
USB_DEVICE_MODE = 0,
USB_HOST_MODE = 1,
USB_DRD_MODE = 2
} USB_OTG_ModeTypeDef;
/**
* @brief URB States definition
*/
typedef enum
{
URB_IDLE = 0,
URB_DONE,
URB_NOTREADY,
URB_NYET,
URB_ERROR,
URB_STALL
} USB_OTG_URBStateTypeDef;
/**
* @brief Host channel States definition
*/
//typedef enum
//{
// HC_IDLE = 0,
// HC_XFRC,
// HC_HALTED,
// HC_NAK,
// HC_NYET,
// HC_STALL,
// HC_XACTERR,
// HC_BBLERR,
// HC_DATATGLERR
//} USB_OTG_HCStateTypeDef;
/**
* @brief USB Instance Initialization Structure definition
*/
typedef struct
{
uint32_t dev_endpoints; /*!< Device Endpoints number.
This parameter depends on the used USB core.
This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
uint32_t Host_channels; /*!< Host Channels number.
This parameter Depends on the used USB core.
This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
uint32_t speed; /*!< USB Core speed.
This parameter can be any value of @ref PCD_Speed/HCD_Speed
(HCD_SPEED_xxx, HCD_SPEED_xxx) */
uint32_t dma_enable; /*!< Enable or disable of the USB embedded DMA used only for OTG HS. */
uint32_t ep0_mps; /*!< Set the Endpoint 0 Max Packet size. */
uint32_t phy_itface; /*!< Select the used PHY interface.
This parameter can be any value of @ref PCD_PHY_Module/HCD_PHY_Module */
uint32_t Sof_enable; /*!< Enable or disable the output of the SOF signal. */
uint32_t low_power_enable; /*!< Enable or disable the low power mode. */
uint32_t lpm_enable; /*!< Enable or disable Link Power Management. */
uint32_t battery_charging_enable; /*!< Enable or disable Battery charging. */
uint32_t vbus_sensing_enable; /*!< Enable or disable the VBUS Sensing feature. */
uint32_t use_dedicated_ep1; /*!< Enable or disable the use of the dedicated EP1 interrupt. */
uint32_t use_external_vbus; /*!< Enable or disable the use of the external VBUS. */
} USB_OTG_CfgTypeDef;
typedef struct
{
uint8_t num; /*!< Endpoint number
This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
uint8_t is_in; /*!< Endpoint direction
This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
uint8_t is_stall; /*!< Endpoint stall condition
This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
uint8_t is_iso_incomplete; /*!< Endpoint isoc condition
This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
uint8_t type; /*!< Endpoint type
This parameter can be any value of @ref USB_LL_EP_Type */
uint8_t data_pid_start; /*!< Initial data PID
This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
uint8_t even_odd_frame; /*!< IFrame parity
This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
uint16_t tx_fifo_num; /*!< Transmission FIFO number
This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
uint32_t maxpacket; /*!< Endpoint Max packet size
This parameter must be a number between Min_Data = 0 and Max_Data = 64KB */
uint8_t *xfer_buff; /*!< Pointer to transfer buffer */
uint32_t dma_addr; /*!< 32 bits aligned transfer buffer address */
uint32_t xfer_len; /*!< Current transfer length */
uint32_t xfer_count; /*!< Partial transfer length in case of multi packet transfer */
} USB_OTG_EPTypeDef;
typedef struct
{
uint8_t dev_addr; /*!< USB device address.
This parameter must be a number between Min_Data = 1 and Max_Data = 255 */
uint8_t ch_num; /*!< Host channel number.
This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
uint8_t ep_num; /*!< Endpoint number.
This parameter must be a number between Min_Data = 1 and Max_Data = 15 */
uint8_t ep_is_in; /*!< Endpoint direction
This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
uint8_t speed; /*!< USB Host Channel speed.
This parameter can be any value of @ref HCD_Device_Speed:
(HCD_DEVICE_SPEED_xxx) */
uint8_t do_ping; /*!< Enable or disable the use of the PING protocol for HS mode. */
uint8_t process_ping; /*!< Execute the PING protocol for HS mode. */
uint8_t ep_type; /*!< Endpoint Type.
This parameter can be any value of @ref USB_LL_EP_Type */
uint16_t max_packet; /*!< Endpoint Max packet size.
This parameter must be a number between Min_Data = 0 and Max_Data = 64KB */
uint8_t data_pid; /*!< Initial data PID.
This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
uint8_t *xfer_buff; /*!< Pointer to transfer buffer. */
uint32_t XferSize; /*!< OTG Channel transfer size. */
uint32_t xfer_len; /*!< Current transfer length. */
uint32_t xfer_count; /*!< Partial transfer length in case of multi packet transfer. */
uint8_t toggle_in; /*!< IN transfer current toggle flag.
This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
uint8_t toggle_out; /*!< OUT transfer current toggle flag
This parameter must be a number between Min_Data = 0 and Max_Data = 1 */
uint32_t dma_addr; /*!< 32 bits aligned transfer buffer address. */
uint32_t ErrCnt; /*!< Host channel error count. */
USB_OTG_URBStateTypeDef urb_state; /*!< URB state.
This parameter can be any value of @ref USB_OTG_URBStateTypeDef */
// USB_OTG_HCStateTypeDef state; /*!< Host Channel state.
// This parameter can be any value of @ref USB_OTG_HCStateTypeDef */
} USB_OTG_HCTypeDef;
/**
* This union represents the bit fields in the User HW Config2
* Register. Read the register into the <i>d32</i> element then read
* out the bits using the <i>b</i>it elements.
*/
typedef union _USB_OTG_HWCFG2_TypeDef {
/** raw register data */
uint32_t d32;
/** register bits */
struct {
/* GHWCFG2 */
unsigned op_mode:3;
unsigned architecture:2;
unsigned point2point:1;
unsigned hs_phy_type:2;
unsigned fs_phy_type:2;
unsigned num_dev_ep:4;
unsigned num_host_chan:4;
unsigned perio_ep_supported:1;
unsigned dynamic_fifo:1;
unsigned multi_proc_int:1;
unsigned reserved21:1;
unsigned nonperio_tx_q_depth:2;
unsigned host_perio_tx_q_depth:2;
unsigned dev_token_q_depth:5;
unsigned otg_enable_ic_usb:1;
} b;
}USB_OTG_HWCFG2_TypeDef;
typedef union _USB_OTG_DTKNQ1_TypeDef {
/** raw register data */
uint32_t d32;
/** register bits */
struct {
/** In Token Queue Write Pointer */
unsigned intknwptr:5;
/** Reserved */
unsigned reserved05_06:2;
/** write pointer has wrapped. */
unsigned wrap_bit:1;
/** EP Numbers of IN Tokens 0 ... 4 */
unsigned epnums0_5:24;
} b;
} USB_OTG_DTKNQ1_TypeDef;
/* =========================================================================================================================== */
/* ================ USB ================ */
/* =========================================================================================================================== */
/**
* @brief USB_OTG_Core_Registers
*/
typedef struct
{
__IO uint32_t GOTGCTL; /*!< USB_OTG Control and Status Register 000h */
__IO uint32_t GOTGINT; /*!< USB_OTG Interrupt Register 004h */
__IO uint32_t GAHBCFG; /*!< Core AHB Configuration Register 008h */
__IO uint32_t GUSBCFG; /*!< Core USB Configuration Register 00Ch */
__IO uint32_t GRSTCTL; /*!< Core Reset Register 010h */
__IO uint32_t GINTSTS; /*!< Core Interrupt Register 014h */
__IO uint32_t GINTMSK; /*!< Core Interrupt Mask Register 018h */
__IO uint32_t GRXSTSR; /*!< Receive Sts Q Read Register 01Ch */
__IO uint32_t GRXSTSP; /*!< Receive Sts Q Read & POP Register 020h */
__IO uint32_t GRXFSIZ; /*!< Receive FIFO Size Register 024h */
__IO uint32_t GNPTXFSIZ; /*!< Non Periodic Tx FIFO Size Register 028h */
__IO uint32_t GNPTXSTS; /*!< Non Periodic Tx FIFO/Queue Sts reg 02Ch */
uint32_t Reserved30[4]; /*!< Reserved 0x30-0x3C */
__I uint32_t GSNPSID; /*!< Synopsys ID Register 40Ch */
__I uint32_t GHWCFG1; /*!< User Hardware Configuration 1 Register 44Ch */
__IO uint32_t GHWCFG2; /*!< User Hardware Configuration 2 Register 48Ch */
__I uint32_t GHWCFG3;
__I uint32_t GHWCFG4;
uint32_t Reserved50[44]; /*!< Reserved 0x50-0x100h */
__IO uint32_t DPTXFSIZ[4]; /*!< Device Periodic Transmit FIFO1 0x104-0x100h */
} USB_OTG_GlobalTypeDef;
/**
* @brief USB_OTG_device_Registers
*/
typedef struct
{
__IO uint32_t DCFG; /*!< dev Configuration Register 800h */
__IO uint32_t DCTL; /*!< dev Control Register 804h */
__IO uint32_t DSTS; /*!< dev Status Register (RO) 808h */
uint32_t Reserved0C; /*!< Reserved 80Ch */
__IO uint32_t DIEPMSK; /*!< dev IN Endpoint Mask 810h */
__IO uint32_t DOEPMSK; /*!< dev OUT Endpoint Mask 814h */
__IO uint32_t DAINT; /*!< dev All Endpoints Itr Reg 818h */
__IO uint32_t DAINTMSK; /*!< dev All Endpoints Itr Mask 81Ch */
__IO uint32_t DTKNQR1; /*!< dev IN Token Seq Reg 1 820h */
__IO uint32_t DTKNQR2; /*!< dev IN Token Seq Reg 2 824h */
__IO uint32_t DVBUSDIS; /*!< dev VBUS discharge Register 828h */
__IO uint32_t DVBUSPULSE; /*!< dev VBUS Pulse Register 82Ch */
__IO uint32_t DTKNQR3; /*!< dev IN Token Seq Reg 3 830h */
__IO uint32_t DTKNQR4; /*!< dev IN Token Seq Reg 4 834h */
} USB_OTG_DeviceTypeDef;
/**
* @brief USB_OTG_IN_Endpoint-Specific_Register
*/
typedef struct
{
__IO uint32_t DIEPCTL; /*!< dev IN Endpoint Control Reg 900h + (ep_num * 20h) + 00h */
uint32_t Reserved04; /*!< Reserved 900h + (ep_num * 20h) + 04h */
__IO uint32_t DIEPINT; /*!< dev IN Endpoint Itr Reg 900h + (ep_num * 20h) + 08h */
uint32_t Reserved0C; /*!< Reserved 900h + (ep_num * 20h) + 0Ch */
__IO uint32_t DIEPTSIZ; /*!< IN Endpoint Txfer Size 900h + (ep_num * 20h) + 10h */
uint32_t Reserved14; /*!< Reserved 900h + (ep_num * 20h) + 14h */
__IO uint32_t DTXFSTS; /*!< IN Endpoint Tx FIFO Status Reg 900h + (ep_num * 20h) + 18h */
uint32_t Reserved18; /*!< Reserved 900h+(ep_num*20h)+1Ch-900h+ (ep_num * 20h) + 1Ch */
} USB_OTG_INEndpointTypeDef;
/**
* @brief USB_OTG_OUT_Endpoint-Specific_Registers
*/
/**
* @brief USB_OTG_OUT_Endpoint-Specific_Registers
*/
typedef struct
{
__IO uint32_t DOEPCTL; /*!< dev OUT Endpoint Control Reg B00h + (ep_num * 20h) + 00h */
uint32_t Reserved04; /*!< Reserved B00h + (ep_num * 20h) + 04h */
__IO uint32_t DOEPINT; /*!< dev OUT Endpoint Itr Reg B00h + (ep_num * 20h) + 08h */
uint32_t Reserved0C; /*!< Reserved B00h + (ep_num * 20h) + 0Ch */
__IO uint32_t DOEPTSIZ; /*!< dev OUT Endpoint Txfer Size B00h + (ep_num * 20h) + 10h */
uint32_t Reserved14[5]; /*!< Reserved B00h + (ep_num * 20h) + 14h - B00h + (ep_num * 20h) + 1Ch */
} USB_OTG_OUTEndpointTypeDef;
/*------------------------------------------------------------------------------------
Macros
-------------------------------------------------------------------------------------*/
#define XC_USB_FS_PERIPH_BASE 0x50010000UL
#define XC_USB_OTG_FS ((USB_OTG_GlobalTypeDef *) XC_USB_FS_PERIPH_BASE)
/** @defgroup USB_OTG_CORE VERSION ID
* @{
*/
#define USB_OTG_CORE_ID_300A 0x4F54300AU
#define USB_OTG_CORE_ID_310A 0x4F54310AU
/**
* @}
*/
/** @defgroup USB_Core_Mode_ USB Core Mode
* @{
*/
#define USB_OTG_MODE_DEVICE 0U
#define USB_OTG_MODE_HOST 1U
#define USB_OTG_MODE_DRD 2U
/**
* @}
*/
/** @defgroup USB_LL Device Speed
* @{
*/
#define USBD_HS_SPEED 0U
#define USBD_HSINFS_SPEED 1U
#define USBH_HS_SPEED 0U
#define USBD_FS_SPEED 2U
#define USBH_FSLS_SPEED 1U
/**
* @}
*/
/** @defgroup USB_LL_Core_Speed USB Low Layer Core Speed
* @{
*/
#define USB_OTG_SPEED_HIGH 0U
#define USB_OTG_SPEED_HIGH_IN_FULL 1U
#define USB_OTG_SPEED_FULL 3U
/**
* @}
*/
/** @defgroup USB_LL_Core_PHY USB Low Layer Core PHY
* @{
*/
#define USB_OTG_ULPI_PHY 1U
#define USB_OTG_EMBEDDED_PHY 2U
/**
* @}
*/
/** @defgroup USB_LL_Turnaround_Timeout Turnaround Timeout Value
* @{
*/
#ifndef USBD_HS_TRDT_VALUE
#define USBD_HS_TRDT_VALUE 9U
#endif /* USBD_HS_TRDT_VALUE */
#ifndef USBD_FS_TRDT_VALUE
#define USBD_FS_TRDT_VALUE 5U
#define USBD_DEFAULT_TRDT_VALUE 9U
#endif /* USBD_HS_TRDT_VALUE */
/**
* @}
*/
/** @defgroup USB_LL_Core_MPS USB Low Layer Core MPS
* @{
*/
#define USB_OTG_HS_MAX_PACKET_SIZE 512U
#define USB_OTG_FS_MAX_PACKET_SIZE 64U
#define USB_OTG_MAX_EP0_SIZE 64U
/**
* @}
*/
/** @defgroup USB_LL_Core_PHY_Frequency USB Low Layer Core PHY Frequency
* @{
*/
#define DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ (0U << 1)
#define DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ (1U << 1)
#define DSTS_ENUMSPD_FS_PHY_48MHZ (3U << 1)
/**
* @}
*/
/** @defgroup USB_LL_CORE_Frame_Interval USB Low Layer Core Frame Interval
* @{
*/
#define DCFG_FRAME_INTERVAL_80 0U
#define DCFG_FRAME_INTERVAL_85 1U
#define DCFG_FRAME_INTERVAL_90 2U
#define DCFG_FRAME_INTERVAL_95 3U
/**
* @}
*/
/** @defgroup USB_LL_EP0_MPS USB Low Layer EP0 MPS
* @{
*/
#define EP_MPS_64 0U
#define EP_MPS_32 1U
#define EP_MPS_16 2U
#define EP_MPS_8 3U
/**
* @}
*/
/** @defgroup USB_LL_EP_Speed USB Low Layer EP Speed
* @{
*/
#define EP_SPEED_LOW 0U
#define EP_SPEED_FULL 1U
#define EP_SPEED_HIGH 2U
/**
* @}
*/
/** @defgroup USB_LL_EP_Type USB Low Layer EP Type
* @{
*/
#define EP_TYPE_CTRL 0U
#define EP_TYPE_ISOC 1U
#define EP_TYPE_BULK 2U
#define EP_TYPE_INTR 3U
#define EP_TYPE_MSK 3U
/**
* @}
*/
/** @defgroup USB_LL_STS_Defines USB Low Layer STS Defines
* @{
*/
#define STS_GOUT_NAK 1U
#define STS_DATA_UPDT 2U
#define STS_XFER_COMP 3U
#define STS_SETUP_COMP 4U
#define STS_SETUP_UPDT 6U
/**
* @}
*/
/** @defgroup USB_LL_HCFG_SPEED_Defines USB Low Layer HCFG Speed Defines
* @{
*/
#define HCFG_30_60_MHZ 0U
#define HCFG_48_MHZ 1U
#define HCFG_6_MHZ 2U
/**
* @}
*/
/** @defgroup USB_LL_HPRT0_PRTSPD_SPEED_Defines USB Low Layer HPRT0 PRTSPD Speed Defines
* @{
*/
#define HPRT0_PRTSPD_HIGH_SPEED 0U
#define HPRT0_PRTSPD_FULL_SPEED 1U
#define HPRT0_PRTSPD_LOW_SPEED 2U
/**
* @}
*/
#define HCCHAR_CTRL 0U
#define HCCHAR_ISOC 1U
#define HCCHAR_BULK 2U
#define HCCHAR_INTR 3U
#define HC_PID_DATA0 0U
#define HC_PID_DATA2 1U
#define HC_PID_DATA1 2U
#define HC_PID_SETUP 3U
#define GRXSTS_PKTSTS_IN 2U
#define GRXSTS_PKTSTS_IN_XFER_COMP 3U
#define GRXSTS_PKTSTS_DATA_TOGGLE_ERR 5U
#define GRXSTS_PKTSTS_CH_HALTED 7U
#define USBx_PCGCCTL *(__IO uint32_t *)((uint32_t)USBx_BASE + USB_OTG_PCGCCTL_BASE)
#define USBx_HPRT0 *(__IO uint32_t *)((uint32_t)USBx_BASE + USB_OTG_HOST_PORT_BASE)
#define USBx_DEVICE ((USB_OTG_DeviceTypeDef *)(USBx_BASE + USB_OTG_DEVICE_BASE))
#define USBx_INEP(i) ((USB_OTG_INEndpointTypeDef *)(USBx_BASE\
+ USB_OTG_IN_ENDPOINT_BASE + ((i) * USB_OTG_EP_REG_SIZE)))
#define USBx_OUTEP(i) ((USB_OTG_OUTEndpointTypeDef *)(USBx_BASE\
+ USB_OTG_OUT_ENDPOINT_BASE + ((i) * USB_OTG_EP_REG_SIZE)))
#define USBx_DFIFO(i) *(__IO uint32_t *)(USBx_BASE + USB_OTG_FIFO_BASE + ((i) * USB_OTG_FIFO_SIZE))
#define USBx_HOST ((USB_OTG_HostTypeDef *)(USBx_BASE + USB_OTG_HOST_BASE))
#define USBx_HC(i) ((USB_OTG_HostChannelTypeDef *)(USBx_BASE\
+ USB_OTG_HOST_CHANNEL_BASE\
+ ((i) * USB_OTG_HOST_CHANNEL_SIZE)))
#define EP_ADDR_MSK 0xFU
/**
* @}
*/
/** @defgroup USB_LL_Exported_Macros USB Low Layer Exported Macros
* @{
*/
#define USB_MASK_INTERRUPT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->GINTMSK &= ~(__INTERRUPT__))
#define USB_UNMASK_INTERRUPT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->GINTMSK |= (__INTERRUPT__))
#define CLEAR_IN_EP_INTR(__EPNUM__, __INTERRUPT__) (USBx_INEP(__EPNUM__)->DIEPINT = (__INTERRUPT__))
#define CLEAR_OUT_EP_INTR(__EPNUM__, __INTERRUPT__) (USBx_OUTEP(__EPNUM__)->DOEPINT = (__INTERRUPT__))
/**
* @}
*/
/*------------------------------------------------------------------------------------
Exported Functions
------------------------------------------------------------------------------------*/
/** @addtogroup USB_LL_Exported_Functions USB Low Layer Exported Functions
* @{
*/
HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg);
HAL_StatusTypeDef USB_DevInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg);
HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx);
HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx);
HAL_StatusTypeDef USB_SetTurnaroundTime(USB_OTG_GlobalTypeDef *USBx, uint32_t hclk, uint8_t speed);
HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx, USB_OTG_ModeTypeDef mode);
HAL_StatusTypeDef USB_SetDevSpeed(USB_OTG_GlobalTypeDef *USBx, uint8_t speed);
HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx);
HAL_StatusTypeDef USB_FlushTxFifo(USB_OTG_GlobalTypeDef *USBx, uint32_t num);
HAL_StatusTypeDef USB_ActivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep);
HAL_StatusTypeDef USB_DeactivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep);
HAL_StatusTypeDef USB_ActivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep);
HAL_StatusTypeDef USB_DeactivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep);
HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep, uint8_t dma);
HAL_StatusTypeDef USB_EP0StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep, uint8_t dma);
HAL_StatusTypeDef USB_WritePacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *src,
uint8_t ch_ep_num, uint16_t len, uint8_t dma);
void *USB_ReadPacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len);
HAL_StatusTypeDef USB_EPSetStall(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep);
HAL_StatusTypeDef USB_EPClearStall(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep);
HAL_StatusTypeDef USB_EPStopXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep);
HAL_StatusTypeDef USB_SetDevAddress(USB_OTG_GlobalTypeDef *USBx, uint8_t address);
HAL_StatusTypeDef USB_DevConnect(USB_OTG_GlobalTypeDef *USBx);
HAL_StatusTypeDef USB_DevDisconnect(USB_OTG_GlobalTypeDef *USBx);
HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx);
HAL_StatusTypeDef USB_ActivateSetup(USB_OTG_GlobalTypeDef *USBx);
HAL_StatusTypeDef USB_EP0_OutStart(USB_OTG_GlobalTypeDef *USBx, uint8_t dma, uint8_t *psetup);
uint8_t USB_GetDevSpeed(USB_OTG_GlobalTypeDef *USBx);
uint32_t USB_GetMode(USB_OTG_GlobalTypeDef *USBx);
uint32_t USB_ReadInterrupts(USB_OTG_GlobalTypeDef *USBx);
uint32_t USB_ReadDevAllOutEpInterrupt(USB_OTG_GlobalTypeDef *USBx);
uint32_t USB_ReadDevOutEPInterrupt(USB_OTG_GlobalTypeDef *USBx, uint8_t epnum);
uint32_t USB_ReadDevAllInEpInterrupt(USB_OTG_GlobalTypeDef *USBx);
uint32_t USB_ReadDevInEPInterrupt(USB_OTG_GlobalTypeDef *USBx, uint8_t epnum);
void USB_ClearInterrupts(USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt);
HAL_StatusTypeDef USB_HostInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg);
HAL_StatusTypeDef USB_InitFSLSPClkSel(USB_OTG_GlobalTypeDef *USBx, uint8_t freq);
HAL_StatusTypeDef USB_ResetPort(USB_OTG_GlobalTypeDef *USBx);
HAL_StatusTypeDef USB_DriveVbus(USB_OTG_GlobalTypeDef *USBx, uint8_t state);
uint32_t USB_GetHostSpeed(USB_OTG_GlobalTypeDef *USBx);
uint32_t USB_GetCurrentFrame(USB_OTG_GlobalTypeDef *USBx);
HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num,
uint8_t epnum, uint8_t dev_address, uint8_t speed,
uint8_t ep_type, uint16_t mps);
HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx,
USB_OTG_HCTypeDef *hc, uint8_t dma);
uint32_t USB_HC_ReadInterrupt(USB_OTG_GlobalTypeDef *USBx);
HAL_StatusTypeDef USB_HC_Halt(USB_OTG_GlobalTypeDef *USBx, uint8_t hc_num);
HAL_StatusTypeDef USB_DoPing(USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num);
HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx);
HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_OTG_GlobalTypeDef *USBx);
HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_OTG_GlobalTypeDef *USBx);
/**
* @}
*/
#endif /* defined (USB_OTG_FS) */
#endif /* __XC_HAL_LL_USB_NP_H */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,686 @@
/*!
* \file xc_hal_pcd_np.h
*
* \brief PCD HAL module driver.(use non-periodic fifo)
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author MCD Application Team
*
* \author ( XinChip ) Alex-J
*/
#ifndef __XC_HAL_PCD_NP_H
#define __XC_HAL_PCD_NP_H
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "xc_hal_ll_usb_np.h"
#if defined (USB_OTG_FS) || defined (USB_OTG_HS)
/*------------------------------------------------------------------------------------
Typedef
------------------------------------------------------------------------------------*/
/**
* @brief PCD State structure definition
*/
typedef enum
{
HAL_PCD_STATE_RESET = 0x00,
HAL_PCD_STATE_READY = 0x01,
HAL_PCD_STATE_ERROR = 0x02,
HAL_PCD_STATE_BUSY = 0x03,
HAL_PCD_STATE_TIMEOUT = 0x04
} PCD_StateTypeDef;
/* Device LPM suspend state */
typedef enum
{
LPM_L0 = 0x00, /* on */
LPM_L1 = 0x01, /* LPM L1 sleep */
LPM_L2 = 0x02, /* suspend */
LPM_L3 = 0x03, /* off */
} PCD_LPM_StateTypeDef;
typedef enum
{
PCD_LPM_L0_ACTIVE = 0x00, /* on */
PCD_LPM_L1_ACTIVE = 0x01, /* LPM L1 sleep */
} PCD_LPM_MsgTypeDef;
typedef enum
{
PCD_BCD_ERROR = 0xFF,
PCD_BCD_CONTACT_DETECTION = 0xFE,
PCD_BCD_STD_DOWNSTREAM_PORT = 0xFD,
PCD_BCD_CHARGING_DOWNSTREAM_PORT = 0xFC,
PCD_BCD_DEDICATED_CHARGING_PORT = 0xFB,
PCD_BCD_DISCOVERY_COMPLETED = 0x00,
} PCD_BCD_MsgTypeDef;
#if defined (USB_OTG_FS) || defined (USB_OTG_HS)
typedef USB_OTG_GlobalTypeDef PCD_TypeDef;
typedef USB_OTG_CfgTypeDef PCD_InitTypeDef;
typedef USB_OTG_EPTypeDef PCD_EPTypeDef;
#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
/**
* @brief PCD Handle Structure definition
*/
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
typedef struct __PCD_HandleTypeDef
#else
typedef struct
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
{
PCD_TypeDef *Instance; /*!< Register base address */
PCD_InitTypeDef Init; /*!< PCD required parameters */
__IO uint8_t USB_Address; /*!< USB Address */
PCD_EPTypeDef IN_ep[16]; /*!< IN endpoint parameters */
PCD_EPTypeDef OUT_ep[16]; /*!< OUT endpoint parameters */
HAL_LockTypeDef Lock; /*!< PCD peripheral status */
__IO PCD_StateTypeDef State; /*!< PCD communication state */
__IO uint32_t ErrorCode; /*!< PCD Error code */
uint32_t Setup[12]; /*!< Setup packet buffer */
PCD_LPM_StateTypeDef LPM_State; /*!< LPM State */
uint32_t BESL;
uint32_t FrameNumber; /*!< Store Current Frame number */
uint32_t lpm_active; /*!< Enable or disable the Link Power Management .
This parameter can be set to ENABLE or DISABLE */
uint32_t battery_charging_active; /*!< Enable or disable Battery charging.
This parameter can be set to ENABLE or DISABLE */
void *pData; /*!< Pointer to upper stack Handler */
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
void (* SOFCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD SOF callback */
void (* SetupStageCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Setup Stage callback */
void (* ResetCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Reset callback */
void (* SuspendCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Suspend callback */
void (* ResumeCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Resume callback */
void (* ConnectCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Connect callback */
void (* DisconnectCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Disconnect callback */
void (* DataOutStageCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< USB OTG PCD Data OUT Stage callback */
void (* DataInStageCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< USB OTG PCD Data IN Stage callback */
void (* ISOOUTIncompleteCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< USB OTG PCD ISO OUT Incomplete callback */
void (* ISOINIncompleteCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< USB OTG PCD ISO IN Incomplete callback */
void (* BCDCallback)(struct __PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg); /*!< USB OTG PCD BCD callback */
void (* LPMCallback)(struct __PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg); /*!< USB OTG PCD LPM callback */
void (* MspInitCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Msp Init callback */
void (* MspDeInitCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Msp DeInit callback */
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
} PCD_HandleTypeDef;
typedef struct {
uint8_t IN_Lock;
uint8_t OUT_Lock;
} PCD_IN_OUT_Status;
extern PCD_IN_OUT_Status PCD_Sta;
/*------------------------------------------------------------------------------------
Macros
-------------------------------------------------------------------------------------*/
/** @defgroup PCD_Speed PCD Speed
* @{
*/
#define PCD_SPEED_HIGH USBD_HS_SPEED
#define PCD_SPEED_HIGH_IN_FULL USBD_HSINFS_SPEED
#define PCD_SPEED_FULL USBD_FS_SPEED
/**
* @}
*/
/** @defgroup PCD_PHY_Module PCD PHY Module
* @{
*/
#define PCD_PHY_ULPI 1U
#define PCD_PHY_EMBEDDED 2U
#define PCD_PHY_UTMI 3U
/**
* @}
*/
/** @defgroup PCD_Error_Code_definition PCD Error Code definition
* @brief PCD Error Code definition
* @{
*/
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
#define HAL_PCD_ERROR_INVALID_CALLBACK (0x00000010U) /*!< Invalid Callback error */
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
/** @defgroup PCD_Exported_Macros PCD Exported Macros
* @brief macros to handle interrupts and specific clock configurations
* @{
*/
#if defined (USB_OTG_FS) || defined (USB_OTG_HS)
#define __HAL_PCD_ENABLE(__HANDLE__) (void)USB_EnableGlobalInt ((__HANDLE__)->Instance)
#define __HAL_PCD_DISABLE(__HANDLE__) (void)USB_DisableGlobalInt ((__HANDLE__)->Instance)
#define __HAL_PCD_GET_FLAG(__HANDLE__, __INTERRUPT__) \
((USB_ReadInterrupts((__HANDLE__)->Instance) & (__INTERRUPT__)) == (__INTERRUPT__))
#define __HAL_PCD_CLEAR_FLAG(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->GINTSTS) &= (__INTERRUPT__))
#define __HAL_PCD_IS_INVALID_INTERRUPT(__HANDLE__) (USB_ReadInterrupts((__HANDLE__)->Instance) == 0U)
#define __HAL_PCD_UNGATE_PHYCLOCK(__HANDLE__) \
*(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE) &= ~(USB_OTG_PCGCCTL_STOPCLK)
#define __HAL_PCD_GATE_PHYCLOCK(__HANDLE__) \
*(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE) |= USB_OTG_PCGCCTL_STOPCLK
#define __HAL_PCD_IS_PHY_SUSPENDED(__HANDLE__) \
((*(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE)) & 0x10U)
#define __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_IT() EXTI->IMR |= (USB_OTG_HS_WAKEUP_EXTI_LINE)
#define __HAL_USB_OTG_HS_WAKEUP_EXTI_DISABLE_IT() EXTI->IMR &= ~(USB_OTG_HS_WAKEUP_EXTI_LINE)
#define __HAL_USB_OTG_HS_WAKEUP_EXTI_GET_FLAG() EXTI->PR & (USB_OTG_HS_WAKEUP_EXTI_LINE)
#define __HAL_USB_OTG_HS_WAKEUP_EXTI_CLEAR_FLAG() EXTI->PR = (USB_OTG_HS_WAKEUP_EXTI_LINE)
#define __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_RISING_EDGE() \
do { \
EXTI->FTSR &= ~(USB_OTG_HS_WAKEUP_EXTI_LINE); \
EXTI->RTSR |= USB_OTG_HS_WAKEUP_EXTI_LINE; \
} while(0U)
#define __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_IT() EXTI->IMR |= USB_OTG_FS_WAKEUP_EXTI_LINE
#define __HAL_USB_OTG_FS_WAKEUP_EXTI_DISABLE_IT() EXTI->IMR &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE)
#define __HAL_USB_OTG_FS_WAKEUP_EXTI_GET_FLAG() EXTI->PR & (USB_OTG_FS_WAKEUP_EXTI_LINE)
#define __HAL_USB_OTG_FS_WAKEUP_EXTI_CLEAR_FLAG() EXTI->PR = USB_OTG_FS_WAKEUP_EXTI_LINE
#define __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_RISING_EDGE() \
do { \
EXTI->FTSR &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE); \
EXTI->RTSR |= USB_OTG_FS_WAKEUP_EXTI_LINE; \
} while(0U)
#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
/** @defgroup USB_EXTI_Line_Interrupt USB EXTI line interrupt
* @{
*/
#if defined (USB_OTG_FS) || defined (USB_OTG_HS)
#define USB_OTG_FS_WAKEUP_EXTI_LINE (0x1U << 18) /*!< USB FS EXTI Line WakeUp Interrupt */
#define USB_OTG_HS_WAKEUP_EXTI_LINE (0x1U << 20) /*!< USB HS EXTI Line WakeUp Interrupt */
#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
/**
* @}
*/
#if defined (USB_OTG_FS) || defined (USB_OTG_HS)
#ifndef USB_OTG_DOEPINT_OTEPSPR
#define USB_OTG_DOEPINT_OTEPSPR (0x1UL << 5) /*!< Status Phase Received interrupt */
#endif /* defined USB_OTG_DOEPINT_OTEPSPR */
#ifndef USB_OTG_DOEPMSK_OTEPSPRM
#define USB_OTG_DOEPMSK_OTEPSPRM (0x1UL << 5) /*!< Setup Packet Received interrupt mask */
#endif /* defined USB_OTG_DOEPMSK_OTEPSPRM */
#ifndef USB_OTG_DOEPINT_NAK
#define USB_OTG_DOEPINT_NAK (0x1UL << 13) /*!< NAK interrupt */
#endif /* defined USB_OTG_DOEPINT_NAK */
#ifndef USB_OTG_DOEPMSK_NAKM
#define USB_OTG_DOEPMSK_NAKM (0x1UL << 13) /*!< OUT Packet NAK interrupt mask */
#endif /* defined USB_OTG_DOEPMSK_NAKM */
#ifndef USB_OTG_DOEPINT_STPKTRX
#define USB_OTG_DOEPINT_STPKTRX (0x1UL << 15) /*!< Setup Packet Received interrupt */
#endif /* defined USB_OTG_DOEPINT_STPKTRX */
#ifndef USB_OTG_DOEPMSK_NYETM
#define USB_OTG_DOEPMSK_NYETM (0x1UL << 14) /*!< Setup Packet Received interrupt mask */
#endif /* defined USB_OTG_DOEPMSK_NYETM */
#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
/*------------------------------------------------------------------------------------
Exported Functions
------------------------------------------------------------------------------------*/
/* Initialization/de-initialization functions ********************************/
/** @addtogroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
* @{
*/
HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd);
HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd);
void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd);
void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd);
HAL_StatusTypeDef HAL_PCDEx_SetTxFiFo(PCD_HandleTypeDef *hpcd, uint8_t fifo, uint16_t size);
HAL_StatusTypeDef HAL_PCDEx_SetRxFiFo(PCD_HandleTypeDef *hpcd, uint16_t size);
#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
/** @defgroup HAL_PCD_Callback_ID_enumeration_definition HAL USB OTG PCD Callback ID enumeration definition
* @brief HAL USB OTG PCD Callback ID enumeration definition
* @{
*/
typedef enum
{
HAL_PCD_SOF_CB_ID = 0x01, /*!< USB PCD SOF callback ID */
HAL_PCD_SETUPSTAGE_CB_ID = 0x02, /*!< USB PCD Setup Stage callback ID */
HAL_PCD_RESET_CB_ID = 0x03, /*!< USB PCD Reset callback ID */
HAL_PCD_SUSPEND_CB_ID = 0x04, /*!< USB PCD Suspend callback ID */
HAL_PCD_RESUME_CB_ID = 0x05, /*!< USB PCD Resume callback ID */
HAL_PCD_CONNECT_CB_ID = 0x06, /*!< USB PCD Connect callback ID */
HAL_PCD_DISCONNECT_CB_ID = 0x07, /*!< USB PCD Disconnect callback ID */
HAL_PCD_MSPINIT_CB_ID = 0x08, /*!< USB PCD MspInit callback ID */
HAL_PCD_MSPDEINIT_CB_ID = 0x09 /*!< USB PCD MspDeInit callback ID */
} HAL_PCD_CallbackIDTypeDef;
/**
* @}
*/
/** @defgroup HAL_PCD_Callback_pointer_definition HAL USB OTG PCD Callback pointer definition
* @brief HAL USB OTG PCD Callback pointer definition
* @{
*/
typedef void (*pPCD_CallbackTypeDef)(PCD_HandleTypeDef *hpcd); /*!< pointer to a common USB OTG PCD callback function */
typedef void (*pPCD_DataOutStageCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< pointer to USB OTG PCD Data OUT Stage callback */
typedef void (*pPCD_DataInStageCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< pointer to USB OTG PCD Data IN Stage callback */
typedef void (*pPCD_IsoOutIncpltCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< pointer to USB OTG PCD ISO OUT Incomplete callback */
typedef void (*pPCD_IsoInIncpltCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< pointer to USB OTG PCD ISO IN Incomplete callback */
typedef void (*pPCD_LpmCallbackTypeDef)(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg); /*!< pointer to USB OTG PCD LPM callback */
typedef void (*pPCD_BcdCallbackTypeDef)(PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg); /*!< pointer to USB OTG PCD BCD callback */
/**
* @}
*/
HAL_StatusTypeDef HAL_PCD_RegisterCallback(PCD_HandleTypeDef *hpcd,
HAL_PCD_CallbackIDTypeDef CallbackID,
pPCD_CallbackTypeDef pCallback);
HAL_StatusTypeDef HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef *hpcd,
HAL_PCD_CallbackIDTypeDef CallbackID);
HAL_StatusTypeDef HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd,
pPCD_DataOutStageCallbackTypeDef pCallback);
HAL_StatusTypeDef HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd);
HAL_StatusTypeDef HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef *hpcd,
pPCD_DataInStageCallbackTypeDef pCallback);
HAL_StatusTypeDef HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef *hpcd);
HAL_StatusTypeDef HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd,
pPCD_IsoOutIncpltCallbackTypeDef pCallback);
HAL_StatusTypeDef HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd);
HAL_StatusTypeDef HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd,
pPCD_IsoInIncpltCallbackTypeDef pCallback);
HAL_StatusTypeDef HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd);
HAL_StatusTypeDef HAL_PCD_RegisterBcdCallback(PCD_HandleTypeDef *hpcd,
pPCD_BcdCallbackTypeDef pCallback);
HAL_StatusTypeDef HAL_PCD_UnRegisterBcdCallback(PCD_HandleTypeDef *hpcd);
HAL_StatusTypeDef HAL_PCD_RegisterLpmCallback(PCD_HandleTypeDef *hpcd,
pPCD_LpmCallbackTypeDef pCallback);
HAL_StatusTypeDef HAL_PCD_UnRegisterLpmCallback(PCD_HandleTypeDef *hpcd);
#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
/**
* @}
*/
/* I/O operation functions ***************************************************/
/* Non-Blocking mode: Interrupt */
/** @addtogroup PCD_Exported_Functions_Group2 Input and Output operation functions
* @{
*/
HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd);
HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd);
void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd);
void HAL_PCD_WKUP_IRQHandler(PCD_HandleTypeDef *hpcd);
void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd);
void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd);
void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd);
void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd);
void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd);
void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd);
void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd);
void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
/**
* @}
*/
/* Peripheral Control functions **********************************************/
/** @addtogroup PCD_Exported_Functions_Group3 Peripheral Control functions
* @{
*/
HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd);
HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd);
HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address);
HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr,
uint16_t ep_mps, uint8_t ep_type);
HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr,
uint8_t *pBuf, uint32_t len);
HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr,
uint8_t *pBuf, uint32_t len);
HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd);
HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd);
HAL_StatusTypeDef HAL_PCD_EP_Abort(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
/**
* @}
*/
/* Peripheral State functions ************************************************/
/** @addtogroup PCD_Exported_Functions_Group4 Peripheral State functions
* @{
*/
PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd);
/**
* @}
*/
#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */
#ifdef __cplusplus
}
#endif
#if 0
#if defined(USB_OTG_FS)
/*------------------------------------------------------------------------------------
Typedef
------------------------------------------------------------------------------------*/
/**
* @brief PCD State structure definition
*/
typedef enum
{
HAL_PCD_STATE_RESET = 0x00,
HAL_PCD_STATE_READY = 0x01,
HAL_PCD_STATE_ERROR = 0x02,
HAL_PCD_STATE_BUSY = 0x03,
HAL_PCD_STATE_TIMEOUT = 0x04
} PCD_StateTypeDef;
/* Device LPM suspend state */
typedef enum
{
LPM_L0 = 0x00, /* on */
LPM_L1 = 0x01, /* LPM L1 sleep */
LPM_L2 = 0x02, /* suspend */
LPM_L3 = 0x03, /* off */
} PCD_LPM_StateTypeDef;
typedef enum
{
PCD_LPM_L0_ACTIVE = 0x00, /* on */
PCD_LPM_L1_ACTIVE = 0x01, /* LPM L1 sleep */
} PCD_LPM_MsgTypeDef;
typedef enum
{
PCD_BCD_ERROR = 0xFF,
PCD_BCD_CONTACT_DETECTION = 0xFE,
PCD_BCD_STD_DOWNSTREAM_PORT = 0xFD,
PCD_BCD_CHARGING_DOWNSTREAM_PORT = 0xFC,
PCD_BCD_DEDICATED_CHARGING_PORT = 0xFB,
PCD_BCD_DISCOVERY_COMPLETED = 0x00,
} PCD_BCD_MsgTypeDef;
typedef USB_OTG_GlobalTypeDef PCD_TypeDef;
typedef USB_OTG_CfgTypeDef PCD_InitTypeDef;
typedef USB_OTG_EPTypeDef PCD_EPTypeDef;
/**
* @brief PCD Handle Structure definition
*/
typedef struct
{
PCD_TypeDef *Instance; /*!< Register base address */
PCD_InitTypeDef Init; /*!< PCD required parameters */
__IO uint8_t USB_Address; /*!< USB Address */
PCD_EPTypeDef IN_ep[16]; /*!< IN endpoint parameters */
PCD_EPTypeDef OUT_ep[16]; /*!< OUT endpoint parameters */
HAL_LockTypeDef Lock; /*!< PCD peripheral status */
__IO PCD_StateTypeDef State; /*!< PCD communication state */
__IO uint32_t ErrorCode; /*!< PCD Error code */
uint32_t Setup[12]; /*!< Setup packet buffer */
PCD_LPM_StateTypeDef LPM_State; /*!< LPM State */
uint32_t BESL;
uint32_t FrameNumber; /*!< Store Current Frame number */
uint32_t lpm_active; /*!< Enable or disable the Link Power Management .
This parameter can be set to ENABLE or DISABLE */
uint32_t battery_charging_active; /*!< Enable or disable Battery charging.
This parameter can be set to ENABLE or DISABLE */
void *pData; /*!< Pointer to upper stack Handler */
} PCD_HandleTypeDef;
/*------------------------------------------------------------------------------------
Macros
-------------------------------------------------------------------------------------*/
/** @defgroup PCD_Speed PCD Speed
* @{
*/
//#define PCD_SPEED_HIGH USBD_HS_SPEED
//#define PCD_SPEED_HIGH_IN_FULL USBD_HSINFS_SPEED
#define PCD_SPEED_FULL USBD_FS_SPEED
/**
* @}
*/
/** @defgroup PCD_PHY_Module PCD PHY Module
* @{
*/
#define PCD_PHY_ULPI 1U
#define PCD_PHY_EMBEDDED 2U
#define PCD_PHY_UTMI 3U
/**
* @}
*/
/** @defgroup PCD_Exported_Macros PCD Exported Macros
* @brief macros to handle interrupts and specific clock configurations
* @{
*/
#define __HAL_PCD_ENABLE(__HANDLE__) (void)USB_EnableGlobalInt ((__HANDLE__)->Instance)
#define __HAL_PCD_DISABLE(__HANDLE__) (void)USB_DisableGlobalInt ((__HANDLE__)->Instance)
#define __HAL_PCD_GET_FLAG(__HANDLE__, __INTERRUPT__) \
((USB_ReadInterrupts((__HANDLE__)->Instance) & (__INTERRUPT__)) == (__INTERRUPT__))
#define __HAL_PCD_CLEAR_FLAG(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->GINTSTS) &= (__INTERRUPT__))
#define __HAL_PCD_IS_INVALID_INTERRUPT(__HANDLE__) (USB_ReadInterrupts((__HANDLE__)->Instance) == 0U)
#define __HAL_PCD_UNGATE_PHYCLOCK(__HANDLE__) \
*(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE) &= ~(USB_OTG_PCGCCTL_STOPCLK)
#define __HAL_PCD_GATE_PHYCLOCK(__HANDLE__) \
*(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE) |= USB_OTG_PCGCCTL_STOPCLK
#define __HAL_PCD_IS_PHY_SUSPENDED(__HANDLE__) \
((*(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE)) & 0x10U)
//#define __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_IT() EXTI->IMR |= (USB_OTG_HS_WAKEUP_EXTI_LINE)
//#define __HAL_USB_OTG_HS_WAKEUP_EXTI_DISABLE_IT() EXTI->IMR &= ~(USB_OTG_HS_WAKEUP_EXTI_LINE)
//#define __HAL_USB_OTG_HS_WAKEUP_EXTI_GET_FLAG() EXTI->PR & (USB_OTG_HS_WAKEUP_EXTI_LINE)
//#define __HAL_USB_OTG_HS_WAKEUP_EXTI_CLEAR_FLAG() EXTI->PR = (USB_OTG_HS_WAKEUP_EXTI_LINE)
//#define __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_RISING_EDGE() \
// do { \
// EXTI->FTSR &= ~(USB_OTG_HS_WAKEUP_EXTI_LINE); \
// EXTI->RTSR |= USB_OTG_HS_WAKEUP_EXTI_LINE; \
// } while(0U)
#define __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_IT() EXTI->IMR |= USB_OTG_FS_WAKEUP_EXTI_LINE
#define __HAL_USB_OTG_FS_WAKEUP_EXTI_DISABLE_IT() EXTI->IMR &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE)
#define __HAL_USB_OTG_FS_WAKEUP_EXTI_GET_FLAG() EXTI->PR & (USB_OTG_FS_WAKEUP_EXTI_LINE)
#define __HAL_USB_OTG_FS_WAKEUP_EXTI_CLEAR_FLAG() EXTI->PR = USB_OTG_FS_WAKEUP_EXTI_LINE
#define __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_RISING_EDGE() \
do { \
EXTI->FTSR &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE); \
EXTI->RTSR |= USB_OTG_FS_WAKEUP_EXTI_LINE; \
} while(0U)
/** @defgroup USB_EXTI_Line_Interrupt USB EXTI line interrupt
* @{
*/
#define USB_OTG_FS_WAKEUP_EXTI_LINE (0x1U << 18) /*!< USB FS EXTI Line WakeUp Interrupt */
//#define USB_OTG_HS_WAKEUP_EXTI_LINE (0x1U << 20) /*!< USB HS EXTI Line WakeUp Interrupt */
/**
* @}
*/
#ifndef USB_OTG_DOEPINT_OTEPSPR
#define USB_OTG_DOEPINT_OTEPSPR (0x1UL << 5) /*!< Status Phase Received interrupt */
#endif /* defined USB_OTG_DOEPINT_OTEPSPR */
#ifndef USB_OTG_DOEPMSK_OTEPSPRM
#define USB_OTG_DOEPMSK_OTEPSPRM (0x1UL << 5) /*!< Setup Packet Received interrupt mask */
#endif /* defined USB_OTG_DOEPMSK_OTEPSPRM */
#ifndef USB_OTG_DOEPINT_NAK
#define USB_OTG_DOEPINT_NAK (0x1UL << 13) /*!< NAK interrupt */
#endif /* defined USB_OTG_DOEPINT_NAK */
#ifndef USB_OTG_DOEPMSK_NAKM
#define USB_OTG_DOEPMSK_NAKM (0x1UL << 13) /*!< OUT Packet NAK interrupt mask */
#endif /* defined USB_OTG_DOEPMSK_NAKM */
#ifndef USB_OTG_DOEPINT_STPKTRX
#define USB_OTG_DOEPINT_STPKTRX (0x1UL << 15) /*!< Setup Packet Received interrupt */
#endif /* defined USB_OTG_DOEPINT_STPKTRX */
#ifndef USB_OTG_DOEPMSK_NYETM
#define USB_OTG_DOEPMSK_NYETM (0x1UL << 14) /*!< Setup Packet Received interrupt mask */
#endif /* defined USB_OTG_DOEPMSK_NYETM */
/*------------------------------------------------------------------------------------
Exported Functions
------------------------------------------------------------------------------------*/
/* Initialization/de-initialization functions ********************************/
/** @addtogroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
* @{
*/
HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd);
HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd);
void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd);
void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd);
HAL_StatusTypeDef HAL_PCDEx_SetTxFiFo(PCD_HandleTypeDef *hpcd, uint8_t fifo, uint16_t size);
HAL_StatusTypeDef HAL_PCDEx_SetRxFiFo(PCD_HandleTypeDef *hpcd, uint16_t size);
/**
* @}
*/
/* I/O operation functions ***************************************************/
/* Non-Blocking mode: Interrupt */
/** @addtogroup PCD_Exported_Functions_Group2 Input and Output operation functions
* @{
*/
HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd);
HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd);
void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd);
void HAL_PCD_WKUP_IRQHandler(PCD_HandleTypeDef *hpcd);
void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd);
void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd);
void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd);
void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd);
void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd);
void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd);
void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd);
void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum);
/**
* @}
*/
/* Peripheral Control functions **********************************************/
/** @addtogroup PCD_Exported_Functions_Group3 Peripheral Control functions
* @{
*/
HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd);
HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd);
HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address);
HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr,
uint16_t ep_mps, uint8_t ep_type);
HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr,
uint8_t *pBuf, uint32_t len);
HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr,
uint8_t *pBuf, uint32_t len);
HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd);
HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd);
HAL_StatusTypeDef HAL_PCD_EP_Abort(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef *hpcd, uint8_t ep_addr);
/**
* @}
*/
/* Peripheral State functions ************************************************/
/** @addtogroup PCD_Exported_Functions_Group4 Peripheral State functions
* @{
*/
PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef *hpcd);
/**
* @}
*/
#endif /* defined (USB_OTG_FS) */
#endif
#endif /* __XC_HAL_PCD_NP_H */
@@ -0,0 +1,266 @@
/*!
* \file xc_hal_usb.c
*
* \brief Target xinchip hal usb implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "xc_hal_usb.h"
#include "xc6xxx.h"
/*------------------------------------------------------------------------------------
Macros
-------------------------------------------------------------------------------------*/
#define USB_RESET_ON( ) cpr_rf_reg1__usb_rstn_reg__setf(0)//CLEAR_BIT(XC_CPR->RF_REG1, (1 << 20))
#define USB_RESET_OFF( ) cpr_rf_reg1__usb_rstn_reg__setf(1)//SET_BIT(XC_CPR->RF_REG1, (1 << 20))
/*------------------------------------------------------------------------------------
Functions
-------------------------------------------------------------------------------------*/
/**
* @brief usb phy dm operation
* @param uint32_t - bit
* @retval None
*/
void USB_Phy_DM_Oprt(uint32_t bit)
{
cpr_rf_reg5__usb_rwreg__setf(bit << 3);
// if(bit == PULL_UP)
// SET_BIT(XC_CPR->RF_REG5, (bit << 3));
// else if(bit == PULL_DOWN)
// CLEAR_BIT(XC_CPR->RF_REG5, (bit << 3));
}
/**
* @brief usb phy dp operation
* @param uint32_t - bit
* @retval None
*/
void USB_Phy_DP_Oprt(uint32_t bit)
{
cpr_rf_reg5__usb_rwreg__setf(bit << 2);
// if(bit == PULL_UP)
// SET_BIT(XC_CPR->RF_REG5, (bit << 2));
// else if(bit == PULL_DOWN)
// CLEAR_BIT(XC_CPR->RF_REG5, (bit << 2));
}
/**
* @brief usb phy enable
* @param void
* @retval None
*/
void USB_Phy_Enable( void )
{
cpr_rf_reg5__usb_rwreg__setf(0 << 4);
// CLEAR_BIT(XC_CPR->RF_REG5, (1 << 4));
// SET_BIT(XC_CPR->RF_REG5, (1 << 4));
}
/**
* @brief usb phy disable
* @param void
* @retval None
*/
void USB_Phy_Disable( void )
{
cpr_rf_reg5__usb_rwreg__setf(1 << 4);
// SET_BIT(XC_CPR->RF_REG5, (1 << 4));
}
#define readl(addr) (*(volatile unsigned int *) (addr))
#define writel(addr, value) (*(volatile unsigned int *) (addr) = (value))
/**
* @brief 32M OSC multiper bbpll to 96M
* @param void
* @retval None
*/
void OSC32M_Multi_BBPLL_96M( void )
{
#if (XC6XX_5C != 1)
if(xc_clock_hfclk_in_get() == CLOCK_HFCLK_IN_32M)
{
xc_clock_bbpll_common_cfg( );
rf_ana27__bbpll_16m_sel__setf(DISABLE);
rf_ana27__bbpll_core_96m_en__setf(DISABLE);
rf_ana26__bbpll_loopdiv__setf(0x03);
rf_ana26__clk_bbpll_en__setf(ENABLE);
rf_ana26__clk_bbpll_rstn__setf(ENABLE);
rf_ana26__bbpll_en__setf(ENABLE);
rf_ana26__bbpll_core_64m_en__setf(ENABLE);
// /* BT_CLK 时钟控制寄存器 */
// XC_CPR->BT_CLK_CTL = (CPR_BT_CLK_CTL_BT_CLK_EN_ENABLE | (CPR_BT_CLK_CTL_BT_CLK_EN_Msk << 16));
// /* BT_MODEM_CLK 时钟控制寄存器 */
//// XC_CPR->BT_MODEM_CTL = (CPR_BT_MODEM_CLK_CTL_BT_MODEM_CLK_EN_ENABLE |
//// (CPR_BT_MODEM_CLK_CTL_BT_MODEM_CLK_EN_Msk << 16));
// /* 配置 BT_PCLK_EN 使能 */
// XC_CPR->CTLAPBCLKEN_GRCTL |= (CPR_CTLAPBCLKEN_GRCTL_BT_PCLK_EN_ENABLE |
// (CPR_CTLAPBCLKEN_GRCTL_BT_PCLK_EN_Msk << CPR_CTLAPBCLKEN_GRCTL_MASK_OFFSET));
//
// SET_BIT(XC_BT_RF->BT.rx_pm_reg_l, (1 << 14));
// XC_CPR_AO->AON_CORERFLDO_EN = 0x1;
// SET_BIT(XC_BT_RF->ana26_reg_l, (0xf << 12));
// SET_BIT(XC_BT_RF->ana27_reg_l, 0x02); // ana27 div 2
// SET_BIT(XC_BT_RF->ana26_reg_l, 0x06); // ana26 6*32 / 2 = 192M / 2 = 96M
}
#else
uint32_t last_idx = xc_clock_hfclk_in_get()/1000000;
// CLEAR_BIT(XC_CPR->RF_REG4, (uint32_t)0x1f);
// SET_BIT(XC_CPR->RF_REG4, (uint32_t)0x11);
// CLEAR_BIT(XC_CPR->RF_REG3, (uint32_t)(0x07 | (0x1f<<8) | (0x3f<<14)));
// SET_BIT(XC_CPR->RF_REG3, (uint32_t)((0x1 << 1) | (0x07<<8) | (0x08<<14)));
uint32_t val = XC_CPR->RF_REG4;
XC_CPR->RF_REG4 = (val & 0xFFFFFFE0) | 0x11; // div2
val = XC_CPR->RF_REG3;
//[00-OSC32M],[01-bbpll direct output],[10-bbpll div output],[11-rc16M]
XC_CPR->RF_REG3 = (val & (~(uint32_t)(0x07 | (0x1f<<8) | (0x3f<<14)))) |
(0x1 << 1) | (0x07<<8) | (0x08<<14);
m_clock_cb.hfclk_in = CLOCK_HFCLK_IN_96M;
uint32_t baudrate, uart_clk, div, mul, clk_ctl, adj_div;
uart_clk = xc_clock_hfclk_in_get();
baudrate = XC_CPR->UART0_CLK_CTL;
mul = (baudrate >> 16) & 0xFFFF;
div = (baudrate & 0xFFFF);
adj_div = uart_clk / 1000000;
clk_ctl = (mul << 16 ) | ( div * adj_div / last_idx);
XC_CPR->UART0_CLK_CTL = clk_ctl;
SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;
SysTick_Config(xc_clock_hfclk_in_get() / 100);
#endif
}
/**
* @brief usb bbpll close
* @param void
* @retval None
*/
void USB_BBPLL_Close( void )
{
rf_ana26__bbpll_core_64m_en__setf(DISABLE);
rf_ana26__bbpll_en__setf(DISABLE);
rf_ana26__clk_bbpll_rstn__setf(DISABLE);
rf_ana26__clk_bbpll_en__setf(DISABLE);
rf_ana26__bbpll_loopdiv__setf(0x00);
// CLEAR_BIT(XC_BT_RF->ana26_reg_l, (0xf << 12));
// CLEAR_BIT(XC_BT_RF->ana26_reg_l, 0x06);
}
/**
* @brief usb pll enable
* @param void
* @retval None
*/
void USB_PLL_Enable( void )
{
OSC32M_Multi_BBPLL_96M( );
cpr_rf_reg1__usb_mclk_div__setf(1);
cpr_rf_reg1__usb_hclk_en__setf(1);
cpr_rf_reg1__usb_mclk_en__setf(1);
cpr_rf_reg1__usb_utmi_clk_div__setf(1);
cpr_rf_reg1__usb_utmi_clk_en__setf(1);
// WRITE_REG(XC_CPR->RF_REG1, (XC_CPR->RF_REG1 & 0xE0FFCFF0) | 0x11003001); // usb clk enable
}
/**
* @brief usb pll disable
* @param void
* @retval None
*/
void USB_PLL_Disable( void )
{
USB_BBPLL_Close( );
}
/**
* @brief usb phy init
* @param void
* @retval None
*/
void USB_Phy_Init( void )
{
USB_PLL_Enable( );
USB_RESET_ON( );
HAL_Delay(100);//for(int i = 0; i < 0x4550; i++);//HAL_Delay(100);
USB_RESET_OFF( );
}
/**
* @brief usb phy deinit
* @param void
* @retval None
*/
void USB_Phy_Deinit( void )
{
NVIC_DisableIRQ(USB_IRQn);
cpr_rf_reg1__usb_utmi_clk_en__setf(0);
cpr_rf_reg1__usb_utmi_clk_div__setf(0);
cpr_rf_reg1__usb_hclk_en__setf(0);
cpr_rf_reg1__usb_mclk_en__setf(0);
// WRITE_REG(XC_CPR->RF_REG1, (XC_CPR->RF_REG1 & 0xE0FFCFF0) | (~0x00003000)); // usb clk disable
USB_Phy_Disable( );
}
/**
* @brief usb phy reset
* @param void
* @retval None
*/
void USB_Phy_Reset( void )
{
USB_RESET_ON( );
HAL_Delay(150); //for(int i = 0; i < 0x4550; i++);//HAL_Delay(100);
USB_RESET_OFF( );
HAL_Delay(10);
}
/**
* @brief usb current control
* @param uint8_t - val
* @retval None
*/
void USB_Current_Ctrl( uint8_t val )
{
cpr_rf_reg5__usbphy_usb_ibc__setf(val);
// CLEAR_BIT(XC_CPR->RF_REG5, (3 << 21));
// SET_BIT(XC_CPR->RF_REG5, (val << 21));
}
@@ -0,0 +1,68 @@
/*!
* \file xc_hal_usb.h
*
* \brief The header of xc_hal_usb.c
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
#ifndef __XC_HAL_USB_H_
#define __XC_HAL_USB_H_
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include <stdint.h>
/*------------------------------------------------------------------------------------
Macros
-------------------------------------------------------------------------------------*/
//#define SET_REG_BIT(REG, BIT) ((REG) |= (BIT))
//#define CLEAR_REG_BIT(REG, BIT) ((REG) &= ~(BIT))
//#define READ_BIT(REG, BIT) ((REG) & (BIT))
//#define CLEAR_REG(REG) ((REG) = (0x0))
//#define WRITE_REG(REG, VAL) ((REG) = (VAL))
//#define READ_REG(REG) ((REG))
#define PULL_UP 1U
#define PULL_DOWN 0U
/*------------------------------------------------------------------------------------
Exported Functions
------------------------------------------- -----------------------------------------*/
void USB_Phy_DM_Oprt(uint32_t bit);
void USB_Phy_DP_Oprt(uint32_t bit);
void USB_Phy_Enable( void );
void USB_Phy_Disable( void );
void USB_PLL_Enable( void );
void USB_PLL_Disable( void );
void USB_Phy_Init( void );
void USB_Phy_Deinit( void );
void USB_Phy_Reset( void );
void USB_Current_Ctrl( uint8_t val );
#endif /* __XC_HAL_USB_H_ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,440 @@
/*!
* \file adc.c
*
* \brief Target adc implementation
*
* \copyright Revised BSD License, see section \ref LICENSE.
*
* \code
*
* _ __ _ ________ _
* | |/ /(_)___ / ____/ /_ (_)___
* | // / __ \/ / / __ \/ / __ \
* / |/ / / / / /___/ / / / / /_/ /
* /_/|_/_/_/ /_/\____/_/ /_/_/ .___/
* /_/
* (C) 2022-2025 XinChip
*
* \endcode
*
* \author ( XinChip ) Alex-J
*
* \author ( XinChip )
*/
/*-----------------------------------------------------------------------------------
INCLUDE HEADE FILES
------------------------------------------------------------------------------------*/
#include "adc.h"
#include "xc6xxx_hal_adc.h"
#include "xc6xxx_hal_adc_dmac.h"
/*------------------------------------------------------------------------------------
Macros
-------------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------------
Global Variables
-------------------------------------------------------------------------------------*/
uint8_t adc_ch_buff[1000];
extern uint32_t adc_val_buff[500];
uint16_t adc_con = 0;
/*------------------------------------------------------------------------------------
Functions
-------------------------------------------------------------------------------------*/
/**
* @brief adc_demo
* @details
* @param void
* @retval void
*/
void adc_demo(void)
{
DEBUG("__ADC_DEMO__\r");
DEBUG("XC_ADC->RF_CTL:%x\n", XC_ADC->RF_CTL);
uint16_t integer;
uint16_t decimal;
uint16_t adc_val = 0;
adc_cfg adc_cfg;
/*----- Special Pin -----*/
/*< SWD 和 SWCK 引脚也可以作为 ADC 使用,
PIN >*/
// GPIO_MuxCtl(12,1);
// GPIO_MuxCtl(13,1);
/*-----------------------*/
// *((volatile unsigned *)(0x4002F000 + 0x03C)) &= ~(0x1<<14);
adc_cfg.Freq = ADC_FREQ_2M;
adc_cfg.RefVol = ADC_REF_VOL_3_3V;
adc_cfg.SampEdge = ADC_SAMPEDGE_FALL;
adc_cfg.ExtDataMode = ADC_DATA_MODE_32BIT;
adc_cfg.ExtEdgeSel = ADC_EXT_EDGE_SEL_INTER;
adc_cfg.ExtSampleNum = ADC_SAMPLE_NUM_8;
adc_cfg.ExtTriggerSel = ADC_TRIGGER_SEL_PWM0;
ADC_Init(XC_ADC, &adc_cfg);
while (1) {
DEBUG("XC_ADC->RF_CTL22:%x\n", XC_ADC->RF_CTL);
ADC_StartGetValue(XC_ADC, ADC_CHANNEL4_PIN0, &adc_val);
if (adc_cfg.RefVol == ADC_REF_VOL_3_3V) {
integer = ((adc_val) * 3.3 * 100) / (1.0 * 4096) / 100;
decimal = ((uint32_t)((adc_val * 3.3 * 100) / 4096) % 100);
DEBUG("3.3v ref adc_vol=%d.%d ,adc_val=%d\n", integer, decimal,
adc_val);
} else if (adc_cfg.RefVol == ADC_REFVOL_2_33V) {
integer = ((adc_val) * 2.33 * 100) / (1.0 * 4096) / 100;
decimal = ((uint32_t)((adc_val * 2.33 * 100) / 4096) % 100);
DEBUG("2.33v ref adc_vol=%d.%d ,adc_val=%d\n", integer, decimal,
adc_val);
}
Delay_Ms(1000);
}
}
/**
* @brief adc_channel_sw_demo
* @details
* @param void
* @retval void
*/
void adc_channelswitch_sw_demo(void)
{
DEBUG("ADC channelswitch sw demo\n");
uint16_t integer;
uint16_t decimal;
adc_cfg adc_cfg;
Delay_Ms(500);
*((volatile unsigned int *)(0x400001BC)) &=
~(1 << 12); // 防止GPIO6被接到运放,导致GADC\上拉无效问题
GPIO_InitTypeDef GPIO_InitCfg = {0};
GPIO_InitCfg.Mux = GPIO_Mux0;
GPIO_InitCfg.FunSel = GPIO_Dx;
GPIO_InitCfg.Pull = GPIO_NOPULL;
// Board Led1 Initialization
GPIO_InitCfg.Dir = GPIO_DIR_INPUT;
GPIO_InitCfg.Int = NOT_INT;
GPIO_InitCfg.Pin = 20;
GPIO_Init(&GPIO_InitCfg);
GPIO_InitCfg.Pin = 18;
GPIO_Init(&GPIO_InitCfg);
GPIO_InitCfg.Pin = 19;
GPIO_Init(&GPIO_InitCfg);
GPIO_InitCfg.Pin = 0;
GPIO_Init(&GPIO_InitCfg);
GPIO_FunSel(3, UART0_TX); // 更换打印口
GPIO_FunSel(2, UART0_RX);
// *((volatile unsigned *)(0x4002F000 + 0x03C)) &= ~(0x1<<14);
adc_cfg.Freq = ADC_FREQ_4M;
adc_cfg.RefVol = ADC_REF_VOL_3_3V;
adc_cfg.SampEdge = ADC_SAMPEDGE_FALL;
adc_cfg.ExtDataMode = ADC_DATA_MODE_32BIT;
adc_cfg.ExtEdgeSel =
ADC_EXT_EDGE_SEL_INTER; // ADC_EXT_EDGE_SEL_EXTERN_RISE //
// ADC_EXT_EDGE_SEL_EXTERN_BOTH
adc_cfg.ExtSampleNum = ADC_SAMPLE_NUM_4;
adc_cfg.ExtTriggerSel = ADC_TRIGGER_SEL_PWM0;
ADC_Init(XC_ADC, &adc_cfg);
__ADC_ChannelSet(XC_ADC, ADC_CHANNEL4_PIN0);
//==================中断设置=========================
ADC_Enable_IT(XC_ADC, ADC_INT_EN_READ_REQ_EN_ENABLE |
ADC_INT_EN_FIFO_ERROR_EN_ENABLE);
NVIC_EnableIRQ(GADC_IRQn);
//===========================================
__ADC_FIFO_ReqIntLenthSet(XC_ADC);
__ADC_FIFO_Flush(XC_ADC);
__ADC_Clear_IT_Flag(XC_ADC);
// ADC DMA enable
// XC_ADC->MAIN_CTL &= ~ADC_MAIN_CTL_DMAS_ON_ENABLE;
// XC_ADC->MAIN_CTL |= ADC_MAIN_CTL_DMAS_ON_ENABLE;
// ADC_DMA_Init();
__ADC_Enable(XC_ADC);
uint32_t val;
ADC_FIFO_TypeDef *fifo_val = NULL;
while (1) {
if (adc_con >= 500 && adc_con != 0xffff) {
fifo_val = (ADC_FIFO_TypeDef *)&val;
for (uint16_t i = 0; i < 500; i++) {
val = adc_val_buff[i];
integer = ((uint32_t)(fifo_val->value_1) * (3.3 * 100)) /
(1.0 * 4095) / 100;
decimal =
((uint32_t)((fifo_val->value_1 * (3.3 * 100)) / 4095) %
100);
DEBUG("i_dex1: %4d ch : %d val: %d adc_vol=%d.%02dV\n", i,
fifo_val->chanel_1, fifo_val->value_1, integer, decimal);
integer = ((uint32_t)(fifo_val->value_2) * (3.3 * 100)) /
(1.0 * 4095) / 100;
decimal =
((uint32_t)((fifo_val->value_2 * (3.3 * 100)) / 4095) %
100);
DEBUG("i_dex2: %4d ch : %d val: %d adc_vol=%d.%02dV\n", i,
fifo_val->chanel_2, fifo_val->value_2, integer, decimal);
if ((i % 2))
DEBUG("\r\n\r\n");
// DEBUG("i_dex: %4d ch : %d val: %d\n",i,
// adc_ch_buff[i],adc_val_buff[i]);
}
adc_con = 0xffff;
}
}
}
/**
* @brief adc_channel_sw_demo
* @details
* @param void
* @retval void
*/
void adc_channelswitch_hw_demo(void)
{
DEBUG("ADC channelswitch hw demo\n");
uint16_t integer;
uint16_t decimal;
adc_cfg adc_cfg;
Delay_Ms(500);
*((volatile unsigned int *)(0x400001BC)) &=
~(1 << 12); // 防止GPIO6被接到运放,导致GADC\上拉无效问题
GPIO_InitTypeDef GPIO_InitCfg = {0};
GPIO_InitCfg.Mux = GPIO_Mux0;
GPIO_InitCfg.FunSel = GPIO_Dx;
GPIO_InitCfg.Pull = GPIO_NOPULL;
// Board Led1 Initialization
GPIO_InitCfg.Dir = GPIO_DIR_INPUT;
GPIO_InitCfg.Int = NOT_INT;
GPIO_InitCfg.Pin = 20;
GPIO_Init(&GPIO_InitCfg);
GPIO_InitCfg.Pin = 18;
GPIO_Init(&GPIO_InitCfg);
GPIO_InitCfg.Pin = 19;
GPIO_Init(&GPIO_InitCfg);
GPIO_InitCfg.Pin = 0;
GPIO_Init(&GPIO_InitCfg);
GPIO_FunSel(3, UART0_TX); // 更换打印口
GPIO_FunSel(2, UART0_RX);
// *((volatile unsigned *)(0x4002F000 + 0x03C)) &= ~(0x1<<14);
adc_cfg.Freq = ADC_FREQ_4M;
adc_cfg.RefVol = ADC_REF_VOL_3_3V;
adc_cfg.SampEdge = ADC_SAMPEDGE_FALL;
adc_cfg.ExtDataMode = ADC_DATA_MODE_32BIT;
adc_cfg.ExtEdgeSel =
ADC_EXT_EDGE_SEL_INTER; // ADC_EXT_EDGE_SEL_EXTERN_RISE //
// ADC_EXT_EDGE_SEL_EXTERN_BOTH
adc_cfg.ExtSampleNum = ADC_SAMPLE_NUM_4;
adc_cfg.ExtTriggerSel = ADC_TRIGGER_SEL_PWM0;
ADC_Init(XC_ADC, &adc_cfg);
XC_ADC->TIMER1 = 62;
XC_ADC->TIMER0 = 1;
//=============设置需要切换的通道(1---4通道,1个bit表示一个通道)=============
XC_ADC->CHAN_CTL &= ~ADC_CHAN_CTL_CHAN_AUTO_Msk;
XC_ADC->CHAN_CTL |= 0xf << 8;
// 使能ADC自动切换
XC_ADC->MAIN_CTL &= ~ADC_MAIN_CTL_AUTO_SW_Msk;
XC_ADC->MAIN_CTL |=
ADC_MAIN_CTL_AUTO_SW_ENABLE; //(ADC_MAIN_CTL_AUTO_SW_ENABLE<<ADC_MAIN_CTL_AUTO_SW_Pos);
//==================中断设置=========================
ADC_Enable_IT(XC_ADC, ADC_INT_EN_READ_REQ_EN_ENABLE |
ADC_INT_EN_FIFO_ERROR_EN_ENABLE);
NVIC_EnableIRQ(GADC_IRQn);
//===========================================
__ADC_FIFO_ReqIntLenthSet(XC_ADC);
__ADC_FIFO_Flush(XC_ADC);
__ADC_Clear_IT_Flag(XC_ADC);
// ADC DMA enable
// XC_ADC->MAIN_CTL &= ~ADC_MAIN_CTL_DMAS_ON_ENABLE;
// XC_ADC->MAIN_CTL |= ADC_MAIN_CTL_DMAS_ON_ENABLE;
// ADC_DMA_Init();
__ADC_Enable(XC_ADC);
uint32_t val;
ADC_FIFO_TypeDef *fifo_val = NULL;
while (1) {
if (adc_con >= 500 && adc_con != 0xffff) {
fifo_val = (ADC_FIFO_TypeDef *)&val;
for (uint16_t i = 0; i < 500; i++) {
val = adc_val_buff[i];
integer = ((uint32_t)(fifo_val->value_1) * (3.3 * 100)) /
(1.0 * 4095) / 100;
decimal =
((uint32_t)((fifo_val->value_1 * (3.3 * 100)) / 4095) %
100);
DEBUG("i_dex1: %4d ch : %d val: %d adc_vol=%d.%02dV\n", i,
fifo_val->chanel_1, fifo_val->value_1, integer, decimal);
integer = ((uint32_t)(fifo_val->value_2) * (3.3 * 100)) /
(1.0 * 4095) / 100;
decimal =
((uint32_t)((fifo_val->value_2 * (3.3 * 100)) / 4095) %
100);
DEBUG("i_dex2: %4d ch : %d val: %d adc_vol=%d.%02dV\n", i,
fifo_val->chanel_2, fifo_val->value_2, integer, decimal);
if ((i % 2))
DEBUG("\r\n\r\n");
// DEBUG("i_dex: %4d ch : %d val: %d\n",i,
// adc_ch_buff[i],adc_val_buff[i]);
}
adc_con = 0xffff;
}
}
}
void ADC_channelswitch_sw_Intr_Callback(void)
{
uint32_t adc_int;
static uint8_t adc_start = 0;
adc_int = XC_ADC->INT;
if (!(adc_int & (ADC_INT_READ_REQ_INT_Msk | ADC_INT_FIFO_ERROR_INT_Msk))) {
return;
}
if (adc_con >= 500) {
//__ADC_Clear_IT_Flag(XC_ADC);
return;
}
//__ADC_Disable(XC_ADC);
__ADC_Clear_IT_Flag(XC_ADC);
if (++adc_start > 3)
adc_start = 0;
switch (adc_start) {
case 0:
__ADC_ChannelSet(XC_ADC, ADC_CHANNEL1_PIN20);
GPIO_Output_Low(1);
GPIO_Output_High(1);
break;
case 1:
__ADC_ChannelSet(XC_ADC, ADC_CHANNEL11_PIN2);
// XC_ADC->MAIN_CTL &= ~ADC_MAIN_CTL_AUTO_SW_Msk;
break;
case 2:
__ADC_ChannelSet(XC_ADC, ADC_CHANNEL4_PIN0);
// XC_ADC->MAIN_CTL &= ~ADC_MAIN_CTL_AUTO_SW_Msk;
break;
case 3:
__ADC_ChannelSet(XC_ADC, ADC_CHANNEL6_PIN4);
// XC_ADC->MAIN_CTL &= ~ADC_MAIN_CTL_AUTO_SW_Msk;
break;
// case 4:
// __ADC_ChannelSet(XC_ADC, ADC_CHANNEL7_PIN5);
// //XC_ADC->MAIN_CTL &= ~ADC_MAIN_CTL_AUTO_SW_Msk;
// break;
//
// case 5:
// __ADC_ChannelSet(XC_ADC, ADC_CHANNEL2_PIN19);
// //XC_ADC->MAIN_CTL &= ~ADC_MAIN_CTL_AUTO_SW_Msk;
// break;
//
// case 6:
// __ADC_ChannelSet(XC_ADC, ADC_CHANNEL3_PIN18);
// //XC_ADC->MAIN_CTL &= ~ADC_MAIN_CTL_AUTO_SW_Msk;
// break;
//
// case 7:
// __ADC_ChannelSet(XC_ADC, ADC_CHANNEL4_PIN0);
// //XC_ADC->MAIN_CTL &= ~ADC_MAIN_CTL_AUTO_SW_Msk;
// break;
}
for (int t = 0; t < ADC_FIFO_CTL_READ_REQ_THRESH_LEN_2; t++) {
// val = XC_ADC->FIFO;
adc_val_buff[adc_con] = XC_ADC->FIFO;
adc_con++;
}
//__ADC_Enable(XC_ADC);
//__ADC_FIFO_Flush(XC_ADC);
//__ADC_Clear_IT_Flag(XC_ADC);
}
void ADC_channelswitch_hw_Intr_Callback(void)
{
uint32_t adc_int;
adc_int = XC_ADC->INT;
if (!(adc_int & (ADC_INT_READ_REQ_INT_Msk | ADC_INT_FIFO_ERROR_INT_Msk))) {
return;
}
if (adc_con >= 500) {
return;
}
//__ADC_Disable(XC_ADC);
__ADC_Clear_IT_Flag(XC_ADC);
for (int t = 0; t < ADC_FIFO_CTL_READ_REQ_THRESH_LEN_2; t++) {
adc_val_buff[adc_con] = XC_ADC->FIFO;
adc_con++;
}
}
// void ADC_Intr_Callback(void)
//{
// ADC_channelswitch_hw_Intr_Callback(); //adc硬件切换
//// ADC_channelswitch_sw_Intr_Callback();//adc软件切换
//// PGA_ADC_Intr_Callback(); //录音pga
//}

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