diff --git a/cpu/soc-x2600/include/ssi.h b/cpu/soc-x2600/include/ssi.h index e2851df9a70c148d8f6dfa783a48b00706aa9055..ac87270b94498e79ce5868b559f8c8218653fe2a 100755 --- a/cpu/soc-x2600/include/ssi.h +++ b/cpu/soc-x2600/include/ssi.h @@ -28,7 +28,7 @@ typedef struct { __IO unsigned long SSIICR; /*!< AES DMA transfer count , , 0x0014 */ __IO unsigned long SSIGR; /*!< AES data input , , 0x0018 */ __IO unsigned long SSIRCNT; /*!< AES data output , , 0x001C */ -} SSI_TypeDef; +} SPI_TypeDef; /********* Register BitField Details: SSIDR BASE+0x0000 *********/ #define SSIDR_D31_D17_Pos (17U) @@ -53,25 +53,25 @@ typedef struct { #define SSIDR_GPC_D16_Msk (0x1UL << SSIDR_GPC_D16_Pos) /*!< 0x00010000 */ #define SSIDR_GPC_D16 SSIDR_GPC_D16_Msk #define SSIDR_GPC_D16_0 (0x1UL << SSIDR_GPC_D16_Pos) /*!< 0x00010000 */ -#define SSIDR_D15_D0_Pos (0U) -#define SSIDR_D15_D0_Msk (0xffffUL << SSIDR_D15_D0_Pos) /*!< 0x0000ffff */ -#define SSIDR_D15_D0 SSIDR_D15_D0_Msk -#define SSIDR_D15_D0_0 (0x1UL << SSIDR_D15_D0_Pos) /*!< 0x00000001 */ -#define SSIDR_D15_D0_1 (0x2UL << SSIDR_D15_D0_Pos) /*!< 0x00000002 */ -#define SSIDR_D15_D0_2 (0x4UL << SSIDR_D15_D0_Pos) /*!< 0x00000004 */ -#define SSIDR_D15_D0_3 (0x8UL << SSIDR_D15_D0_Pos) /*!< 0x00000008 */ -#define SSIDR_D15_D0_4 (0x10UL << SSIDR_D15_D0_Pos) /*!< 0x00000010 */ -#define SSIDR_D15_D0_5 (0x20UL << SSIDR_D15_D0_Pos) /*!< 0x00000020 */ -#define SSIDR_D15_D0_6 (0x40UL << SSIDR_D15_D0_Pos) /*!< 0x00000040 */ -#define SSIDR_D15_D0_7 (0x80UL << SSIDR_D15_D0_Pos) /*!< 0x00000080 */ -#define SSIDR_D15_D0_8 (0x100UL << SSIDR_D15_D0_Pos) /*!< 0x00000100 */ -#define SSIDR_D15_D0_9 (0x200UL << SSIDR_D15_D0_Pos) /*!< 0x00000200 */ -#define SSIDR_D15_D0_10 (0x400UL << SSIDR_D15_D0_Pos) /*!< 0x00000400 */ -#define SSIDR_D15_D0_11 (0x800UL << SSIDR_D15_D0_Pos) /*!< 0x00000800 */ -#define SSIDR_D15_D0_12 (0x1000UL << SSIDR_D15_D0_Pos) /*!< 0x00001000 */ -#define SSIDR_D15_D0_13 (0x2000UL << SSIDR_D15_D0_Pos) /*!< 0x00002000 */ -#define SSIDR_D15_D0_14 (0x4000UL << SSIDR_D15_D0_Pos) /*!< 0x00004000 */ -#define SSIDR_D15_D0_15 (0x8000UL << SSIDR_D15_D0_Pos) /*!< 0x00008000 */ +#define SSIDR_D15_10_Pos (0U) +#define SSIDR_D15_10_Msk (0xffffUL << SSIDR_D15_10_Pos) /*!< 0x0000ffff */ +#define SSIDR_D15_10 SSIDR_D15_10_Msk +#define SSIDR_D15_10_0 (0x1UL << SSIDR_D15_10_Pos) /*!< 0x00000001 */ +#define SSIDR_D15_10_1 (0x2UL << SSIDR_D15_10_Pos) /*!< 0x00000002 */ +#define SSIDR_D15_10_2 (0x4UL << SSIDR_D15_10_Pos) /*!< 0x00000004 */ +#define SSIDR_D15_10_3 (0x8UL << SSIDR_D15_10_Pos) /*!< 0x00000008 */ +#define SSIDR_D15_10_4 (0x10UL << SSIDR_D15_10_Pos) /*!< 0x00000010 */ +#define SSIDR_D15_10_5 (0x20UL << SSIDR_D15_10_Pos) /*!< 0x00000020 */ +#define SSIDR_D15_10_6 (0x40UL << SSIDR_D15_10_Pos) /*!< 0x00000040 */ +#define SSIDR_D15_10_7 (0x80UL << SSIDR_D15_10_Pos) /*!< 0x00000080 */ +#define SSIDR_D15_10_8 (0x100UL << SSIDR_D15_10_Pos) /*!< 0x00000100 */ +#define SSIDR_D15_10_9 (0x200UL << SSIDR_D15_10_Pos) /*!< 0x00000200 */ +#define SSIDR_D15_10_10 (0x400UL << SSIDR_D15_10_Pos) /*!< 0x00000400 */ +#define SSIDR_D15_10_11 (0x800UL << SSIDR_D15_10_Pos) /*!< 0x00000800 */ +#define SSIDR_D15_10_12 (0x1000UL << SSIDR_D15_10_Pos) /*!< 0x00001000 */ +#define SSIDR_D15_10_13 (0x2000UL << SSIDR_D15_10_Pos) /*!< 0x00002000 */ +#define SSIDR_D15_10_14 (0x4000UL << SSIDR_D15_10_Pos) /*!< 0x00004000 */ +#define SSIDR_D15_10_15 (0x8000UL << SSIDR_D15_10_Pos) /*!< 0x00008000 */ /********* Register BitField Details: SSICR0 BASE+0x0004 *********/ #define SSICR0_TENDIAN_Pos (18U) @@ -161,6 +161,10 @@ typedef struct { #define SSICR1_TCKFI SSICR1_TCKFI_Msk #define SSICR1_TCKFI_0 (0x1UL << SSICR1_TCKFI_Pos) /*!< 0x04000000 */ #define SSICR1_TCKFI_1 (0x2UL << SSICR1_TCKFI_Pos) /*!< 0x08000000 */ +#define SSICR1_GPCMD_Pos (25U) +#define SSICR1_GPCMD_Msk (0x1UL << SSICR1_GPCMD_Pos) /*!< 0x02000000 */ +#define SSICR1_GPCMD SSICR1_GPCMD_Msk +#define SSICR1_GPCMD_0 (0x1UL << SSICR1_GPCMD_Pos) /*!< 0x02000000 */ #define SSICR1_ITFRM_Pos (24U) #define SSICR1_ITFRM_Msk (0x1UL << SSICR1_ITFRM_Pos) /*!< 0x01000000 */ #define SSICR1_ITFRM SSICR1_ITFRM_Msk @@ -203,6 +207,10 @@ typedef struct { #define SSICR1_FLEN_2 (0x4UL << SSICR1_FLEN_Pos) /*!< 0x00000020 */ #define SSICR1_FLEN_3 (0x8UL << SSICR1_FLEN_Pos) /*!< 0x00000040 */ #define SSICR1_FLEN_4 (0x10UL << SSICR1_FLEN_Pos) /*!< 0x00000080 */ +#define SSICR1_GPCHL_Pos (2U) +#define SSICR1_GPCHL_Msk (0x1UL << SSICR1_GPCHL_Pos) /*!< 0x00000004 */ +#define SSICR1_GPCHL SSICR1_GPCHL_Msk +#define SSICR1_GPCHL_0 (0x1UL << SSICR1_GPCHL_Pos) /*!< 0x00000004 */ #define SSICR1_PHA_Pos (1U) #define SSICR1_PHA_Msk (0x1UL << SSICR1_PHA_Pos) /*!< 0x00000002 */ #define SSICR1_PHA SSICR1_PHA_Msk @@ -259,35 +267,16 @@ typedef struct { #define SSISR_RFHF_Msk (0x1UL << SSISR_RFHF_Pos) /*!< 0x00000004 */ #define SSISR_RFHF SSISR_RFHF_Msk #define SSISR_RFHF_0 (0x1UL << SSISR_RFHF_Pos) /*!< 0x00000004 */ -#define SSISR_UNDR_Pos (1U) -#define SSISR_UNDR_Msk (0x1UL << SSISR_UNDR_Pos) /*!< 0x00000002 */ -#define SSISR_UNDR SSISR_UNDR_Msk -#define SSISR_UNDR_0 (0x1UL << SSISR_UNDR_Pos) /*!< 0x00000002 */ -#define SSISR_OVER_Pos (0U) -#define SSISR_OVER_Msk (0x1UL << SSISR_OVER_Pos) /*!< 0x00000001 */ -#define SSISR_OVER SSISR_OVER_Msk -#define SSISR_OVER_0 (0x1UL << SSISR_OVER_Pos) /*!< 0x00000001 */ +#define SSISR_TUNDR_Pos (1U) +#define SSISR_TUNDR_Msk (0x1UL << SSISR_TUNDR_Pos) /*!< 0x00000002 */ +#define SSISR_TUNDR SSISR_TUNDR_Msk +#define SSISR_TUNDR_0 (0x1UL << SSISR_TUNDR_Pos) /*!< 0x00000002 */ +#define SSISR_ROVER_Pos (0U) +#define SSISR_ROVER_Msk (0x1UL << SSISR_ROVER_Pos) /*!< 0x00000001 */ +#define SSISR_ROVER SSISR_ROVER_Msk +#define SSISR_ROVER_0 (0x1UL << SSISR_ROVER_Pos) /*!< 0x00000001 */ /********* Register BitField Details: SSIITR BASE+0x0010 *********/ -#define SSIITR_NULL_Pos (16U) -#define SSIITR_NULL_Msk (0xffffUL << SSIITR_NULL_Pos) /*!< 0xffff0000 */ -#define SSIITR_NULL SSIITR_NULL_Msk -#define SSIITR_NULL_0 (0x1UL << SSIITR_NULL_Pos) /*!< 0x00010000 */ -#define SSIITR_NULL_1 (0x2UL << SSIITR_NULL_Pos) /*!< 0x00020000 */ -#define SSIITR_NULL_2 (0x4UL << SSIITR_NULL_Pos) /*!< 0x00040000 */ -#define SSIITR_NULL_3 (0x8UL << SSIITR_NULL_Pos) /*!< 0x00080000 */ -#define SSIITR_NULL_4 (0x10UL << SSIITR_NULL_Pos) /*!< 0x00100000 */ -#define SSIITR_NULL_5 (0x20UL << SSIITR_NULL_Pos) /*!< 0x00200000 */ -#define SSIITR_NULL_6 (0x40UL << SSIITR_NULL_Pos) /*!< 0x00400000 */ -#define SSIITR_NULL_7 (0x80UL << SSIITR_NULL_Pos) /*!< 0x00800000 */ -#define SSIITR_NULL_8 (0x100UL << SSIITR_NULL_Pos) /*!< 0x01000000 */ -#define SSIITR_NULL_9 (0x200UL << SSIITR_NULL_Pos) /*!< 0x02000000 */ -#define SSIITR_NULL_10 (0x400UL << SSIITR_NULL_Pos) /*!< 0x04000000 */ -#define SSIITR_NULL_11 (0x800UL << SSIITR_NULL_Pos) /*!< 0x08000000 */ -#define SSIITR_NULL_12 (0x1000UL << SSIITR_NULL_Pos) /*!< 0x10000000 */ -#define SSIITR_NULL_13 (0x2000UL << SSIITR_NULL_Pos) /*!< 0x20000000 */ -#define SSIITR_NULL_14 (0x4000UL << SSIITR_NULL_Pos) /*!< 0x40000000 */ -#define SSIITR_NULL_15 (0x8000UL << SSIITR_NULL_Pos) /*!< 0x80000000 */ #define SSIITR_CNTCLK_Pos (15U) #define SSIITR_CNTCLK_Msk (0x1UL << SSIITR_CNTCLK_Pos) /*!< 0x00008000 */ #define SSIITR_CNTCLK SSIITR_CNTCLK_Msk @@ -312,33 +301,6 @@ typedef struct { #define SSIITR_IVLTM_14 (0x4000UL << SSIITR_IVLTM_Pos) /*!< 0x00004000 */ /********* Register BitField Details: SSIICR BASE+0x0014 *********/ -#define SSIICR_NULL_Pos (8U) -#define SSIICR_NULL_Msk (0xffffffUL << SSIICR_NULL_Pos) /*!< 0xffffff00 */ -#define SSIICR_NULL SSIICR_NULL_Msk -#define SSIICR_NULL_0 (0x1UL << SSIICR_NULL_Pos) /*!< 0x00000100 */ -#define SSIICR_NULL_1 (0x2UL << SSIICR_NULL_Pos) /*!< 0x00000200 */ -#define SSIICR_NULL_2 (0x4UL << SSIICR_NULL_Pos) /*!< 0x00000400 */ -#define SSIICR_NULL_3 (0x8UL << SSIICR_NULL_Pos) /*!< 0x00000800 */ -#define SSIICR_NULL_4 (0x10UL << SSIICR_NULL_Pos) /*!< 0x00001000 */ -#define SSIICR_NULL_5 (0x20UL << SSIICR_NULL_Pos) /*!< 0x00002000 */ -#define SSIICR_NULL_6 (0x40UL << SSIICR_NULL_Pos) /*!< 0x00004000 */ -#define SSIICR_NULL_7 (0x80UL << SSIICR_NULL_Pos) /*!< 0x00008000 */ -#define SSIICR_NULL_8 (0x100UL << SSIICR_NULL_Pos) /*!< 0x00010000 */ -#define SSIICR_NULL_9 (0x200UL << SSIICR_NULL_Pos) /*!< 0x00020000 */ -#define SSIICR_NULL_10 (0x400UL << SSIICR_NULL_Pos) /*!< 0x00040000 */ -#define SSIICR_NULL_11 (0x800UL << SSIICR_NULL_Pos) /*!< 0x00080000 */ -#define SSIICR_NULL_12 (0x1000UL << SSIICR_NULL_Pos) /*!< 0x00100000 */ -#define SSIICR_NULL_13 (0x2000UL << SSIICR_NULL_Pos) /*!< 0x00200000 */ -#define SSIICR_NULL_14 (0x4000UL << SSIICR_NULL_Pos) /*!< 0x00400000 */ -#define SSIICR_NULL_15 (0x8000UL << SSIICR_NULL_Pos) /*!< 0x00800000 */ -#define SSIICR_NULL_16 (0x10000UL << SSIICR_NULL_Pos) /*!< 0x01000000 */ -#define SSIICR_NULL_17 (0x20000UL << SSIICR_NULL_Pos) /*!< 0x02000000 */ -#define SSIICR_NULL_18 (0x40000UL << SSIICR_NULL_Pos) /*!< 0x04000000 */ -#define SSIICR_NULL_19 (0x80000UL << SSIICR_NULL_Pos) /*!< 0x08000000 */ -#define SSIICR_NULL_20 (0x100000UL << SSIICR_NULL_Pos) /*!< 0x10000000 */ -#define SSIICR_NULL_21 (0x200000UL << SSIICR_NULL_Pos) /*!< 0x20000000 */ -#define SSIICR_NULL_22 (0x400000UL << SSIICR_NULL_Pos) /*!< 0x40000000 */ -#define SSIICR_NULL_23 (0x800000UL << SSIICR_NULL_Pos) /*!< 0x80000000 */ #define SSIICR_ICC_Pos (0U) #define SSIICR_ICC_Msk (0x7UL << SSIICR_ICC_Pos) /*!< 0x00000007 */ #define SSIICR_ICC SSIICR_ICC_Msk @@ -347,25 +309,6 @@ typedef struct { #define SSIICR_ICC_2 (0x4UL << SSIICR_ICC_Pos) /*!< 0x00000004 */ /********* Register BitField Details: SSIGR BASE+0x0018 *********/ -#define SSIGR_NULL_Pos (16U) -#define SSIGR_NULL_Msk (0xffffUL << SSIGR_NULL_Pos) /*!< 0xffff0000 */ -#define SSIGR_NULL SSIGR_NULL_Msk -#define SSIGR_NULL_0 (0x1UL << SSIGR_NULL_Pos) /*!< 0x00010000 */ -#define SSIGR_NULL_1 (0x2UL << SSIGR_NULL_Pos) /*!< 0x00020000 */ -#define SSIGR_NULL_2 (0x4UL << SSIGR_NULL_Pos) /*!< 0x00040000 */ -#define SSIGR_NULL_3 (0x8UL << SSIGR_NULL_Pos) /*!< 0x00080000 */ -#define SSIGR_NULL_4 (0x10UL << SSIGR_NULL_Pos) /*!< 0x00100000 */ -#define SSIGR_NULL_5 (0x20UL << SSIGR_NULL_Pos) /*!< 0x00200000 */ -#define SSIGR_NULL_6 (0x40UL << SSIGR_NULL_Pos) /*!< 0x00400000 */ -#define SSIGR_NULL_7 (0x80UL << SSIGR_NULL_Pos) /*!< 0x00800000 */ -#define SSIGR_NULL_8 (0x100UL << SSIGR_NULL_Pos) /*!< 0x01000000 */ -#define SSIGR_NULL_9 (0x200UL << SSIGR_NULL_Pos) /*!< 0x02000000 */ -#define SSIGR_NULL_10 (0x400UL << SSIGR_NULL_Pos) /*!< 0x04000000 */ -#define SSIGR_NULL_11 (0x800UL << SSIGR_NULL_Pos) /*!< 0x08000000 */ -#define SSIGR_NULL_12 (0x1000UL << SSIGR_NULL_Pos) /*!< 0x10000000 */ -#define SSIGR_NULL_13 (0x2000UL << SSIGR_NULL_Pos) /*!< 0x20000000 */ -#define SSIGR_NULL_14 (0x4000UL << SSIGR_NULL_Pos) /*!< 0x40000000 */ -#define SSIGR_NULL_15 (0x8000UL << SSIGR_NULL_Pos) /*!< 0x80000000 */ #define SSIGR_CGV_Pos (0U) #define SSIGR_CGV_Msk (0xffUL << SSIGR_CGV_Pos) /*!< 0x000000ff */ #define SSIGR_CGV SSIGR_CGV_Msk diff --git a/cpu/soc-x2600/include/x2600.h b/cpu/soc-x2600/include/x2600.h index a878ec46e714b86e4cbd3a87988542a5f2339a58..3753ab6fcbc30a1c2e8d270b214122a66a9a6a5c 100755 --- a/cpu/soc-x2600/include/x2600.h +++ b/cpu/soc-x2600/include/x2600.h @@ -114,8 +114,8 @@ extern "C" { #define TCU1_Instance ((TCU_TypeDef *) (TCU1_BASE)) #define SFC_Instance ((SFC_TypeDef *) (SFC_BASE )) -#define SSI0_Instance ((SSI_TypeDef *) (SSI0_BASE )) -#define SSI1_Instance ((SSI_TypeDef *) (SSI1_BASE )) +#define SSI0_Instance ((SPI_TypeDef *) (SSI0_BASE )) +#define SSI1_Instance ((SPI_TypeDef *) (SSI1_BASE )) #define UART0_Instance ((UART_TypeDef *) (UART0_BASE )) #define UART1_Instance ((UART_TypeDef *) (UART1_BASE )) #define UART2_Instance ((UART_TypeDef *) (UART2_BASE )) @@ -154,8 +154,8 @@ extern "C" { #define TCU0_Instance ((TCU_TypeDef *) (TCU0_BASE | 0xa0000000)) #define TCU1_Instance ((TCU_TypeDef *) (TCU1_BASE | 0xa0000000)) #define SFC_Instance ((SFC_TypeDef *) (SFC_BASE | 0xa0000000)) -#define SSI0_Instance ((SSI_TypeDef *) (SSI0_BASE | 0xa0000000)) -#define SSI1_Instance ((SSI_TypeDef *) (SSI1_BASE | 0xa0000000)) +#define SSI0_Instance ((SPI_TypeDef *) (SSI0_BASE | 0xa0000000)) +#define SSI1_Instance ((SPI_TypeDef *) (SSI1_BASE | 0xa0000000)) #define UART0_Instance ((UART_TypeDef *) (UART0_BASE | 0xa0000000)) #define UART1_Instance ((UART_TypeDef *) (UART1_BASE | 0xa0000000)) #define UART2_Instance ((UART_TypeDef *) (UART2_BASE | 0xa0000000)) diff --git a/drivers/drivers-x2600/ChangeLog b/drivers/drivers-x2600/ChangeLog index 1c91602454ff2d657ae1e9949ff4ca26c8663b44..8d8256e767eb382c4d093065b854766cf95a77ec 100644 --- a/drivers/drivers-x2600/ChangeLog +++ b/drivers/drivers-x2600/ChangeLog @@ -1,3 +1,4 @@ +2023-5-30 支持spi轮询模式、中断模式和dma模式 2023-5-26 支持TFT屏RDMA模式 2023-5-19 支持PWM DMA模式 2023-5-12 支持PWM寄存器模式 PWM DMA模式尚未支持 diff --git a/drivers/drivers-x2600/include/x2600_hal_conf.h b/drivers/drivers-x2600/include/x2600_hal_conf.h index 1d0dfe96f9bea60fa62f472cce35c3020d4f28b0..b6bdc831ff4cd34fc6f280422b7fc9507e3d4bb3 100644 --- a/drivers/drivers-x2600/include/x2600_hal_conf.h +++ b/drivers/drivers-x2600/include/x2600_hal_conf.h @@ -16,9 +16,9 @@ #define HAL_TCU_ENABLED #define HAL_DPU_ENABLED #define HAL_AIC_ENABLED +#define HAL_SPI_ENABLED #if 0 #define HAL_MSC_ENABLED -#define HAL_SPI_ENABLED #define HAL_WDT_ENABLED #define HAL_RTC_ENABLED #define HAL_EFUSE_ENABLED @@ -62,7 +62,7 @@ #endif #ifdef HAL_SPI_ENABLED -#include "x2600_hal_spi.h" +#include "x2600_hal_ssi.h" #endif #ifdef HAL_WDT_ENABLED diff --git a/drivers/drivers-x2600/include/x2600_hal_ssi.h b/drivers/drivers-x2600/include/x2600_hal_ssi.h index ec0cb3c9fb4dc365445233453a17d1636c5d9375..e816aef0c73e68b8219b5ab17b50d7ac77cec2a7 100755 --- a/drivers/drivers-x2600/include/x2600_hal_ssi.h +++ b/drivers/drivers-x2600/include/x2600_hal_ssi.h @@ -15,9 +15,6 @@ #ifndef __X2600_HAL_SSI_H__ #define __X2600_HAL_SSI_H__ -#ifdef __cplusplus - extern "C" { -#endif /** * @addtogroup group_SSI @@ -30,65 +27,509 @@ */ /* 1. 头文件 (Includes)----------------------------------------------- */ -//删除此行,添加内容 -//删除此行,添加内容 +#include "x2600_hal_def.h" + + +#ifdef __cplusplus +extern "C" { +#endif + /* 2. 导出的类型 (Exported Types)--------------------------------------- */ /** * @defgroup SSI_exported_types SSI 导出的类型 (Exported Types) * @{ */ - -// 删除此行, 添加内容 -// 删除此行, 添加内容 +typedef enum { + HAL_SPI_STATE_RESET = 0x00U, /*!< 外围设备未初始化 */ + HAL_SPI_STATE_READY = 0x01U, /*!< 外围设备已经初始化并准备就绪 */ + HAL_SPI_STATE_BUSY = 0x02U, /*!< 内部程序正在进行中 */ + HAL_SPI_STATE_BUSY_TX = 0x03U, /*!< 数据传输过程正在进行 */ + HAL_SPI_STATE_BUSY_RX = 0x04U, /*!< 数据接收过程正在进行 */ + HAL_SPI_STATE_BUSY_TX_RX = 0x05U, /*!< 数据传输和接收正在进行 */ + HAL_SPI_STATE_ERROR = 0x06U, /*!< SPI 错误状态 */ + HAL_SPI_STATE_ABORT = 0x07U /*!< SPI 终止进行中 */ +} HAL_SPI_StateTypeDef; + +/** @defgroup SPI_exported_types_group2 SPI 句柄结构体定义 + * @{ + */ +/** + * @brief SPI 初始化参数 + */ +typedef struct { + uint32_t DataSize; /*!< SPI 字长度 */ + uint32_t TransferEndian; /*!< SPI 发送字节序 */ + uint32_t ReceiveEndian; /*!< SPI 接收字节序 */ + uint32_t FrameVaildLevel; /*!< SPI 帧有效电平 */ + uint32_t CLKPolarity; /*!< SPI 时钟极性 */ + uint32_t CLKPhase; /*!< SPI 时钟相位 */ + uint32_t LoopMode; /*!< SPI Loopback 模式 */ +} SPI_InitTypeDef; + + +/** + * @brief SPI 句柄结构体定义 + */ +typedef struct __SPI_HandleTypeDef { + SPI_TypeDef *Instance; /*!< SPI 寄存器基地址 */ + SPI_InitTypeDef Init; /*!< SPI 初始化参数 */ + + uint8_t *pTxBuffPtr; /*!< 指向SPI Tx缓冲区的指针 */ + uint16_t TxXferSize; /*!< SPI Tx传输大小 */ + __IO uint16_t TxXferCount; /*!< SPI Tx传输计数器 */ + uint8_t *pRxBuffPtr; /*!< 指向SPI Rx缓冲区的指针 */ + uint16_t RxXferSize; /*!< SPI Rx 传输大小 */ + __IO uint16_t RxXferCount; /*!< SPI Rx 传输计数器 */ + void (*RxISR)(struct __SPI_HandleTypeDef *hspi); /*!< Rx函数指针 */ + void (*TxISR)(struct __SPI_HandleTypeDef *hspi); /*!< Tx函数指针 */ + + HAL_LockTypeDef Lock; /*!< 锁资源 */ + __IO HAL_SPI_StateTypeDef State; /*!< SPI 状态 */ + __IO uint32_t ErrorCode; /*!< SPI 错误码 */ + + __IO uint32_t TxTrigger; /*!< SPI Tx阈值(IT) */ + __IO uint32_t RxTrigger; /*!< SPI Rx阈值(IT) */ + DMA_HandleTypeDef *DMA_Handle; + DMA_InitChannelConfTypeDef *SPI_DMA_Tx_Config; + DMA_InitChannelConfTypeDef *SPI_DMA_Rx_Config; + int dma_tx_ch; + int dma_rx_ch; + +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + void (* TxCpltCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI Tx 完成回调 */ + void (* RxCpltCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI Rx 完成回调 */ + void (* TxRxCpltCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI TxRx 完成回调 */ + void (* ErrorCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI 错误回调 */ + void (* MspInitCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI Msp 初始化回调 */ + void (* MspDeInitCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI Msp 取消初始化回调 */ +#endif +} SPI_HandleTypeDef; /** * @} - */ + */ + +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) +/** @defgroup SPI_exported_types_group3 SPI Callback ID 枚举类型定义 + * @{ + */ +typedef enum { + HAL_SPI_TX_COMPLETE_CB_ID = 0x00U, /*!< SPI Tx Completed callback ID */ + HAL_SPI_RX_COMPLETE_CB_ID = 0x01U, /*!< SPI Rx Completed callback ID */ + HAL_SPI_TX_RX_COMPLETE_CB_ID = 0x02U, /*!< SPI TxRx Completed callback ID */ + HAL_SPI_ERROR_CB_ID = 0x03U, /*!< SPI Error callback ID */ + HAL_SPI_MSPINIT_CB_ID = 0x04U, /*!< SPI Msp Init callback ID */ + HAL_SPI_MSPDEINIT_CB_ID = 0x05U /*!< SPI Msp DeInit callback ID */ + +} HAL_SPI_CallbackIDTypeDef; +/** + * @} + */ + +/** @defgroup SPI_exported_types_group4 SPI callback函数类型定义 + * @{ + */ +typedef void (*pSPI_CallbackTypeDef)(SPI_HandleTypeDef *hspi); /*!< 指向SPI callback函数指针 */ +/** + * @} + */ + +#endif +/** + * @} + */ + /* 3. 导出常量定义 Exported Constants ----------------------------------- */ /** * @defgroup SSI_exported_constants SSI 导出的常量 Exported Constants * @{ */ -// 删除此行, 添加内容 -// 删除此行, 添加内容 +#define HAL_SPI_ERROR_NONE (0x00000000U) /*!< 没有错误 */ +#define HAL_SPI_ERROR_DMA (0x00000001U) /*!< DMA传输错误 */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) +#define HAL_SPI_ERROR_INVALID_CALLBACK (0x00000002U) /*!< 无效的回调 */ +#endif +/** + * @} + */ +/** + * @defgroup SPI_exported_constants_group2 SPI 中断使能 + * @{ + */ +#define SPI_IT_TIE (SSICR0_TIE_0) +#define SPI_IT_RIE (SSICR0_RIE_0) +#define SPI_IT_TEIE (SSICR0_TEIE_0) +#define SPI_IT_REIE (SSICR0_REIE_0) /** * @} - */ + */ + +/** + * @defgroup SPI_exported_constants_group3 SPI 中断标志 + * @{ + */ +#define SPI_IT_TX_FLAG (SSISR_TFHE_0) +#define SPI_IT_RX_FLAG (SSISR_RFHF_0) +#define SPI_IT_TX_ERROR_FLAG (SSISR_TUNDR_0) +#define SPI_IT_RX_ERROR_FLAG (SSISR_ROVER_0) +/** + * @} + */ + +/** + * @defgroup SPI_exported_constants_group4 SPI 从帧有效到时钟开始的时间 + * @{ + */ +#define SPI_TFVCK_HALF_OR_1CYCLE (0x00000000U) +#define SPI_TFVCK_1CYCLE (SSICR1_TFVCK_0) +#define SPI_TFVCK_2CYCLE (SSICR1_TFVCK_1) +#define SPI_TFVCK_3CYCLE (SSICR1_TFVCK_1 | SSICR1_TFVCK_0) +/** + * @} + */ + +/** + * @defgroup SPI_exported_constants_group5 SPI 从时钟停止到帧无效的时间 + * @{ + */ +#define SPI_TCKFI_HALF_OR_1CYCLE (0x00000000U) +#define SPI_TCKFI_1CYCLE (SSICR1_TCKFI_0) +#define SPI_TCKFI_2CYCLE (SSICR1_TCKFI_1) +#define SPI_TCKFI_3CYCLE (SSICR1_TCKFI_1 | SSICR1_TCKFI_0) +/** + * @} + */ + +/** + * @defgroup SPI_exported_constants_group6 SPI FIFO阈值和深度 + * @{ + */ +#define SPI_FIFO_MAX_DEPTH 128 +#define SPI_TX_THRESHOLD 8 +#define SPI_RX_THRESHOLD 120 +/** + * @} + */ + +/** + * @defgroup SPI_exported_constants_group7 SPI 字宽 + * @{ + */ +#define SPI_DATASIZE_8BIT (SSICR1_FLEN_1 | SSICR1_FLEN_2) +#define SPI_DATASIZE_16BIT (SSICR1_FLEN_1 | SSICR1_FLEN_2 | SSICR1_FLEN_3) +#define SPI_DATASIZE_32BIT (SSICR1_FLEN_1 | SSICR1_FLEN_2 | SSICR1_FLEN_3 | SSICR1_FLEN_4) +#define SPI_DATASIZE_BIT(bitLength) ((bitLength - 2) << SSICR1_FLEN_Pos) +/** + * @} + */ + +/** @brief SSIDR 寄存器,指向SPI FIFO。 + * @param __HANDLE__ 指定SPI句柄. + * @retval 无 + */ +#define SPI_FIFO(__HANDLE__) (&(__HANDLE__)->Instance->SSIDR) +//#define SPI_FIFO(__HANDLE__) ((__HANDLE__)->Instance->SSIDR) +/** + * @defgroup SPI_exported_constants_group8 SPI 发送字节序 + * @{ + */ +#define SPI_T_MSB_BYTE_MSB_BIT (0x00000000U) +#define SPI_T_MSB_BYTE_LSB_BIT (SSICR0_TENDIAN_0) +#define SPI_T_LSB_BYTE_LSB_BIT (SSICR0_TENDIAN_1) +#define SPI_T_LSB_BYTE_MSB_BIT (SSICR0_TENDIAN_0 | SSICR0_TENDIAN_1) +/** + * @} + */ + +/** + * @defgroup SPI_exported_constants_group9 SPI 接收字节序 + * @{ + */ +#define SPI_R_MSB_BYTE_MSB_BIT (0x00000000U) +#define SPI_R_MSB_BYTE_LSB_BIT (SSICR0_RENDIAN_0) +#define SPI_R_LSB_BYTE_LSB_BIT (SSICR0_RENDIAN_1) +#define SPI_R_LSB_BYTE_MSB_BIT (SSICR0_RENDIAN_0 | SSICR0_RENDIAN_1) +/** + * @} + */ + +/** + * @defgroup SPI_exported_constants_group10 SPI 片选有效电平 + * @{ + */ +#define SPI_CE0_LOW_CE1_LOW (0x00000000U) +#define SPI_CE0_HIGH_CE1_LOW (SSICR1_FRMHL_0) +#define SPI_CE0_LOW_CE1_HIGH (SSICR1_FRMHL_1) +#define SPI_CE0_HIGH_CE1_HIGH (SSICR1_FRMHL_0 | SSICR1_FRMHL_1) +/** + * @} + */ + +/** + * @defgroup SPI_exported_constants_group11 SPI 时钟极性 + * @{ + */ +#define SPI_POLARITY_LOW (0x00000000U) +#define SPI_POLARITY_HIGH SSICR1_POL_0 +/** + * @} + */ + +/** + * @defgroup SPI_exported_constants_group12 SPI 相位 + * @{ + */ +#define SPI_PHASE_1EDGE (0x00000000U) +#define SPI_PHASE_2EDGE SSICR1_PHA_0 +/** + * @} + */ + +/** + * @defgroup SPI_exported_constants_group13 SPI Loopback模式 + * @{ + */ +#define SPI_LOOP_DISABLE (0x00000000U) +#define SPI_LOOP_ENABLE SSICR0_LOOP_0 +/** + * @} + */ +/** + * @} + */ + /* 4. 导出宏定义 Exported Macros --------------------------------------- */ /** * @defgroup SSI_exported_macros SSI 导出宏 Exported Macros * @{ */ - -// 删除此行, 添加内容 -// 删除此行, 添加内容 +/** + * @defgroup SPI_exported_macros_group1 SPI 控制器使能 + * @{ + */ +#define __HAL_SPI_ENABLE(__HANDLE__) SET_BIT((__HANDLE__)->Instance->SSICR0, SSICR0_SSIE_0) +#define __HAL_SPI_DISABLE(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->SSICR0, SSICR0_SSIE_0) +/** + * @} + */ +/** + * @defgroup SPI_exported_macros_group2 SPI standard格式 + * @{ + */ +#define __HAL_SPI_SET_STANDARD_FORMAT(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->SSICR0, SSICR1_FMAT_Msk) +/** + * @} + */ +/** + * @defgroup SPI_exported_macros_group3 SPI 自动清underrun + * @{ + */ +#define __HAL_SPI_AUTO_CLEAR_UNDERUN(__HANDLE__) SET_BIT((__HANDLE__)->Instance->SSICR0, SSICR0_EACLRUN_0) +#define __HAL_SPI_UNAUTO_CLEAR_UNDERUN(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->SSICR0, SSICR0_EACLRUN_0) /** * @} - */ + */ + +/** + * @defgroup SPI_exported_macros_group4 SPI Flush FIFO + * @{ + */ +#define __HAL_SPI_CLEAR_TFIFO(__HANDLE__) SET_BIT((__HANDLE__)->Instance->SSICR0, SSICR0_TFLUSH_0) +#define __HAL_SPI_CLEAR_RFIFO(__HANDLE__) SET_BIT((__HANDLE__)->Instance->SSICR0, SSICR0_RFLUSH_0) +/** + * @} + */ + +/** + * @defgroup SPI_exported_macros_group5 SPI 中断使能 + * @{ + */ +#define __HAL_SPI_ENABLE_IT(__HANDLE__, __INTERRUPT__) SET_BIT((__HANDLE__)->Instance->SSICR0, (__INTERRUPT__)) +#define __HAL_SPI_DISABLE_IT(__HANDLE__, __INTERRUPT__) CLEAR_BIT((__HANDLE__)->Instance->SSICR0, (__INTERRUPT__)) +#define __HAL_SPI_IS_ENABLE_IT(__HANDLE__, __INTERRUPT__) READ_BIT((__HANDLE__)->Instance->SSICR0, (__INTERRUPT__)) +/** + * @} + */ + +/** + * @defgroup SPI_exported_macros_group6 SPI (receive finish)控制 + * @{ + */ +#define __HAL_SPI_ENABLE_RX_FINISH_CONTROL(__HANDLE__) SET_BIT((__HANDLE__)->Instance->SSICR0, SSICR0_RFINE_0) +#define __HAL_SPI_DISABLE_RX_FINISH_CONTROL(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->SSICR0, SSICR0_RFINE_0) +/** + * @} + */ + +/** + * @defgroup SPI_exported_macros_group7 SPI (receive continue)配置 + * @{ + */ +#define __HAL_SPI_SET_RX_CONTINUE(__HANDLE__) SET_BIT((__HANDLE__)->Instance->SSICR0, SSICR0_RFINC_0) +#define __HAL_SPI_CLEAR_RX_CONTINUE(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->SSICR0, SSICR0_RFINC_0) +/** + * @} + */ + +/** + * @defgroup SPI_exported_macros_group8 SPI (receive continue)使能控制 + * @{ + */ +#define __HAL_SPI_RX_COUNTER_VALID(__HANDLE__) SET_BIT((__HANDLE__)->Instance->SSICR0, SSICR0_VRCNT_0) +#define __HAL_SPI_RX_COUNTER_UNVALID(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->SSICR0, SSICR0_VRCNT_0) +/** + * @} + */ + +/** + * @defgroup SPI_exported_macros_group9 SPI TFIFO空模式配置 + * @{ + */ +#define __HAL_SPI_SET_NEW_TFIFO_EMPTY_MODE(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->SSICR0, SSICR0_TFMODE_0) +#define __HAL_SPI_SET_OLD_TFIFO_EMPTY_MODE(__HANDLE__) SET_BIT((__HANDLE__)->Instance->SSICR0, SSICR0_TFMODE_0) +/** + * @} + */ + +/** + * @defgroup SPI_exported_macros_group10 SPI 从帧有效到时钟开始时间配置 + * @{ + */ +#define __HAL_SPI_TFVCLK_DELAY(__HANDLE__, __CYCLE__) MODIFY_REG((__HANDLE__)->Instance->SSICR1, SSICR1_TFVCK_Msk, __CYCLE__) +/** + * @} + */ + +/** + * @defgroup SPI_exported_macros_group11 SPI 从时钟停止到帧无效的时间配置 + * @{ + */ +#define __HAL_SPI_TCKFI_DELAY(__HANDLE__, __CYCLE__) MODIFY_REG((__HANDLE__)->Instance->SSICR1, SSICR1_TCKFI_Msk, __CYCLE__) +/** + * @} + */ + +/** + * @defgroup SPI_exported_macros_group12 SPI 使能接收控制 + * @{ + */ +#define __HAL_SPI_ENABLE_RECEIVE(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->SSICR0, SSICR0_DISREV_0) +#define __HAL_SPI_DISABLE_RECEIVE(__HANDLE__) SET_BIT((__HANDLE__)->Instance->SSICR0, SSICR0_DISREV_0) +/** + * @} + */ + +/** + * @defgroup SPI_exported_macros_group13 SPI (UNFIN)位控制,传输开始和结束控制 + * @{ + */ +#define __HAL_SPI_START_TRANSFER(__HANDLE__) SET_BIT((__HANDLE__)->Instance->SSICR1, SSICR1_UNFIN_0) +#define __HAL_SPI_FINISH_TRANSFER(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->SSICR1, SSICR1_UNFIN_0) +/** + * @} + */ + +/** + * @defgroup SPI_exported_macros_group14 SPI 发送和接收的阈值配置 + * @{ + */ +#define __HAL_SPI_SET_TX_THRESHOLD(__HANDLE__, __THRESHOLD__) MODIFY_REG((__HANDLE__)->Instance->SSICR1, SSICR1_TTRG_Msk, (__THRESHOLD__)/8) +#define __HAL_SPI_SET_RX_THRESHOLD(__HANDLE__, __THRESHOLD__) MODIFY_REG((__HANDLE__)->Instance->SSICR1, SSICR1_RTRG_Msk, (__THRESHOLD__)/8) +/** + * @} + */ + +/** + * @defgroup SPI_exported_macros_group15 SPI 状态相关 + * @{ + */ +#define __HAL_SPI_CLEAR_ERROR(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->SSISR, (SSISR_TUNDR_0 | SSISR_ROVER_0)) +#define __HAL_SPI_TX_FIFO_IS_FULL(__HANDLE__) READ_BIT((__HANDLE__)->Instance->SSISR, SSISR_TFF_Msk) +#define __HAL_SPI_RX_FIFO_IS_EMPTY(__HANDLE__) READ_BIT((__HANDLE__)->Instance->SSISR, SSISR_RFE_Msk) +#define __HAL_SPI_IS_RX_ERROR(__HANDLE__) READ_BIT((__HANDLE__)->Instance->SSISR, SSISR_ROVER_Msk) +#define __HAL_SPI_IS_TX_ERROR(__HANDLE__) READ_BIT((__HANDLE__)->Instance->SSISR, SSISR_TUNDR_Msk) +#define __HAL_SPI_IS_RX_FIFO_HELF_FULL(__HANDLE__) READ_BIT((__HANDLE__)->Instance->SSISR, SSISR_RFHF_0) +#define __HAL_SPI_IS_TX_FIFO_HELF_EMPTY(__HANDLE__) READ_BIT((__HANDLE__)->Instance->SSISR, SSISR_TFHE_0) +#define __HAL_SPI_CLEAR_TX_ERROR(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->SSISR, SSISR_TUNDR_0) +#define __HAL_SPI_CLEAR_RX_ERROR(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->SSISR, SSISR_ROVER_0) +#define __HAL_SPI_GET_STATUS(__HANDLE__) READ_REG((__HANDLE__)->Instance->SSISR) +#define __HAL_SPI_GET_RX_FIFO_NUM(__HANDLE__) (READ_BIT((__HANDLE__)->Instance->SSISR, SSISR_RFIFO_NUM_Msk) >> SSISR_RFIFO_NUM_Pos) +#define __HAL_SPI_GET_TX_FIFO_NUM(__HANDLE__) (READ_BIT((__HANDLE__)->Instance->SSISR, SSISR_TFIFO_NUM_Msk) >> SSISR_TFIFO_NUM_Pos) +/** + * @} + */ + +/** + * @defgroup SPI_exported_macros_group16 SPI 接收计数器配置 + * @{ + */ +#define __HAL_SPI_SET_RX_COUNTER(__HANDLE__, __VALUE__) WRITE_REG((__HANDLE__)->Instance->SSIRCNT, __VALUE__) +/** + * @} + */ +/** + * @} + */ + /* 5. 导出函数申明 Exported Funcs --------------------------------------- */ /** * @defgroup SSI_exported_funcs SSI 导出函数申明 Exported Funcs * @{ */ - -// 删除此行, 添加内容 -// 删除此行, 添加内容 +/** @defgroup SPI_exported_funcs_group1 SPI 初始化函数 + * @{ + */ +HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi); /*!< SPI外围设备初始化 */ +HAL_StatusTypeDef HAL_SPI_DeInit(SPI_HandleTypeDef *hspi); /*!< SPI取消外围设备初始化 */ +void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi); /*!< MCU相关初始化 */ +void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi); /*!< 取消MCU初始化 */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) +HAL_StatusTypeDef HAL_SPI_RegisterCallback(SPI_HandleTypeDef *hspi, + HAL_SPI_CallbackIDTypeDef CallbackID, pSPI_CallbackTypeDef pCallback); /*!< SPI注册回调函数 */ +HAL_StatusTypeDef HAL_SPI_UnRegisterCallback(SPI_HandleTypeDef *hspi, + HAL_SPI_CallbackIDTypeDef CallbackID); /*!< SPI取消注册回调函数 */ +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ /** * @} - */ -/* 6. 导出变量申明 (Exported Variables) --------------------------------- */ + */ + +/** @defgroup SPI_exported_funcs_group2 SPI IO操作相关函数 + * @{ + */ +HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout); /*!< SPI发送数据(Polling) */ +HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout); /*!< SPI接收数据(Polling) */ +HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, + uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout); /*!< SPI全双工发送接收数据(Polling) */ +HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size); /*!< SPI发送数据(IT) */ +HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size); /*!< SPI接收数据(IT) */ +HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, + uint8_t *pTxData, uint8_t *pRxData, uint16_t Size); /*!< SPI全双工发送接收数据(IT) */ +HAL_StatusTypeDef HAL_SPI_DMA_Transmit(SPI_HandleTypeDef *hspi,uint8_t *pData, uint16_t Size); /*!= 0x10) + + +#define IS_SPI_TRANSFER_ENDIAN(__BIT__) (((__BIT__) == SPI_T_MSB_BYTE_MSB_BIT) || \ + ((__BIT__) == SPI_T_MSB_BYTE_LSB_BIT) || \ + ((__BIT__) == SPI_T_LSB_BYTE_LSB_BIT) || \ + ((__BIT__) == SPI_T_LSB_BYTE_MSB_BIT)) + +#define IS_SPI_RECEIVE_ENDIAN(__BIT__) (((__BIT__) == SPI_R_MSB_BYTE_MSB_BIT) || \ + ((__BIT__) == SPI_R_MSB_BYTE_LSB_BIT) || \ + ((__BIT__) == SPI_R_LSB_BYTE_LSB_BIT) || \ + ((__BIT__) == SPI_R_LSB_BYTE_MSB_BIT)) + +#define IS_SPI_FRAME_VALID_LEVEL(__BIT__) (((__BIT__) == SPI_CE0_LOW_CE1_LOW) || \ + ((__BIT__) == SPI_CE0_HIGH_CE1_LOW) || \ + ((__BIT__) == SPI_CE0_LOW_CE1_HIGH) || \ + ((__BIT__) == SPI_CE0_HIGH_CE1_HIGH)) + +#define IS_SPI_CPOL(__CPOL__) (((__CPOL__) == SPI_POLARITY_LOW) || \ + ((__CPOL__) == SPI_POLARITY_HIGH)) + +#define IS_SPI_CPHA(__CPHA__) (((__CPHA__) == SPI_PHASE_1EDGE) || \ + ((__CPHA__) == SPI_PHASE_2EDGE)) +#define IS_SPI_LOOP(__LOOP__) (((__LOOP__) == SPI_LOOP_ENABLE) || \ + ((__LOOP__) == SPI_LOOP_DISABLE)) /** * @} */ diff --git a/drivers/drivers-x2600/include/x2600_ll_cpm.h b/drivers/drivers-x2600/include/x2600_ll_cpm.h index 1a0eeee96815fc9c594e9fb4efaa4c99e47ced6a..2c83d437839cfdbb0123515009947b8f092f35ee 100755 --- a/drivers/drivers-x2600/include/x2600_ll_cpm.h +++ b/drivers/drivers-x2600/include/x2600_ll_cpm.h @@ -303,6 +303,8 @@ HAL_StatusTypeDef CPM_CGU_SADC_Stop(CPM_TypeDef *CPMx); HAL_StatusTypeDef CPM_CGU_LCD_Start(CPM_TypeDef *CPMx, LL_CPM_CGU_ConfigTypeDef *Config); HAL_StatusTypeDef CPM_CGU_LCD_Stop(CPM_TypeDef *CPMx); HAL_StatusTypeDef CPM_CGU_I2S0_Config(CPM_TypeDef *CPMx, LL_CPM_CGU_I2STypeDef *Config); +HAL_StatusTypeDef CPM_CGU_SSI_Start(CPM_TypeDef *CPMx, LL_CPM_CGU_ConfigTypeDef *Config); +HAL_StatusTypeDef CPM_CGU_SSI_Stop(CPM_TypeDef *CPMx); #if 0 HAL_StatusTypeDef CPM_CGU_I2S1_Config(CPM_TypeDef *CPMx, LL_CPM_CGU_I2STypeDef *Config); HAL_StatusTypeDef CPM_CGU_DDR_Start(CPM_TypeDef *CPMx, LL_CPM_CGU_ConfigTypeDef *Config); @@ -315,8 +317,6 @@ HAL_StatusTypeDef CPM_CGU_MSC1_Start(CPM_TypeDef *CPMx, LL_CPM_CGU_ConfigTypeDef HAL_StatusTypeDef CPM_CGU_MSC1_Stop(CPM_TypeDef *CPMx); HAL_StatusTypeDef CPM_CGU_SFC_Start(CPM_TypeDef *CPMx, LL_CPM_CGU_ConfigTypeDef *Config); HAL_StatusTypeDef CPM_CGU_SFC_Stop(CPM_TypeDef *CPMx); -HAL_StatusTypeDef CPM_CGU_SSI_Start(CPM_TypeDef *CPMx, LL_CPM_CGU_ConfigTypeDef *Config); -HAL_StatusTypeDef CPM_CGU_SSI_Stop(CPM_TypeDef *CPMx); HAL_StatusTypeDef CPM_CGU_CIM_Start(CPM_TypeDef *CPMx, LL_CPM_CGU_ConfigTypeDef *Config); HAL_StatusTypeDef CPM_CGU_CIM_Stop(CPM_TypeDef *CPMx); HAL_StatusTypeDef CPM_CGU_CAN0_Start(CPM_TypeDef *CPMx, LL_CPM_CGU_ConfigTypeDef *Config); diff --git a/drivers/drivers-x2600/src/x2600_hal_ssi.c b/drivers/drivers-x2600/src/x2600_hal_ssi.c index 97a48687687ce5506401f7673135be01b53eab7f..8016e67cb980c8142f1e7d31fa1eebd6a76d3060 100755 --- a/drivers/drivers-x2600/src/x2600_hal_ssi.c +++ b/drivers/drivers-x2600/src/x2600_hal_ssi.c @@ -14,16 +14,47 @@ ============================================================================== ##### 使用说明 ##### ============================================================================== - [!!!!删除此内容,添加针对模块的使用方法说明,例如: 配置,启动/停止,状态,重点提醒等等.!!!!] + [特点] + (#) 支持字节序配置. + (#) 支持片选有效电平配置. + (#) 支持全双工发送接收模式. + (#) 支持半双工只发送,只接收模式. + (#) 支持Loopback模式. + (#) 支持Polling、IT模式支持,PDMA模式暂不支持. + (#) 支持SPI最大频率50MHz. + + [Polling模式,快速编程] + (#) 1.使能SPI clock gate. + (#) 2.使能CPM时钟和内部分频. + (#) 3.定义全局SPI句柄,初始化SPI配置. + (#) 4.配置GPIO. + (#) 5.发送或接收数据. + + [IT模式,快速编程] + (#) 1.用户自定义Callback函数. + (#) 2.使能SPI clock gate. + (#) 3.使能CPM时钟和内部分频. + (#) 4.定义全局SPI句柄,初始化SPI配置. + (#) 5.配置GPIO. + (#) 6.请求中断,注册中断处理函数. + (#) 7.发送或接收数据. + (#) 8.等待callback触发,完成数据传输. + + [注意事项] + (#) 1.测试代码可以外部短接mosi和miso,或者设置为Loopback模式. + @endverbatim */ /* 1.头文件 (Includes)------------------------------------------------ */ +#include "x2600_hal.h" /** @addtogroup g_X2600_SSI_HAL_Driver * @{ */ - +#define HAL_SPI_MODULE_ENABLED + +#ifdef HAL_SPI_MODULE_ENABLED /* 2.私有常量定义Private Constants -------------------------------------- */ /** * @addtogroup SSI_private_constants @@ -53,10 +84,7 @@ * @addtogroup SSI_private_macros * @{ */ - -// 删除此行, 添加内容 -// 删除此行, 添加内容 - +#define MIN_T(A,B) (((A)<(B))? (A):(B)) /*!< 取参数中较小值 */ /** * @} */ @@ -77,10 +105,12 @@ * @addtogroup SSI_private_funcs * @{ */ - -// 删除此行, 添加内容 -// 删除此行, 添加内容 - +static void SPI_TxISR_8BIT(struct __SPI_HandleTypeDef *hspi); +static void SPI_TxISR_16BIT(struct __SPI_HandleTypeDef *hspi); +static void SPI_TxISR_32BIT(struct __SPI_HandleTypeDef *hspi); +static void SPI_RxISR_8BIT(struct __SPI_HandleTypeDef *hspi); +static void SPI_RxISR_16BIT(struct __SPI_HandleTypeDef *hspi); +static void SPI_RxISR_32BIT(struct __SPI_HandleTypeDef *hspi); /** * @} */ @@ -89,9 +119,102 @@ * @defgroup SSI_private_funcs_impl SSI 私有函数实现 * @{ */ - -// 删除此行, 添加内容 -// 删除此行, 添加内容 +/** + * @brief 用于接收8bit位宽数据 + * @param 指向包含SPI模块配置信息的SPI_HandleTypeDef结构的hspi指针 + * @retval None + */ +static void SPI_RxISR_8BIT(struct __SPI_HandleTypeDef *hspi) +{ + (*(uint8_t *)hspi->pRxBuffPtr) = (uint8_t)hspi->Instance->SSIDR; + hspi->pRxBuffPtr += sizeof(uint8_t); + hspi->RxXferCount--; +} + +/** + * @brief 用于接收16bit位宽数据 + * @param 指向包含SPI模块配置信息的SPI_HandleTypeDef结构的hspi指针 + * @retval None + */ +static void SPI_RxISR_16BIT(struct __SPI_HandleTypeDef *hspi) +{ + (*(uint16_t *)hspi->pRxBuffPtr) = (uint16_t)hspi->Instance->SSIDR; + hspi->pRxBuffPtr += sizeof(uint16_t); + hspi->RxXferCount--; +} + +/** + * @brief 用于接收32bit位宽数据 + * @param 指向包含SPI模块配置信息的SPI_HandleTypeDef结构的hspi指针 + * @retval None + */ +static void SPI_RxISR_32BIT(struct __SPI_HandleTypeDef *hspi) +{ + (*(uint32_t *)hspi->pRxBuffPtr) = (uint32_t)hspi->Instance->SSIDR; + hspi->pRxBuffPtr += sizeof(uint32_t); + hspi->RxXferCount--; +} + +/** + * @brief 用于适配Alios,接收4-16bit位宽数据位宽数据 + * @param 指向包含SPI模块配置信息的SPI_HandleTypeDef结构的hspi指针 + * @retval Non2e + */ +static void SPI_RxISR_BIT(struct __SPI_HandleTypeDef *hspi) +{ + (*(uint32_t *)hspi->pRxBuffPtr) = (uint32_t)hspi->Instance->SSIDR; + hspi->pRxBuffPtr += sizeof(uint32_t); + hspi->RxXferCount--; +} + +/** + * @brief 用于发送8bit位宽数据 + * @param 指向包含SPI模块配置信息的SPI_HandleTypeDef结构的hspi指针 + * @retval None + */ +static void SPI_TxISR_8BIT(struct __SPI_HandleTypeDef *hspi) +{ + *(__IO uint8_t *)&hspi->Instance->SSIDR = *((uint8_t *)hspi->pTxBuffPtr); + hspi->pTxBuffPtr += sizeof(uint8_t); + hspi->TxXferCount--; +} + +/** + * @brief 用于发送16bit位宽数据 + * @param 指向包含SPI模块配置信息的SPI_HandleTypeDef结构的hspi指针 + * @retval None + */ +static void SPI_TxISR_16BIT(struct __SPI_HandleTypeDef *hspi) +{ + *(__IO uint16_t *)&hspi->Instance->SSIDR = *((uint16_t *)hspi->pTxBuffPtr); + hspi->pTxBuffPtr += sizeof(uint16_t); + hspi->TxXferCount--; +} + +/** + * @brief 用于发送32bit位宽数据 + * @param 指向包含SPI模块配置信息的SPI_HandleTypeDef结构的hspi指针 + * @retval None + */ +static void SPI_TxISR_32BIT(struct __SPI_HandleTypeDef *hspi) +{ + *(__IO uint32_t *)&hspi->Instance->SSIDR = *((uint32_t *)hspi->pTxBuffPtr); + hspi->pTxBuffPtr += sizeof(uint32_t); + hspi->TxXferCount--; +} + +/** + * @brief 用于适配Alios,发送4-16bit位宽数据 + * @param 指向包含SPI模块配置信息的SPI_HandleTypeDef结构的hspi指针 + * @retval None + */ +static void SPI_TxISR_BIT(struct __SPI_HandleTypeDef *hspi) +{ + uint8_t dataSize = (hspi->Init.DataSize >> 3)+2; + *(__IO uint32_t *)&hspi->Instance->SSIDR = *((uint32_t *)hspi->pTxBuffPtr); + hspi->pTxBuffPtr = (void *)(hspi->pTxBuffPtr)+dataSize; + hspi->TxXferCount--; +} /** * @} @@ -101,14 +224,1189 @@ * @defgroup SSI_exported_funcs_impl SSI 导出函数实现 * @{ */ - -// 删除此行, 添加内容 -// 删除此行, 添加内容 +/** + * @brief 初始化 SPI外围设备 + * @param 指向包含SPI模块配置信息的SPI_HandleTypeDef结构的hspi指针 + * @retval HAL 状态 + */ +HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi) +{ + /* 检查分配的SPI句柄 */ + if (hspi == NULL) { + return HAL_ERROR; + } + + /* 检查参数 */ + assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance)); + assert_param(IS_SPI_DATASIZE(hspi->Init.DataSize)); + assert_param(IS_SPI_TRANSFER_ENDIAN(hspi->Init.TransferEndian)); + assert_param(IS_SPI_RECEIVE_ENDIAN(hspi->Init.ReceiveEndian)); + assert_param(IS_SPI_FRAME_VALID_LEVEL(hspi->Init.FrameVaildLevel)); + assert_param(IS_SPI_CPOL(hspi->Init.CLKPolarity)); + assert_param(IS_SPI_CPHA(hspi->Init.CLKPhase)); + assert_param(IS_SPI_LOOP(hspi->Init.LoopMode)); + + if (hspi->State == HAL_SPI_STATE_RESET) { + /* 初始化MCU相关配置 :GPIO, CLOCK, INTC */ +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + hspi->TxCpltCallback = HAL_SPI_TxCpltCallback; + hspi->RxCpltCallback = HAL_SPI_RxCpltCallback; + hspi->TxRxCpltCallback = HAL_SPI_TxRxCpltCallback; + hspi->ErrorCallback = HAL_SPI_ErrorCallback; + + if (hspi->MspInitCallback == NULL) { + hspi->MspInitCallback = HAL_SPI_MspInit; + } + + hspi->MspInitCallback(hspi); +#else + HAL_SPI_MspInit(hspi); +#endif + } + + hspi->State = HAL_SPI_STATE_BUSY; + + /* 禁用所选SPI外围设备 */ + __HAL_SPI_DISABLE(hspi); + + /* 1. 禁用中断 */ + __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TIE | SPI_IT_RIE | SPI_IT_TEIE | SPI_IT_REIE)); + + /* 2. 禁用接收使能 */ + __HAL_SPI_DISABLE_RECEIVE(hspi); + + /* 3. 初始化SPI 协议相关配置 */ + SET_BIT(hspi->Instance->SSICR0, ((hspi->Init.TransferEndian & SSICR0_TENDIAN_Msk) | + (hspi->Init.ReceiveEndian & SSICR0_RENDIAN_Msk) | + (hspi->Init.LoopMode & SSICR0_LOOP_Msk))); + + + WRITE_REG(hspi->Instance->SSICR1, ((hspi->Init.FrameVaildLevel & SSICR1_FRMHL_Msk) | + (hspi->Init.DataSize & SSICR1_FLEN_Msk) | + (hspi->Init.CLKPhase & SSICR1_PHA_Msk) | + (hspi->Init.CLKPolarity & SSICR1_POL_Msk))); + + /* 5. 初始化控制器 */ + __HAL_SPI_SET_STANDARD_FORMAT(hspi); + __HAL_SPI_AUTO_CLEAR_UNDERUN(hspi); + __HAL_SPI_SET_NEW_TFIFO_EMPTY_MODE(hspi); + __HAL_SPI_DISABLE_RX_FINISH_CONTROL(hspi); + __HAL_SPI_SET_RX_CONTINUE(hspi); + __HAL_SPI_RX_COUNTER_UNVALID(hspi); + __HAL_SPI_TFVCLK_DELAY(hspi, SPI_TFVCK_3CYCLE); + + /* 6. 清除FIFO和错误状态 */ + __HAL_SPI_CLEAR_TFIFO(hspi); + __HAL_SPI_CLEAR_RFIFO(hspi); + __HAL_SPI_CLEAR_ERROR(hspi); + + /* 使能所选SPI外围设备 */ + __HAL_SPI_ENABLE(hspi); + + HAL_DMA_Init(hspi->DMA_Handle); + + if (hspi->SPI_DMA_Tx_Config != NULL) { + hspi->dma_tx_ch = HAL_DMA_requestChannel(hspi->DMA_Handle, hspi->SPI_DMA_Tx_Config); + prom_printk("--------------------------->>> %s %d tx ch = %d\n", __func__, __LINE__,hspi->dma_tx_ch); + } + if (hspi->SPI_DMA_Rx_Config != NULL) { + hspi->dma_rx_ch = HAL_DMA_requestChannel(hspi->DMA_Handle, hspi->SPI_DMA_Rx_Config); + prom_printk("--------------------------->>> %s %d rx ch = %d\n", __func__, __LINE__,hspi->dma_rx_ch); + } + __HAL_Lock_Init(&hspi->Lock); + + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->State = HAL_SPI_STATE_READY; + + return HAL_OK; +} /** - * @} - */ + * @brief 取消初始化SPI外围设备 + * @param 指向包含SPI模块配置信息的SPI_HandleTypeDef结构的hspi指针 + * @retval HAL 状态 + */ +HAL_StatusTypeDef HAL_SPI_DeInit(SPI_HandleTypeDef *hspi) +{ + /* 检查分配的SPI句柄 */ + if (hspi == NULL) { + return HAL_ERROR; + } + + /* 检查参数 */ + assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance)); + + hspi->State = HAL_SPI_STATE_BUSY; + + /* 禁用所选SPI外围设备 */ + __HAL_SPI_DISABLE(hspi); + +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + if (hspi->MspDeInitCallback == NULL) { + hspi->MspDeInitCallback = HAL_SPI_MspDeInit; + } + + hspi->MspDeInitCallback(hspi); +#else + HAL_SPI_MspDeInit(hspi); +#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ + + if (hspi->SPI_DMA_Tx_Config != NULL) { + hspi->dma_tx_ch = HAL_DMA_releseChannel(hspi->DMA_Handle, hspi->dma_tx_ch); + } + if (hspi->SPI_DMA_Rx_Config != NULL) { + hspi->dma_rx_ch = HAL_DMA_releseChannel(hspi->DMA_Handle, hspi->dma_rx_ch); + } + HAL_DMA_DeInit(hspi->DMA_Handle); + + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->State = HAL_SPI_STATE_RESET; + + return HAL_OK; +} + +/** + * @brief 初始化 SPI MCU相关配置 + * @param 指向包含SPI模块配置信息的SPI_HandleTypeDef结构的hspi指针 + * @retval None + */ +__weak void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi) +{ + /* 防止未使用的参数编译警告 */ + UNUSED(hspi); + + /* NOTE : 不应修改此函数,当需要回调时,应在用户文件中实现HAL_SPI_MspInit + */ +} + +/** + * @brief 取消初始化 SPI MCU相关配置 + * @param 指向包含SPI模块配置信息的SPI_HandleTypeDef结构的hspi指针 + * @retval None + */ +__weak void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi) +{ + /* 防止未使用的参数编译警告 */ + UNUSED(hspi); + + /* NOTE : 不应修改此函数,当需要回调时,应在用户文件中实现HAL_SPI_MspInit + */ +} + +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) +/** + * @brief 注册要使用的用户SPI回调函数,代替weak函数 + * @param 指向包含指定SPI配置信息的SPI_HandleTypeDef结构的hspi指针 + * @param 要注册的回调的CallbackID + * @param 指向回调函数的pCallback指针 + * @retval HAL 状态 + */ +HAL_StatusTypeDef HAL_SPI_RegisterCallback(SPI_HandleTypeDef *hspi, HAL_SPI_CallbackIDTypeDef CallbackID, + pSPI_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) { + hspi->ErrorCode |= HAL_SPI_ERROR_INVALID_CALLBACK; + return HAL_ERROR; + } + + /* 进程锁定 */ + __HAL_Lock(&hspi->Lock); + + if (HAL_SPI_STATE_READY == hspi->State) { + switch (CallbackID) { + case HAL_SPI_TX_COMPLETE_CB_ID : + hspi->TxCpltCallback = pCallback; + break; + + case HAL_SPI_RX_COMPLETE_CB_ID : + hspi->RxCpltCallback = pCallback; + break; + + case HAL_SPI_TX_RX_COMPLETE_CB_ID : + hspi->TxRxCpltCallback = pCallback; + break; + + case HAL_SPI_MSPINIT_CB_ID : + hspi->MspInitCallback = pCallback; + break; + + case HAL_SPI_MSPDEINIT_CB_ID : + hspi->MspDeInitCallback = pCallback; + break; + + case HAL_SPI_ERROR_CB_ID : + hspi->ErrorCallback = pCallback; + break; + + default : + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK); + status = HAL_ERROR; + break; + } + } else if (HAL_SPI_STATE_RESET == hspi->State) { + switch (CallbackID) { + case HAL_SPI_MSPINIT_CB_ID : + hspi->MspInitCallback = pCallback; + break; + + case HAL_SPI_MSPDEINIT_CB_ID : + hspi->MspDeInitCallback = pCallback; + break; + + default : + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK); + status = HAL_ERROR; + /* Set the transaction information */ + break; + } + } else { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK); + status = HAL_ERROR; + } + + /* 进程解锁 */ + __HAL_UnLock(&hspi->Lock); + + return status; +} + +/** + * @brief 注销SPI回调, SPI回调被重定向到weak函数 + * @param 指向包含指定SPI配置信息的SPI_HandleTypeDef结构的hspi指针 + * @param 要注册的回调的CallbackID + * @param 指向回调函数的pCallback指针 + * @retval HAL 状态 + */ +HAL_StatusTypeDef HAL_SPI_UnRegisterCallback(SPI_HandleTypeDef *hspi, HAL_SPI_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* 进程锁定 */ + __HAL_Lock(&hspi->Lock); + + if (HAL_SPI_STATE_READY == hspi->State) { + switch (CallbackID) { + case HAL_SPI_TX_COMPLETE_CB_ID : + hspi->TxCpltCallback = HAL_SPI_TxCpltCallback; + break; + + case HAL_SPI_RX_COMPLETE_CB_ID : + hspi->RxCpltCallback = HAL_SPI_RxCpltCallback; + break; + + case HAL_SPI_TX_RX_COMPLETE_CB_ID : + hspi->TxRxCpltCallback = HAL_SPI_TxRxCpltCallback; + break; + + case HAL_SPI_MSPINIT_CB_ID : + hspi->MspInitCallback = HAL_SPI_MspInit; + break; + + case HAL_SPI_MSPDEINIT_CB_ID : + hspi->MspDeInitCallback = HAL_SPI_MspDeInit; + break; + + case HAL_SPI_ERROR_CB_ID : + hspi->ErrorCallback = HAL_SPI_ErrorCallback; + break; + + default : + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK); + status = HAL_ERROR; + break; + } + } else if (HAL_SPI_STATE_RESET == hspi->State) { + switch (CallbackID) { + case HAL_SPI_MSPINIT_CB_ID : + hspi->MspInitCallback = HAL_SPI_MspInit; + break; + + case HAL_SPI_MSPDEINIT_CB_ID : + hspi->MspDeInitCallback = HAL_SPI_MspDeInit; + break; + + default : + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK); + status = HAL_ERROR; + break; + } + } else { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK); + status = HAL_ERROR; + } + + /* 进程解锁 */ + __HAL_UnLock(&hspi->Lock); + + return status; +} +#endif + +/** + * @brief 阻塞模式传输批量数据(Polling) + * @param 指向包含指定SPI配置信息的SPI_HandleTypeDef结构的hspi指针 + * @param 指向数据缓冲区的pData指针 + * @param 数据长度 + * @param 超时持续时间 + * @retval HAL 状态 + */ +HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint32_t tickstart; + HAL_StatusTypeDef errorcode = HAL_OK; + + /* 进程锁定 */ + __HAL_Lock(&hspi->Lock); + + tickstart = HAL_GetTick(); + + if (hspi->State != HAL_SPI_STATE_READY) { + errorcode = HAL_BUSY; + goto error; + } + + if ((pData == NULL) || (Size == 0U)) { + errorcode = HAL_ERROR; + goto error; + } + + hspi->State = HAL_SPI_STATE_BUSY_TX; + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->pTxBuffPtr = (uint8_t *)pData; + hspi->TxXferSize = Size; + hspi->TxXferCount = Size; + + hspi->pRxBuffPtr = (uint8_t *)NULL; + hspi->RxXferSize = 0U; + hspi->RxXferCount = 0U; + + if (hspi->Init.DataSize == SPI_DATASIZE_8BIT) { + hspi->TxISR = SPI_TxISR_8BIT; + hspi->RxISR = SPI_RxISR_8BIT; + } else if (hspi->Init.DataSize == SPI_DATASIZE_16BIT) { + hspi->TxISR = SPI_TxISR_16BIT; + hspi->RxISR = SPI_RxISR_16BIT; + } else if (hspi->Init.DataSize == SPI_DATASIZE_32BIT) { + hspi->TxISR = SPI_TxISR_32BIT; + hspi->RxISR = SPI_RxISR_32BIT; + } else { + hspi->TxISR = SPI_TxISR_BIT; + hspi->RxISR = SPI_RxISR_BIT; + } + + __HAL_SPI_CLEAR_TFIFO(hspi); + __HAL_SPI_CLEAR_ERROR(hspi); + __HAL_SPI_DISABLE_RECEIVE(hspi); + __HAL_SPI_START_TRANSFER(hspi); + + while (!(hspi->TxXferCount == 0)) { + if ((hspi->TxXferCount > 0) && !(__HAL_SPI_TX_FIFO_IS_FULL(hspi))) { + hspi->TxISR(hspi); + + /* 传输结束 */ + if (hspi->TxXferCount == 0) { + __HAL_SPI_FINISH_TRANSFER(hspi); + } + + if (__HAL_SPI_IS_TX_ERROR(hspi)) { + __HAL_SPI_CLEAR_TX_ERROR(hspi); + } + } + + /* 超时处理 */ + if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U)) { + errorcode = HAL_TIMEOUT; + goto error; + } + } + + hspi->State = HAL_SPI_STATE_READY; + +error: + __HAL_SPI_CLEAR_ERROR(hspi); + + /* 进程解锁 */ + __HAL_UnLock(&hspi->Lock); + + return errorcode; + +} + +/** + * @brief 阻塞模式接收批量数据(Polling) + * @param 指向包含指定SPI配置信息的SPI_HandleTypeDef结构的hspi指针 + * @param 指向数据缓冲区的pData指针 + * @param 数据长度 + * @param 超时持续时间 + * @retval HAL 状态 + */ +HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint32_t tickstart; + HAL_StatusTypeDef errorcode = HAL_OK; + uint32_t zero = 0; + + /* 进程锁定 */ + __HAL_Lock(&hspi->Lock); + + tickstart = HAL_GetTick(); + + if (!(hspi->State == HAL_SPI_STATE_READY)) { + errorcode = HAL_BUSY; + goto error; + } + + if ((pData == NULL) || (Size == 0U)) { + errorcode = HAL_ERROR; + goto error; + } + + hspi->State = HAL_SPI_STATE_BUSY_RX; + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->pRxBuffPtr = (uint8_t *)pData; + hspi->RxXferCount = Size; + hspi->RxXferSize = Size; + + hspi->pTxBuffPtr = (uint8_t *)&zero; + hspi->TxXferCount = 1U; + hspi->TxXferSize = 1U; + + if (hspi->Init.DataSize == SPI_DATASIZE_8BIT) { + hspi->TxISR = SPI_TxISR_8BIT; + hspi->RxISR = SPI_RxISR_8BIT; + } else if (hspi->Init.DataSize == SPI_DATASIZE_16BIT) { + hspi->TxISR = SPI_TxISR_16BIT; + hspi->RxISR = SPI_RxISR_16BIT; + } else if (hspi->Init.DataSize == SPI_DATASIZE_32BIT) { + hspi->TxISR = SPI_TxISR_32BIT; + hspi->RxISR = SPI_RxISR_32BIT; + } else { + hspi->TxISR = SPI_TxISR_BIT; + hspi->RxISR = SPI_RxISR_BIT; + } + + /* 清状态 */ + __HAL_SPI_CLEAR_TFIFO(hspi); + __HAL_SPI_CLEAR_RFIFO(hspi); + __HAL_SPI_CLEAR_ERROR(hspi); + __HAL_SPI_ENABLE_RECEIVE(hspi); + + /* 只接收模式配置 */ + __HAL_SPI_SET_RX_COUNTER(hspi, Size); + __HAL_SPI_RX_COUNTER_VALID(hspi); /* rcnt enable */ + __HAL_SPI_ENABLE_RX_FINISH_CONTROL(hspi); /* rfine 1 */ + __HAL_SPI_CLEAR_RX_CONTINUE(hspi); /* rfinc 0 */ + + /* 发送1个word数据 */ + __HAL_SPI_START_TRANSFER(hspi); + hspi->TxISR(hspi); + __HAL_SPI_FINISH_TRANSFER(hspi); + + /* 处理underrun状态 */ + if (__HAL_SPI_IS_TX_ERROR(hspi)) { + __HAL_SPI_CLEAR_TX_ERROR(hspi); + } + + /* 产生时钟用于接收数据 */ + while (!(hspi->RxXferCount == 0)) { + if ((hspi->RxXferCount > 0) && !(__HAL_SPI_RX_FIFO_IS_EMPTY(hspi))) { + hspi->RxISR(hspi); + } + + /* 接收完成 */ + if (hspi->RxXferCount == 0) { + __HAL_SPI_SET_RX_CONTINUE(hspi); /* rfinc 1 */ + } + + /* 超时处理 */ + if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U)) { + errorcode = HAL_TIMEOUT; + goto error; + } + } + hspi->State = HAL_SPI_STATE_READY; + +error: + __HAL_SPI_RX_COUNTER_UNVALID(hspi); /* rcnt disable */ + __HAL_SPI_ENABLE_RX_FINISH_CONTROL(hspi); /* rfine 1 */ + __HAL_SPI_SET_RX_CONTINUE(hspi); /* rfinc 1 */ + __HAL_SPI_CLEAR_ERROR(hspi); + + /* 进程解锁 */ + __HAL_UnLock(&hspi->Lock); + return errorcode; +} + +/** + * @brief 阻塞模式传输和接收批量数据(Polling) + * @param 指向包含指定SPI配置信息的SPI_HandleTypeDef结构的hspi指针 + * @param 指向传输数据缓冲区的pTxData指针 + * @param 指向接收数据缓冲区的pRxData指针 + * @param 数据长度 + * @param 超时持续时间 + * @retval HAL 状态 + */ +HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, + uint8_t *pRxData, uint16_t Size, uint32_t Timeout) +{ + uint32_t tickstart; + HAL_StatusTypeDef errorcode = HAL_OK; + + /* 进程锁定 */ + __HAL_Lock(&hspi->Lock); + + if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U)) { + errorcode = HAL_ERROR; + /* Set the transaction information */ + goto error; + } + + tickstart = HAL_GetTick(); + + if (!(hspi->State == HAL_SPI_STATE_READY)) { + errorcode = HAL_BUSY; + goto error; + } + + if (hspi->State != HAL_SPI_STATE_BUSY_RX) { + hspi->State = HAL_SPI_STATE_BUSY_TX_RX; + } + + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->pRxBuffPtr = (uint8_t *)pRxData; + hspi->RxXferCount = Size; + hspi->RxXferSize = Size; + hspi->pTxBuffPtr = (uint8_t *)pTxData; + hspi->TxXferCount = Size; + hspi->TxXferSize = Size; + + if (hspi->Init.DataSize == SPI_DATASIZE_8BIT) { + hspi->TxISR = SPI_TxISR_8BIT; + hspi->RxISR = SPI_RxISR_8BIT; + } else if (hspi->Init.DataSize == SPI_DATASIZE_16BIT) { + hspi->TxISR = SPI_TxISR_16BIT; + hspi->RxISR = SPI_RxISR_16BIT; + } else if (hspi->Init.DataSize == SPI_DATASIZE_32BIT) { + hspi->TxISR = SPI_TxISR_32BIT; + hspi->RxISR = SPI_RxISR_32BIT; + } else { + hspi->TxISR = SPI_TxISR_BIT; + hspi->RxISR = SPI_RxISR_BIT; + } + + __HAL_SPI_CLEAR_TFIFO(hspi); + __HAL_SPI_CLEAR_RFIFO(hspi); + __HAL_SPI_CLEAR_ERROR(hspi); + __HAL_SPI_ENABLE_RECEIVE(hspi); + __HAL_SPI_START_TRANSFER(hspi); + + while (!((hspi->TxXferCount == 0) && (hspi->RxXferCount == 0))) { + if ((hspi->TxXferCount > 0) && !(__HAL_SPI_TX_FIFO_IS_FULL(hspi))) { + hspi->TxISR(hspi); + + /* 手动清underrun */ + if (__HAL_SPI_IS_TX_ERROR(hspi)) { + __HAL_SPI_CLEAR_TX_ERROR(hspi); + } + + /* 传输结束 */ + if (hspi->TxXferCount == 0) { + __HAL_SPI_FINISH_TRANSFER(hspi); + } + } + + if ((hspi->RxXferCount > 0) && !(__HAL_SPI_RX_FIFO_IS_EMPTY(hspi))) { + hspi->RxISR(hspi); + } + + /* 超时处理 */ + if ((((HAL_GetTick() - tickstart) >= Timeout) && ((Timeout != HAL_MAX_DELAY))) || (Timeout == 0U)) { + errorcode = HAL_TIMEOUT; + goto error; + } + } + + if (__HAL_SPI_IS_RX_ERROR(hspi)) { + hspi->State = HAL_SPI_STATE_ERROR; + errorcode = HAL_ERROR; + } + + hspi->State = HAL_SPI_STATE_READY; + +error : + __HAL_SPI_DISABLE_RECEIVE(hspi); + __HAL_SPI_CLEAR_ERROR(hspi); + __HAL_SPI_CLEAR_TFIFO(hspi); + __HAL_SPI_CLEAR_RFIFO(hspi); + + /* 进程解锁 */ + __HAL_UnLock(&hspi->Lock); + + return errorcode; +} + +/** + * @brief 中断模式传输批量数据(IT) + * @param 指向包含指定SPI配置信息的SPI_HandleTypeDef结构的hspi指针 + * @param 指向数据缓冲区的pData指针 + * @param 数据长度 + * @param 超时持续时间 + * @retval HAL 状态 + */ +HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size) +{ + HAL_StatusTypeDef errorcode = HAL_OK; + + __HAL_Lock(&hspi->Lock); + + if ((pData == NULL) || (Size == 0U)) { + errorcode = HAL_ERROR; + goto error; + } + + if (hspi->State != HAL_SPI_STATE_READY) { + errorcode = HAL_BUSY; + goto error; + } + + hspi->State = HAL_SPI_STATE_BUSY_TX; + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->pTxBuffPtr = (uint8_t *)pData; + hspi->TxXferSize = Size; + hspi->TxXferCount = Size; + + hspi->pRxBuffPtr = (uint8_t *)NULL; + hspi->RxXferSize = 0U; + hspi->RxXferCount = 0U; + hspi->RxISR = NULL; + + if (hspi->Init.DataSize == SPI_DATASIZE_8BIT) { + hspi->TxISR = SPI_TxISR_8BIT; + hspi->RxISR = SPI_RxISR_8BIT; + } else if (hspi->Init.DataSize == SPI_DATASIZE_16BIT) { + hspi->TxISR = SPI_TxISR_16BIT; + hspi->RxISR = SPI_RxISR_16BIT; + } else if (hspi->Init.DataSize == SPI_DATASIZE_32BIT) { + hspi->TxISR = SPI_TxISR_32BIT; + hspi->RxISR = SPI_RxISR_32BIT; + } else { + hspi->TxISR = SPI_TxISR_BIT; + hspi->RxISR = SPI_RxISR_BIT; + } + + __HAL_SPI_CLEAR_TFIFO(hspi); + __HAL_SPI_CLEAR_RFIFO(hspi); + __HAL_SPI_CLEAR_ERROR(hspi); + + if (hspi->TxXferCount < SPI_FIFO_MAX_DEPTH) { + /* 发送数据小于TFIFO深度,不启动发送中断 */ + while (hspi->TxXferCount) { + hspi->TxISR(hspi); + } + +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + hspi->TxCpltCallback(hspi); +#else + HAL_SPI_TxCpltCallback(hspi); +#endif + + hspi->State = HAL_SPI_STATE_READY; + + } else { + + /* 设置发送阈值, 并打开发送和发送错误状态中断 */ + hspi->TxTrigger = SPI_TX_THRESHOLD; + __HAL_SPI_SET_TX_THRESHOLD(hspi, hspi->TxTrigger); + + __HAL_SPI_START_TRANSFER(hspi); + __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TIE | SPI_IT_TEIE)); + } + +error: + /* 进程解锁 */ + __HAL_UnLock(&hspi->Lock); + + return errorcode; +} + + +/** + * @brief 中断模式接收批量数据(IT) + * @param 指向包含指定SPI配置信息的SPI_HandleTypeDef结构的hspi指针 + * @param 指向数据缓冲区的pData指针 + * @param 数据长度 + * @param 超时持续时间 + * @retval HAL 状态 + */ +HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size) +{ + HAL_StatusTypeDef errorcode = HAL_OK; + uint32_t zero = 0; + + __HAL_Lock(&hspi->Lock); + + if (hspi->State != HAL_SPI_STATE_READY) { + errorcode = HAL_BUSY; + goto error; + } + + if ((pData == NULL) || (Size == 0U)) { + errorcode = HAL_ERROR; + goto error; + } + + hspi->State = HAL_SPI_STATE_BUSY_RX; + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->pRxBuffPtr = (uint8_t *)pData; + hspi->RxXferSize = Size; + hspi->RxXferCount = Size; + + hspi->pTxBuffPtr = (uint8_t *)&zero; + hspi->TxXferCount = 1U; + hspi->TxXferSize = 1U; + + if (hspi->Init.DataSize == SPI_DATASIZE_8BIT) { + hspi->TxISR = SPI_TxISR_8BIT; + hspi->RxISR = SPI_RxISR_8BIT; + } else if (hspi->Init.DataSize == SPI_DATASIZE_16BIT) { + hspi->TxISR = SPI_TxISR_16BIT; + hspi->RxISR = SPI_RxISR_16BIT; + } else if (hspi->Init.DataSize == SPI_DATASIZE_32BIT) { + hspi->TxISR = SPI_TxISR_32BIT; + hspi->RxISR = SPI_RxISR_32BIT; + } else { + hspi->TxISR = SPI_TxISR_BIT; + hspi->RxISR = SPI_RxISR_BIT; + } + + /* 清状态 */ + __HAL_SPI_CLEAR_TFIFO(hspi); + __HAL_SPI_CLEAR_RFIFO(hspi); + __HAL_SPI_CLEAR_ERROR(hspi); + __HAL_SPI_ENABLE_RECEIVE(hspi); + + /* 只接收模式配置 */ + __HAL_SPI_SET_RX_COUNTER(hspi, Size); + __HAL_SPI_RX_COUNTER_VALID(hspi); /* rcnt enable */ + __HAL_SPI_ENABLE_RX_FINISH_CONTROL(hspi); /* rfine 1 */ + __HAL_SPI_CLEAR_RX_CONTINUE(hspi); /* rfinc 0 */ + + /* 发送1个word数据 */ + __HAL_SPI_START_TRANSFER(hspi); + hspi->TxISR(hspi); + __HAL_SPI_FINISH_TRANSFER(hspi); + + /* 设置接收阈值, 并打开接收和接收错误状态中断 */ + hspi->RxTrigger = SPI_RX_THRESHOLD; + if (hspi->RxXferCount < hspi->RxTrigger) { + hspi->RxTrigger = hspi->RxXferCount; + } + + __HAL_SPI_SET_RX_THRESHOLD(hspi, hspi->RxTrigger); + __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_RIE | SPI_IT_REIE)); + +error: + __HAL_UnLock(&hspi->Lock); + + return errorcode; +} +/** + * @brief 中断模式传输和接收批量数据(IT) + * @param 指向包含指定SPI配置信息的SPI_HandleTypeDef结构的hspi指针 + * @param 指向传输数据缓冲区的pTxData指针 + * @param 指向接收数据缓冲区的pRxData指针 + * @param 数据长度 + * @param 超时持续时间 + * @retval HAL 状态 + */ +HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size) +{ + HAL_StatusTypeDef errorcode = HAL_OK; + + __HAL_Lock(&hspi->Lock); + + if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U)) { + errorcode = HAL_ERROR; + goto error; + } + + if (!(hspi->State == HAL_SPI_STATE_READY)) { + errorcode = HAL_BUSY; + goto error; + } + + if (hspi->State != HAL_SPI_STATE_BUSY_RX) { + hspi->State = HAL_SPI_STATE_BUSY_TX_RX; + } + + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->pTxBuffPtr = (uint8_t *)pTxData; + hspi->TxXferSize = Size; + hspi->TxXferCount = Size; + hspi->pRxBuffPtr = (uint8_t *)pRxData; + hspi->RxXferSize = Size; + hspi->RxXferCount = Size; + + if (hspi->Init.DataSize == SPI_DATASIZE_8BIT) { + hspi->TxISR = SPI_TxISR_8BIT; + hspi->RxISR = SPI_RxISR_8BIT; + } else if (hspi->Init.DataSize == SPI_DATASIZE_16BIT) { + hspi->TxISR = SPI_TxISR_16BIT; + hspi->RxISR = SPI_RxISR_16BIT; + } else if (hspi->Init.DataSize == SPI_DATASIZE_32BIT) { + hspi->TxISR = SPI_TxISR_32BIT; + hspi->RxISR = SPI_RxISR_32BIT; + } else { + hspi->TxISR = SPI_TxISR_BIT; + hspi->RxISR = SPI_RxISR_BIT; + } + + __HAL_SPI_CLEAR_TFIFO(hspi); + __HAL_SPI_CLEAR_RFIFO(hspi); + __HAL_SPI_CLEAR_ERROR(hspi); + __HAL_SPI_ENABLE_RECEIVE(hspi); + + if (hspi->TxXferCount < SPI_FIFO_MAX_DEPTH) { + /* 发送数据小于TFIFO深度,不启动发送中断 */ + while (hspi->TxXferCount) { + hspi->TxISR(hspi); + } + + /* 设置接收阈值, 并打开接收和接收错误状态中断 */ + hspi->RxTrigger = SPI_RX_THRESHOLD; + if (hspi->RxXferCount < hspi->RxTrigger) { + hspi->RxTrigger = hspi->RxXferCount; + } + + __HAL_SPI_SET_RX_THRESHOLD(hspi, hspi->RxTrigger); + __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_RIE | SPI_IT_REIE)); + + } else { + /* 设置发送和接收阈值, 并打开所有中断 */ + hspi->RxTrigger = SPI_RX_THRESHOLD; + hspi->RxTrigger = SPI_RX_THRESHOLD; + hspi->TxTrigger = SPI_TX_THRESHOLD; + __HAL_SPI_SET_RX_THRESHOLD(hspi, hspi->RxTrigger); + __HAL_SPI_SET_TX_THRESHOLD(hspi, hspi->TxTrigger); + __HAL_SPI_START_TRANSFER(hspi); + __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TIE | SPI_IT_RIE | SPI_IT_TEIE | SPI_IT_REIE)); + } + +error: + __HAL_UnLock(&hspi->Lock); + return errorcode; +} +HAL_StatusTypeDef HAL_SPI_DMA_Transmit(SPI_HandleTypeDef *hspi,uint8_t *pData, uint16_t Size) +{ + HAL_StatusTypeDef errorcode = HAL_OK; + __HAL_Lock(&hspi->Lock); + + if ((pData == NULL) || (Size == 0U)) { + errorcode = HAL_ERROR; + goto error; + } + + if (hspi->State != HAL_SPI_STATE_READY) { + errorcode = HAL_BUSY; + goto error; + } + + hspi->State = HAL_SPI_STATE_BUSY_TX; + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->pTxBuffPtr = (uint8_t *)pData; + hspi->TxXferSize = Size; + hspi->TxXferCount = Size; + + hspi->pRxBuffPtr = (uint8_t *)NULL; + hspi->RxXferSize = 0U; + hspi->RxXferCount = 0U; + + __HAL_SPI_CLEAR_TFIFO(hspi); + __HAL_SPI_CLEAR_RFIFO(hspi); + __HAL_SPI_CLEAR_ERROR(hspi); + + hspi->TxTrigger = 1; + __HAL_SPI_SET_TX_THRESHOLD(hspi, hspi->TxTrigger); + + + __HAL_SPI_ENABLE_IT(hspi, SPI_IT_TEIE); + + HAL_DMA_Start(hspi->DMA_Handle, hspi->SPI_DMA_Tx_Config->Channel); + + hspi->State = HAL_SPI_STATE_READY; +#if 0 + if(HAL_SPI_STATE_ABORT) + return HAL_OK; + else + return HAL_BUSY; +#endif +error: + __HAL_SPI_CLEAR_ERROR(hspi); + + /* 进程解锁 */ + __HAL_UnLock(&hspi->Lock); + + return errorcode; + +} + +HAL_StatusTypeDef HAL_SPI_DMA_Receive(SPI_HandleTypeDef *hspi,uint8_t *pData, uint16_t Size) +{ + HAL_StatusTypeDef errorcode = HAL_OK; + uint32_t zero = 0; + __HAL_Lock(&hspi->Lock); + + if ((pData == NULL) || (Size == 0U)) { + errorcode = HAL_ERROR; + goto error; + } + + if (hspi->State != HAL_SPI_STATE_READY) { + errorcode = HAL_BUSY; + goto error; + } + hspi->State = HAL_SPI_STATE_BUSY_RX; + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->pRxBuffPtr = (uint8_t *)pData; + hspi->RxXferSize = Size; + hspi->RxXferCount = Size; + + hspi->pTxBuffPtr = (uint8_t *)&zero; + hspi->TxXferCount = 1U; + hspi->TxXferSize = 1U; + + /* 清状态 */ + __HAL_SPI_CLEAR_TFIFO(hspi); + __HAL_SPI_CLEAR_RFIFO(hspi); + __HAL_SPI_CLEAR_ERROR(hspi); + __HAL_SPI_ENABLE_RECEIVE(hspi); + + /* 只接收模式配置 */ + __HAL_SPI_SET_RX_COUNTER(hspi, Size); + __HAL_SPI_RX_COUNTER_VALID(hspi); /* rcnt enable */ + __HAL_SPI_ENABLE_RX_FINISH_CONTROL(hspi); /* rfine 1 */ + __HAL_SPI_CLEAR_RX_CONTINUE(hspi); /* rfinc 0 */ + + /* 发送1个word数据 */ + __HAL_SPI_START_TRANSFER(hspi); + + __HAL_SPI_FINISH_TRANSFER(hspi); + + /* 设置接收阈值, 并打开接收和接收错误状态中断 */ + hspi->RxTrigger = 1; + __HAL_SPI_SET_TX_THRESHOLD(hspi, hspi->RxTrigger); + + + __HAL_SPI_ENABLE_IT(hspi, SPI_IT_REIE); + + HAL_DMA_Start(hspi->DMA_Handle, hspi->SPI_DMA_Rx_Config->Channel); + + hspi->State = HAL_SPI_STATE_READY; +#if 0 + if(HAL_SPI_STATE_ABORT) + return HAL_OK; + else + return HAL_BUSY; +#endif +error: + __HAL_SPI_CLEAR_ERROR(hspi); + + /* 进程解锁 */ + __HAL_UnLock(&hspi->Lock); + + return errorcode; + +} +HAL_StatusTypeDef HAL_SPI_DMA_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size) +{ + HAL_StatusTypeDef errorcode = HAL_OK; + __HAL_Lock(&hspi->Lock); + + if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U)) { + errorcode = HAL_ERROR; + goto error; + } + if (!(hspi->State == HAL_SPI_STATE_READY)) { + errorcode = HAL_BUSY; + goto error; + } + if (hspi->State != HAL_SPI_STATE_BUSY_RX) { + hspi->State = HAL_SPI_STATE_BUSY_TX_RX; + } + hspi->ErrorCode = HAL_SPI_ERROR_NONE; + hspi->pTxBuffPtr = (uint8_t *)pTxData; + hspi->TxXferSize = Size; + hspi->TxXferCount = Size; + hspi->pRxBuffPtr = (uint8_t *)pRxData; + hspi->RxXferSize = Size; + hspi->RxXferCount = Size; + + __HAL_SPI_CLEAR_TFIFO(hspi); + __HAL_SPI_CLEAR_RFIFO(hspi); + __HAL_SPI_CLEAR_ERROR(hspi); + __HAL_SPI_ENABLE_RECEIVE(hspi); + + /* 设置发送和接收阈值, 并打开所有中断 */ + hspi->RxTrigger = 1; + hspi->TxTrigger = 1; + + __HAL_SPI_SET_RX_THRESHOLD(hspi, hspi->RxTrigger); + __HAL_SPI_SET_TX_THRESHOLD(hspi, hspi->TxTrigger); + __HAL_SPI_FINISH_TRANSFER(hspi); + __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TEIE | SPI_IT_REIE)); + + HAL_DMA_Start(hspi->DMA_Handle, hspi->SPI_DMA_Rx_Config->Channel); + HAL_DMA_Start(hspi->DMA_Handle, hspi->SPI_DMA_Tx_Config->Channel); + hspi->State = HAL_SPI_STATE_READY; +error: + __HAL_UnLock(&hspi->Lock); + return errorcode; +} +/** + * @brief SPI中断处理函数 + * @param 中断号irq + * @param 外部参数data + * @retval None + */ +void HAL_SPI_IRQHandler(int irq, void *data) +{ + SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)data; + + if (__HAL_SPI_IS_TX_ERROR(hspi) && __HAL_SPI_IS_ENABLE_IT(hspi, SPI_IT_TEIE)) { + __HAL_SPI_CLEAR_TX_ERROR(hspi); + __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TEIE); + prom_printk("underrun!\n"); + } + + if (__HAL_SPI_IS_RX_ERROR(hspi) && __HAL_SPI_IS_ENABLE_IT(hspi, SPI_IT_REIE)) { + prom_printk("overrun!\n"); + __HAL_SPI_DISABLE_IT(hspi, SPI_IT_REIE); + } + + if (__HAL_SPI_IS_RX_FIFO_HELF_FULL(hspi) && __HAL_SPI_IS_ENABLE_IT(hspi, SPI_IT_RIE)) { + if (hspi->RxXferCount > 0) { + uint32_t r_entries = __HAL_SPI_GET_RX_FIFO_NUM(hspi); + + while (r_entries--) { + hspi->RxISR(hspi); + } + } + + if (hspi->RxXferCount == 0) { + __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RIE | SPI_IT_REIE)); + } else if (hspi->RxXferCount < hspi->RxTrigger) { + hspi->RxTrigger = hspi->RxXferCount; + __HAL_SPI_SET_RX_THRESHOLD(hspi, hspi->RxTrigger); + } + } + + if (__HAL_SPI_IS_TX_FIFO_HELF_EMPTY(hspi) && __HAL_SPI_IS_ENABLE_IT(hspi, SPI_IT_TIE)) { + if (hspi->TxXferCount > 0) { + uint32_t w_entries = SPI_FIFO_MAX_DEPTH - __HAL_SPI_GET_TX_FIFO_NUM(hspi); + + w_entries = MIN_T(hspi->TxXferCount, w_entries); + + while (w_entries--) { + hspi->TxISR(hspi); + } + } + + if (hspi->TxXferCount == 0) { + __HAL_SPI_FINISH_TRANSFER(hspi); + __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TIE | SPI_IT_TEIE)); + __HAL_SPI_CLEAR_TX_ERROR(hspi); + } + } + + + /* 传输和接收完成 */ + if ((hspi->RxXferCount == 0) && (hspi->TxXferCount == 0)) { + /* 屏蔽所以中断,清状态 */ + __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RIE | SPI_IT_REIE | SPI_IT_TIE | SPI_IT_TEIE)); + __HAL_SPI_RX_COUNTER_UNVALID(hspi); /* rcnt disable */ + __HAL_SPI_ENABLE_RX_FINISH_CONTROL(hspi); /* rfine 1 */ + __HAL_SPI_SET_RX_CONTINUE(hspi); /* rfinc 1 */ + __HAL_SPI_CLEAR_ERROR(hspi); + + /* 调用Callback函数 */ + if (hspi->State == HAL_SPI_STATE_BUSY_TX) { +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + hspi->TxCpltCallback(hspi); +#else + HAL_SPI_TxCpltCallback(hspi); +#endif + } else if (hspi->State == HAL_SPI_STATE_BUSY_RX) { +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + hspi->RxCpltCallback(hspi); +#else + HAL_SPI_RxCpltCallback(hspi); +#endif + } else if (hspi->State == HAL_SPI_STATE_BUSY_TX_RX) { +#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) + hspi->TxRxCpltCallback(hspi); +#else + HAL_SPI_TxRxCpltCallback(hspi); +#endif + } + + hspi->State = HAL_SPI_STATE_READY; + } +} + +/** + * @brief 完成SPI数据发送调用的回调函数 + * @param 指向包含SPI模块配置信息的SPI_HandleTypeDef结构的hspi指针 + * @retval None + */ +__weak void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) +{ + /* 防止未使用的参数编译警告 */ + UNUSED(hspi); + /* NOTE : 不应修改此函数,当需要回调时,应在用户文件中实现HAL_SPI_MspInit */ +} + +/** + * @brief 完成SPI数据接收调用的回调函数 + * @param 指向包含SPI模块配置信息的SPI_HandleTypeDef结构的hspi指针 + * @retval None + */ +__weak void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) +{ + /* 防止未使用的参数编译警告 */ + UNUSED(hspi); + /* NOTE : 不应修改此函数,当需要回调时,应在用户文件中实现HAL_SPI_MspInit */ +} + +/** + * @brief 完成SPI数据发送和接收调用的回调函数 + * @param 指向包含SPI模块配置信息的SPI_HandleTypeDef结构的hspi指针 + * @retval None + */ +__weak void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) +{ + /* 防止未使用的参数编译警告 */ + UNUSED(hspi); + /* NOTE : 不应修改此函数,当需要回调时,应在用户文件中实现HAL_SPI_MspInit */ +} + +/** + * @brief SPI发生错误状态调用的回调函数 + * @param 指向包含SPI模块配置信息的SPI_HandleTypeDef结构的hspi指针 + * @retval None + */ +__weak void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi) +{ + /* 防止未使用的参数编译警告 */ + UNUSED(hspi); + /* NOTE : 不应修改此函数,当需要回调时,应在用户文件中实现HAL_SPI_MspInit */ +} /** * @} - */ + */ +#endif /* HAL_SPI_MODULE_ENABLED */ +/** + * @} + */ diff --git a/drivers/drivers-x2600/src/x2600_ll_cpm.c b/drivers/drivers-x2600/src/x2600_ll_cpm.c index 34709a9d6960be9f00d6a0d0bf910fb0262e3cfb..c714aceaeaf6a4bc3c5e0a7e20dd567b5d64cead 100755 --- a/drivers/drivers-x2600/src/x2600_ll_cpm.c +++ b/drivers/drivers-x2600/src/x2600_ll_cpm.c @@ -575,81 +575,6 @@ HAL_StatusTypeDef CPM_CGU_SFC_Stop(CPM_TypeDef *CPMx) return HAL_OK; } - -/** - * @brief 配置SSICGU时钟分频比,并打开时钟 - * @param CPMx: 指向CPMx的基地址 - * @param Config: 描述配置内容 - * @retval HAL Status. - */ - -HAL_StatusTypeDef CPM_CGU_SSI_Start(CPM_TypeDef *CPMx, LL_CPM_CGU_ConfigTypeDef *Config) -{ - uint32_t val; - uint32_t config; - uint32_t count; - /* 参数检查 */ - assert_param(IS_CPM_INSTALL(CPMx)); - assert_param(IS_SSICDR_CONFIG(Config->Config)); - assert_param(IS_SSICDR_DIV(Config->Div)); - assert_param(IS_SSICDR_PLLMUX(Config->PLLMux)); - /* 读取SSICDR寄存器值*/ - val = READ_REG(CPMx->SSICDR); - val |= SSICDR_CE_SSI; - /* 如果已打开时钟,先关闭时钟*/ - if (val & SSICDR_SSI_STOP_Msk) { - val |= SSICDR_SSI_STOP; - WRITE_REG(CPMx->SSICDR, val); - count = SystemCoreClock / 8U / 1000U * 8; - /*等待BUSY. */ - while (--count && (READ_REG(CPMx->SSICDR) & SSICDR_SSI_BUSY)); - if (count == 0) { - return HAL_TIMEOUT; - } - } - /* 重新配时钟,并打开时钟*/ - config = Config->Div | Config->PLLMux | Config->Config; - WRITE_REG(CPMx->SSICDR, config | SSICDR_CE_SSI); - count = SystemCoreClock / 8U / 1000U * 8; - /* 等待时钟稳定 */ - while (--count && (READ_REG(CPMx->SSICDR) & SSICDR_SSI_BUSY)); - if (count == 0) { - return HAL_TIMEOUT; - } - /* 去掉CE_ENABLE.保护防止误操作 */ - WRITE_REG(CPMx->SSICDR, config); - return HAL_OK; -} - -/** - * @brief 停止SSICGU的时钟 - * @param CPMx: 指向CPMx的基地址 - * @retval HAL Status. - */ - -HAL_StatusTypeDef CPM_CGU_SSI_Stop(CPM_TypeDef *CPMx) -{ - uint32_t val; - uint32_t count; - /* 参数检查 */ - assert_param(IS_CPM_INSTALL(CPMx)); - /* 读取SSICDR寄存器值*/ - val = READ_REG(CPMx->SSICDR); - /* 使能CE_ENABLE */ - val |= SSICDR_CE_SSI; - /* 如果已打开时钟,才关闭时钟*/ - if (val & SSICDR_SSI_STOP_Msk) { - val |= SSICDR_SSI_STOP; - WRITE_REG(CPMx->SSICDR, val); - count = SystemCoreClock / 8U / 1000U * 8; - while (--count && (READ_REG(CPMx->SSICDR) & SSICDR_SSI_BUSY)); - if (count == 0) { - return HAL_TIMEOUT; - } - } - return HAL_OK; -} - /** * @brief 配置CIMCGU时钟分频比,并打开时钟 * @param CPMx: 指向CPMx的基地址 @@ -1075,6 +1000,79 @@ HAL_StatusTypeDef CPM_CGU_PWM_Stop(CPM_TypeDef *CPMx) return HAL_OK; } +/** + * @brief 配置SSICGU时钟分频比,并打开时钟 + * @param CPMx: 指向CPMx的基地址 + * @param Config: 描述配置内容 + * @retval HAL Status. + */ + +HAL_StatusTypeDef CPM_CGU_SSI_Start(CPM_TypeDef *CPMx, LL_CPM_CGU_ConfigTypeDef *Config) +{ + uint32_t val; + uint32_t config; + uint32_t count; + /* 参数检查 */ + assert_param(IS_CPM_INSTALL(CPMx)); + assert_param(IS_SSICDR_CONFIG(Config->Config)); + assert_param(IS_SSICDR_DIV(Config->Div)); + assert_param(IS_SSICDR_PLLMUX(Config->PLLMux)); + /* 读取SSICDR寄存器值*/ + val = READ_REG(CPMx->SSICDR); + val |= SSICDR_CE_SSI; + /* 如果已打开时钟,先关闭时钟*/ + if (val & SSICDR_SSI_STOP_Msk) { + val |= SSICDR_SSI_STOP; + WRITE_REG(CPMx->SSICDR, val); + count = SystemCoreClock / 8U / 1000U * 8; + /*等待BUSY. */ + while (--count && (READ_REG(CPMx->SSICDR) & SSICDR_SSI_BUSY)); + if (count == 0) { + return HAL_TIMEOUT; + } + } + /* 重新配时钟,并打开时钟*/ + config = Config->Div | Config->PLLMux | Config->Config; + WRITE_REG(CPMx->SSICDR, config | SSICDR_CE_SSI); + count = SystemCoreClock / 8U / 1000U * 8; + /* 等待时钟稳定 */ + while (--count && (READ_REG(CPMx->SSICDR) & SSICDR_SSI_BUSY)); + if (count == 0) { + return HAL_TIMEOUT; + } + /* 去掉CE_ENABLE.保护防止误操作 */ + WRITE_REG(CPMx->SSICDR, config); + return HAL_OK; +} + +/** + * @brief 停止SSICGU的时钟 + * @param CPMx: 指向CPMx的基地址 + * @retval HAL Status. + */ + +HAL_StatusTypeDef CPM_CGU_SSI_Stop(CPM_TypeDef *CPMx) +{ + uint32_t val; + uint32_t count; + /* 参数检查 */ + assert_param(IS_CPM_INSTALL(CPMx)); + /* 读取SSICDR寄存器值*/ + val = READ_REG(CPMx->SSICDR); + /* 使能CE_ENABLE */ + val |= SSICDR_CE_SSI; + /* 如果已打开时钟,才关闭时钟*/ + if (val & SSICDR_SSI_STOP_Msk) { + val |= SSICDR_SSI_STOP; + WRITE_REG(CPMx->SSICDR, val); + count = SystemCoreClock / 8U / 1000U * 8; + while (--count && (READ_REG(CPMx->SSICDR) & SSICDR_SSI_BUSY)); + if (count == 0) { + return HAL_TIMEOUT; + } + } + return HAL_OK; +} /** * @brief 打开设备寄存器时钟 diff --git a/projects/x2660-halley/Examples/spi/spi_fullduplex_dma/CMakeLists.txt b/projects/x2660-halley/Examples/spi/spi_fullduplex_dma/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..481bb5706d6f0c7c48738ce93181aa58883b3ec1 --- /dev/null +++ b/projects/x2660-halley/Examples/spi/spi_fullduplex_dma/CMakeLists.txt @@ -0,0 +1,113 @@ +cmake_minimum_required(VERSION 3.8) +# +# Core project settings +# +Project(ssi_dma) # Modified +enable_language(C CXX ASM) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +# Setup compiler settings +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_C_EXTENSIONS ON) +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS ON) +set(PROJ_PATH ${CMAKE_CURRENT_SOURCE_DIR}) +set(SDK_PATH ${PROJ_PATH}/../../../../../) +message("Build type: " ${CMAKE_BUILD_TYPE}) + +# Set linker script +set(linker_script_SRC ${SDK_PATH}/cpu/core-riscv/ld.lds) # Modified +set(EXECUTABLE ${CMAKE_PROJECT_NAME}) +set(CPU_PARAMETERS "-march=rv32imc -mabi=ilp32 -Wno-abi") + +set(CMAKE_ASM_FLAGS "${CPU_PARAMETERS} -D_ASSEMBLER_ -D__ASSEMBLY__") + +set(CMAKE_C_FLAGS "${CPU_PARAMETERS} -fno-pic -fno-builtin -fomit-frame-pointer -Wall -nostdlib -Wall -fdata-sections -ffunction-sections") + +# Compiler options + +if(CMAKE_BUILD_TYPE STREQUAL Debug) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -g -ggdb -DDEBUG") +else() + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2") +endif() + +set(CMAKE_CXX_FLAGS ${CMAKE_C_FLAGS}) + +set(CMAKE_LD_FLAGS "${CPU_PARAMETERS}") + + +set(sources_SRCS # Modified + ${SDK_PATH}/cpu/core-riscv/spinlock.c + ${SDK_PATH}/cpu/core-riscv/start.S + ${SDK_PATH}/cpu/core-riscv/genex.S + ${SDK_PATH}/cpu/core-riscv/traps.c + ${SDK_PATH}/cpu/soc-x2600/src/interrupt.c + ${SDK_PATH}/cpu/soc-x2600/src/serial.c + ${SDK_PATH}/cpu/soc-x2600/src/startup.c + ${SDK_PATH}/drivers/drivers-x2600/src/x2600_hal_def.c + ${SDK_PATH}/drivers/drivers-x2600/src/x2600_hal_ssi.c + ${SDK_PATH}/drivers/drivers-x2600/src/x2600_ll_gpio.c + ${SDK_PATH}/drivers/drivers-x2600/src/x2600_ll_cpm.c + ${SDK_PATH}/drivers/drivers-x2600/src/x2600_hal_pdma.c + ${SDK_PATH}/drivers/drivers-x2600/src/x2600_hal_tick_risc_ccu.c + ${SDK_PATH}/drivers/drivers-x2600/src/x2600_ll_risc_ccu.c + ${SDK_PATH}/lib/libc/minimal/ctype.c + ${SDK_PATH}/lib/libc/minimal/div64.c + ${SDK_PATH}/lib/libc/minimal/string.c + ${SDK_PATH}/lib/libc/minimal/vsprintf.c + main.c + +) + +if(CMAKE_EXPORT_COMPILE_COMMANDS) + set(CMAKE_C_STANDARD_INCLUDE_DIRECTORIES ${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}) + set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}) +endif() + +# +# Include directories +# +#set(include_path_DIRS +# Modified + +include_directories( + ${PROJ_PATH}/include + ${SDK_PATH}/lib/libc/minimal/include + ${SDK_PATH}/drivers/drivers-x2600/include + ${SDK_PATH}/cpu/core-riscv/include + ${SDK_PATH}/cpu/soc-x2600/include + +) + +# +# -L libdirs. +# +link_directories( +#path/to/lib +) + +# Executable files +add_executable(${EXECUTABLE} ${sources_SRCS}) + +# Linker options +target_link_libraries(${EXECUTABLE} PRIVATE + -T${linker_script_SRC} + ${CMAKE_LD_FLAGS} + -Wl,-Map=${CMAKE_PROJECT_NAME}.map,--cref + -Wl,--gc-sections + -Wl,--start-group + -Wl,--end-group + -Wl,--print-memory-usage +) + +# Execute post-build to print size +add_custom_command(TARGET ${EXECUTABLE} POST_BUILD + COMMAND ${CMAKE_SIZE} $ +) + +# Convert output to hex and binary +add_custom_command(TARGET ${EXECUTABLE} POST_BUILD + COMMAND ${CMAKE_OBJCOPY} -O binary $ ${EXECUTABLE}.bin + ) diff --git a/projects/x2660-halley/Examples/spi/spi_fullduplex_dma/Makefile b/projects/x2660-halley/Examples/spi/spi_fullduplex_dma/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..0fbda21b99bcdc2b6dbdf2302637272a8946ebb6 --- /dev/null +++ b/projects/x2660-halley/Examples/spi/spi_fullduplex_dma/Makefile @@ -0,0 +1,178 @@ +###################################### +# target +###################################### +TARGET = ssi_dma + +SDK_PATH = ../../../../../ + + +###################################### +# building variables +###################################### +# debug build? +DEBUG = 1 +# optimization +OPT = -Og -fno-pic -fno-builtin -fomit-frame-pointer -Wall -nostdlib -Werror-implicit-function-declaration + + +####################################### +# paths +####################################### +# Build path +BUILD_DIR = build + +###################################### +# source +###################################### +# C sources +C_SOURCES = \ +$(SDK_PATH)/cpu/core-riscv/traps.c \ +$(SDK_PATH)/cpu/core-riscv/spinlock.c \ +$(SDK_PATH)/cpu/soc-x2600/src/startup.c \ +$(SDK_PATH)/cpu/soc-x2600/src/serial.c \ +$(SDK_PATH)/cpu/soc-x2600/src/interrupt.c \ +$(SDK_PATH)/drivers/drivers-x2600/src/x2600_hal_def.c \ +$(SDK_PATH)/drivers/drivers-x2600/src/x2600_hal_pdma.c \ +$(SDK_PATH)/drivers/drivers-x2600/src/x2600_hal_ssi.c \ +$(SDK_PATH)/drivers/drivers-x2600/src/x2600_ll_cpm.c \ +$(SDK_PATH)/drivers/drivers-x2600/src/x2600_ll_gpio.c \ +$(SDK_PATH)/drivers/drivers-x2600/src/x2600_hal_tick_risc_ccu.c \ +$(SDK_PATH)/drivers/drivers-x2600/src/x2600_ll_risc_ccu.c \ +$(SDK_PATH)/lib/libc/minimal/vsprintf.c \ +$(SDK_PATH)/lib/libc/minimal/string.c \ +$(SDK_PATH)/lib/libc/minimal/ctype.c \ +$(SDK_PATH)/lib/libc/minimal/div64.c \ +main.c + +# ASM sources +ASM_SOURCES = \ +$(SDK_PATH)/cpu/core-riscv/start.S \ +$(SDK_PATH)/cpu/core-riscv/genex.S + + +####################################### +# binaries +####################################### +PREFIX = riscv32-ingenicv0-elf- +# The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx) +# either it can be added to the PATH environment variable. +ifdef GCC_PATH +CC = $(GCC_PATH)/$(PREFIX)gcc +AS = $(GCC_PATH)/$(PREFIX)as +LD = $(GCC_PATH)/$(PREFIX)ld +CP = $(GCC_PATH)/$(PREFIX)objcopy +SZ = $(GCC_PATH)/$(PREFIX)size +else +CC = $(PREFIX)gcc +AS = $(PREFIX)as +LD = $(PREFIX)ld +CP = $(PREFIX)objcopy +SZ = $(PREFIX)size +endif +BIN = $(CP) -O binary -S + +####################################### +# CFLAGS +####################################### +# cpu +CPU = -march=rv32imc -mabi=ilp32 -Wno-abi + +# fpu +FPU = + +# float-abi +FLOAT-ABI = + +# mcu +#MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI) +MCU = $(CPU) $(FPU) $(FLOAT-ABI) + +# macros for gcc +# AS defines +AS_DEFS = -D_ASSEMBLER_ -D__ASSEMBLY__ + +# C defines +C_DEFS = + + +# AS includes +AS_INCLUDES = \ +-I$(SDK_PATH)/cpu/core-riscv/include \ +-I$(SDK_PATH)/lib/libc/minimal/include \ + +# C includes +C_INCLUDES = \ +-Iinclude \ +-I$(SDK_PATH)/cpu/core-riscv/include \ +-I$(SDK_PATH)/cpu/soc-x2600/include \ +-I$(SDK_PATH)/lib/libc/minimal/include \ +-I$(SDK_PATH)/drivers/drivers-x2600/include + + +# compile gcc flags +ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections + +CFLAGS = $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections + +ifeq ($(DEBUG), 1) +CFLAGS += -g -gdwarf-2 -O0 +endif + + +# Generate dependency information +CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)" + + +####################################### +# LDFLAGS +####################################### +# link script +LDSCRIPT = $(SDK_PATH)/cpu/core-riscv/ld.lds + +# libraries +#LIBS = -lc -lm -lnosys +LIBDIR = +LDFLAGS = $(MCU) -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections -nostdlib + +# default action: build all +all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).bin + + +####################################### +# build the application +####################################### +# list of objects +OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o))) +vpath %.c $(sort $(dir $(C_SOURCES))) +# list of ASM program objects +OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.S=.o))) +vpath %.S $(sort $(dir $(ASM_SOURCES))) + +$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) + $(CC) -c $(CFLAGS) $< -o $@ + +$(BUILD_DIR)/%.o: %.S Makefile | $(BUILD_DIR) + $(CC) -c $(ASFLAGS) -o $@ $< + +$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile + $(CC) $(OBJECTS) $(LDFLAGS) -o $@ + $(SZ) $@ + +$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR) + $(BIN) $< $@ + +$(BUILD_DIR): + mkdir $@ + +####################################### +# clean up +####################################### +clean: + -rm -fR $(BUILD_DIR) + +####################################### +# dependencies +####################################### +-include $(wildcard $(BUILD_DIR)/*.d) + +# *** EOF *** diff --git a/projects/x2660-halley/Examples/spi/spi_fullduplex_dma/include/board_eth_phy_conf.h b/projects/x2660-halley/Examples/spi/spi_fullduplex_dma/include/board_eth_phy_conf.h new file mode 100644 index 0000000000000000000000000000000000000000..c907ead4a2298d34794f0491a29781cf67ffdb68 --- /dev/null +++ b/projects/x2660-halley/Examples/spi/spi_fullduplex_dma/include/board_eth_phy_conf.h @@ -0,0 +1,75 @@ +#ifndef __ETH_PHY_CONF_H +#define __ETH_PHY_CONF_H + +/* ################## Ethernet peripheral configuration ##################### */ + +/* Section 1 : Ethernet peripheral configuration */ + +/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ +#define MAC_ADDR0 0x00U +#define MAC_ADDR1 0x11U +#define MAC_ADDR2 0x22U +#define MAC_ADDR3 0x33U +#define MAC_ADDR4 0x44U +#define MAC_ADDR5 0x55U + +/* Definition of the Ethernet driver buffers size and count */ +#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ +#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ +#define ETH_RXBUFNB ((uint32_t)4U) /* 4 Rx buffers of size ETH_RX_BUF_SIZE */ +#define ETH_TXBUFNB ((uint32_t)4U) /* 4 Tx buffers of size ETH_TX_BUF_SIZE */ + +/* Section 2: PHY configuration section */ + +/* DP83848 PHY Address*/ +#define DP83848_PHY_ADDRESS 0x01U +/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ +#define PHY_RESET_DELAY ((uint32_t)0x000000FFU) +/* PHY Configuration delay */ +#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFFU) + +#define PHY_READ_TO ((uint32_t)0x0000FFFFU) +#define PHY_WRITE_TO ((uint32_t)0x0000FFFFU) + +/* Section 3: Common PHY Registers */ + +#define PHY_BCR ((uint16_t)0x00U) /*!< Transceiver Basic Control Register */ +#define PHY_BSR ((uint16_t)0x01U) /*!< Transceiver Basic Status Register */ + +#define PHY_RESET ((uint16_t)0x8000U) /*!< PHY Reset */ +#define PHY_LOOPBACK ((uint16_t)0x4000U) /*!< Select loop-back mode */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100U) /*!< Set the full-duplex mode at 100 Mb/s */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2600U) /*!< Set the half-duplex mode at 100 Mb/s */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100U) /*!< Set the full-duplex mode at 10 Mb/s */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000U) /*!< Set the half-duplex mode at 10 Mb/s */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000U) /*!< Enable auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200U) /*!< Restart auto-negotiation function */ +#define PHY_POWERDOWN ((uint16_t)0x0800U) /*!< Select the power down mode */ +#define PHY_ISOLATE ((uint16_t)0x0400U) /*!< Isolate PHY from MII */ + +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020U) /*!< Auto-Negotiation process completed */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< Valid link established */ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002U) /*!< Jabber condition detected */ + +/* Section 4: Extended PHY Registers */ + +#define PHY_SR ((uint16_t)0x10U) /*!< PHY status register Offset */ +#define PHY_MICR ((uint16_t)0x11U) /*!< MII Interrupt Control Register */ +#define PHY_MISR ((uint16_t)0x12U) /*!< MII Interrupt Status and Misc. Control Register */ + +#define PHY_LINK_STATUS ((uint16_t)0x0001U) /*!< PHY Link mask */ +#define PHY_SPEED_STATUS ((uint16_t)0x0002U) /*!< PHY Speed mask */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0004U) /*!< PHY Duplex mask */ + +#define PHY_MICR_INT_EN ((uint16_t)0x0002U) /*!< PHY Enable interrupts */ +#define PHY_MICR_INT_OE ((uint16_t)0x0001U) /*!< PHY Enable output interrupt events */ + +#define PHY_MISR_LINK_INT_EN ((uint16_t)0x0020U) /*!< Enable Interrupt on change of link status */ +#define PHY_LINK_INTERRUPT ((uint16_t)0x2600U) /*!< PHY link status interrupt mask */ + +/* ################## Ethernet peripheral configuration ##################### */ + + + +#endif // __ETH_PHY_CONF_H + diff --git a/projects/x2660-halley/Examples/spi/spi_fullduplex_dma/include/x2600_hal_conf.h b/projects/x2660-halley/Examples/spi/spi_fullduplex_dma/include/x2600_hal_conf.h new file mode 100644 index 0000000000000000000000000000000000000000..a2f6791bd3101b4d831ec77856f54637f8f771e0 --- /dev/null +++ b/projects/x2660-halley/Examples/spi/spi_fullduplex_dma/include/x2600_hal_conf.h @@ -0,0 +1,116 @@ +#ifndef __X2600_HAL_CONF_H__ +#define __X2600_HAL_CONF_H__ +/* TODO: 本文件应该通过工具生成,在配置工程中选择不同的组件时,在此处包含不同的头文件 + 暂时包含全部头文件. +*/ + + +/* 1. Includes ---------------------------------------------------- */ + + +/* Hal Module selections. */ +#define HAL_MSC_ENABLED +#define HAL_I2C_ENABLED +#define HAL_UART_ENABLED +#define HAL_ADC_ENABLED +#define HAL_SPI_ENABLED +#define HAL_WDT_ENABLED +#define HAL_TCU_ENABLED +#define HAL_RTC_ENABLED +#define HAL_EFUSE_ENABLED +#define HAL_PWM_ENABLED +#define HAL_GMAC_ENABLED +#define HAL_USB_ENABLED + +/* 系统时钟配配置,通过工具生成,随开发板或者平台变化.*/ +#include +#include + +#include "x2600_hal_tick.h" +#include "x2600_ll_ost_core.h" +#include "x2600_ll_ost_global.h" +#include "x2600_ll_cpm.h" +#include "x2600_ll_gpio.h" + +#include "x2600_hal_pdma.h" + +//#include "x2600_hal_sfcnor.h" + +#ifdef HAL_MSC_ENABLED + +#endif + +#ifdef HAL_I2C_ENABLED +#include "x2600_hal_i2c.h" +#endif + +#ifdef HAL_UART_ENABLED +#include "x2600_hal_uart.h" +#endif + +#ifdef HAL_ADC_ENABLED +#include "x2600_hal_adc.h" +#endif + +#ifdef HAL_SPI_ENABLED +#include "x2600_hal_ssi.h" +#endif + +#ifdef HAL_WDT_ENABLED +#include "x2600_hal_wdt.h" +#endif + +#ifdef HAL_TCU_ENABLED +#include "x2600_hal_tcu.h" +#endif + +#ifdef HAL_RTC_ENABLED +#include "x2600_hal_rtc.h" +#endif + +#ifdef HAL_EFUSE_ENABLED +#include "x2600_ll_efuse.h" +#include "x2600_hal_efuse.h" +#endif + +#ifdef HAL_PWM_ENABLED +#include "x2600_hal_pwm.h" +#endif + +#ifdef HAL_GMAC_ENABLED +#include "x2600_hal_gmac.h" +#endif + +#ifdef HAL_USB_ENABLED +#include "x2600_hal_pcd.h" +#include "x2600_hal_pcd_ex.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* 2. Exported Types ---------------------------------------------- */ + +/* 3. Exported Constants ------------------------------------------ */ + +/* 4. Exported Macros --------------------------------------------- */ + +/* 5. Exported Funcs ---------------------------------------------- */ + +/* 6. Exported Variables ------------------------------------------ */ + +/* 7. Private Types ----------------------------------------------- */ + +/* 8. Private Constants ------------------------------------------- */ + +/* 9. Private Macros ---------------------------------------------- */ + +/* 10. Private Funcs ---------------------------------------------- */ + +/* 11. Private Variables ------------------------------------------ */ + +#ifdef __cplusplus +} +#endif +#endif /* __X2600_HAL_H__ */ diff --git a/projects/x2660-halley/Examples/spi/spi_fullduplex_dma/include/x2600_sysclk_conf.h b/projects/x2660-halley/Examples/spi/spi_fullduplex_dma/include/x2600_sysclk_conf.h new file mode 100644 index 0000000000000000000000000000000000000000..3c4888de77815e51f6a20b70226fc73892421676 --- /dev/null +++ b/projects/x2660-halley/Examples/spi/spi_fullduplex_dma/include/x2600_sysclk_conf.h @@ -0,0 +1,68 @@ +/** + * @file x2600_sysclk_conf.h + * @author MPU系统软件部团队 + * @brief + * + * @copyright 版权所有 (北京君正集成电路股份有限公司) {2022} + * @copyright Copyright© 2022 Ingenic Semiconductor Co.,Ltd + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __X2600_SYSCLK_CONF_H__ +#define __X2600_SYSCLK_CONF_H__ + +#ifdef __cplusplus +extern "C" { +#endif +/* 1. Includes ---------------------------------------------------- */ + +/* 2. Exported Types ---------------------------------------------- */ + + +/* 3. Exported Constants ------------------------------------------ */ + +/* 4. Exported Macros --------------------------------------------- */ +#define SYSCLK_EXTAL (24000000) +#define SYSCLK_APLL (1200000000) +#define SYSCLK_MPLL (1200000000) + +#define SystemCoreClock SYSCLK_APLL + +#define CGU_CONFIG_MSC_APLL_24M { \ + .PLLMux = MSC1CDR_SCLK_A, \ + .Div = 24, \ + .Config = 0 } + +#define CGU_CONFIG_MSC_APLL_48M { \ + .PLLMux = MSC1CDR_SCLK_A, \ + .Div = 11, \ + .Config = 0 } + + +#define CGU_CONFIG_SSI_MPLL_500K { \ + .PLLMux = SSICDR_MPLL, \ + .Div = 15, \ + .Config = 0 } + +/* 5. Exported Funcs ---------------------------------------------- */ + +/* 6. Exported Variables ------------------------------------------ */ + +/* 7. Private Types ----------------------------------------------- */ + +/* 8. Private Constants ------------------------------------------- */ + +/* 9. Private Macros ---------------------------------------------- */ + +/* 10. Private Funcs ---------------------------------------------- */ + +/* 11. Private Variables ------------------------------------------ */ + +#ifdef __cplusplus +} +#endif +#endif /* __X2600_HAL_ADC_H__ */ diff --git a/projects/x2660-halley/Examples/spi/spi_fullduplex_dma/main.c b/projects/x2660-halley/Examples/spi/spi_fullduplex_dma/main.c new file mode 100644 index 0000000000000000000000000000000000000000..b74253a79f8a505230183d658830c00c310e2844 --- /dev/null +++ b/projects/x2660-halley/Examples/spi/spi_fullduplex_dma/main.c @@ -0,0 +1,192 @@ +#include + +#define COUNTOF(__BUFFER__) (sizeof(__BUFFER__) / sizeof(*(__BUFFER__))) +#define BUFFERSIZE (COUNTOF(aTxBuffer)) + +SPI_HandleTypeDef SpiHandle; +LL_CPM_CGU_ConfigTypeDef SpiCguConfig = CGU_CONFIG_SSI_MPLL_500K; + +uint8_t aTxBuffer[] = {0xaa}; +uint8_t aRxBuffer[BUFFERSIZE]; + +__attribute__((unused)) static void dump_spi_reg(void); + +DMA_HandleTypeDef DMA_Handle; +DMA_InitChannelConfTypeDef SPI_DMA_Tx_Config; +DMA_InitChannelConfTypeDef SPI_DMA_Rx_Config; + +__align(32) DMA_DescriptorDef SPI_Tx_desc; +DMA_InitDescConfTypeDef SPI_Tx_descConfig; +__align(32) DMA_DescriptorDef SPI_Rx_desc; +DMA_InitDescConfTypeDef SPI_Rx_descConfig; + +static void Error_Handler(void); + +void dma_rx_cb(struct __DMA_HandleTypeDef *hdma) +{ + prom_printk("**-------------------dma rx end\n"); + Flush_Cache_AllAddr(); + return; +} + +void dma_tx_cb(struct __DMA_HandleTypeDef *hdma) +{ + prom_printk("**-------------------dma tx end\n"); + Flush_Cache_AllAddr(); + return; +} + +void SPI_DMA_Init(void) +{ + prom_printk("SPI Tx destcriptor address = %08x\n", &SPI_Tx_desc); + prom_printk("SPI Tx Buffer address = %p\n", aTxBuffer); + prom_printk("SPI Rx destcriptor address = %08x\n", &SPI_Rx_desc); + prom_printk("SPI Rx Buffer address = %p\n", aRxBuffer); + + /* 实例化SPI句柄,并初始化SPI外围设备 */ + SpiHandle.Instance = SSI0_Instance; + SpiHandle.Init.DataSize = SPI_DATASIZE_8BIT; + SpiHandle.Init.TransferEndian = SPI_T_MSB_BYTE_MSB_BIT; + SpiHandle.Init.ReceiveEndian = SPI_R_MSB_BYTE_MSB_BIT; + SpiHandle.Init.FrameVaildLevel = SPI_CE0_LOW_CE1_LOW; + SpiHandle.Init.CLKPolarity = SPI_POLARITY_LOW; + SpiHandle.Init.CLKPhase = SPI_PHASE_1EDGE; + SpiHandle.Init.LoopMode = SPI_LOOP_DISABLE; + SpiHandle.DMA_Handle = &DMA_Handle; + SpiHandle.SPI_DMA_Rx_Config = &SPI_DMA_Rx_Config; + SpiHandle.SPI_DMA_Tx_Config = &SPI_DMA_Tx_Config; + + /* Rx Config */ + SPI_DMA_Rx_Config.XferCpltCallback = dma_rx_cb; + SPI_DMA_Rx_Config.data = NULL; + SPI_DMA_Rx_Config.DescMode = DESCRIPTOR; + SPI_DMA_Rx_Config.desc = &SPI_Rx_desc; + SPI_DMA_Rx_Config.descConfig = &SPI_Rx_descConfig; + SPI_DMA_Rx_Config.desc_count = sizeof(SPI_Rx_desc) / sizeof(DMA_DescriptorDef); + + SPI_Rx_descConfig.Desc_Interrupt = DMA_INTERRUPT; + SPI_Rx_descConfig.Desc_Link = NO_LINK; + SPI_Rx_descConfig.DescDMATransferType = DMA_RQ_SSI0_RX; + + SPI_Rx_descConfig.DescSrcAddress =(void *)SPI_FIFO(&SpiHandle); + SPI_Rx_descConfig.DescSrcAddrIncrement = DISABLE; + SPI_Rx_descConfig.DescSrcPortWidth = DMA_PORT_8BIT; + + SPI_Rx_descConfig.DescDstAddress = aRxBuffer; + SPI_Rx_descConfig.DescDstAddrIncrement = ENABLE; + SPI_Rx_descConfig.DescDstPortWidth = DMA_PORT_8BIT; + + SPI_Rx_descConfig.DescTransferNumByte = 1; + SPI_Rx_descConfig.DataLength = 1 ; + + /* Tx Config */ + SPI_DMA_Tx_Config.XferCpltCallback = dma_tx_cb; + SPI_DMA_Tx_Config.data = NULL; + SPI_DMA_Tx_Config.DescMode = DESCRIPTOR; + SPI_DMA_Tx_Config.desc = &SPI_Tx_desc; + SPI_DMA_Tx_Config.descConfig = &SPI_Tx_descConfig; + SPI_DMA_Tx_Config.desc_count = sizeof(SPI_Tx_desc) / sizeof(DMA_DescriptorDef); + + SPI_Tx_descConfig.Desc_Interrupt = DMA_INTERRUPT; + SPI_Tx_descConfig.Desc_Link = NO_LINK; + SPI_Tx_descConfig.DescDMATransferType = DMA_RQ_SSI0_TX; + + SPI_Tx_descConfig.DescSrcAddress = aTxBuffer; + SPI_Tx_descConfig.DescSrcAddrIncrement = ENABLE; + SPI_Tx_descConfig.DescSrcPortWidth = DMA_PORT_8BIT; + + SPI_Tx_descConfig.DescDstAddress = (void *)SPI_FIFO(&SpiHandle); + SPI_Tx_descConfig.DescDstAddrIncrement =DISABLE; + SPI_Tx_descConfig.DescDstPortWidth = DMA_PORT_8BIT; + + SPI_Tx_descConfig.DescTransferNumByte = 1; + SPI_Tx_descConfig.DataLength = 1; + + DMA_Handle.Instance = DMA_Instance ; +} + +int main(void) +{ + prom_printk("hello world %s %d\n",__func__,__LINE__); + + /* config clk MPLL + * * MPLL SSICDR SSIGR + * * (1200000000) / (15+1) / (2*(74+1)) = 500k + * */ + CPM_CGU_SSI_Start(CPM_Instance, &SpiCguConfig); + + /* 使能clock gate */ + CPM_GATE_Enable(CPM_Instance, CPM_CLKID_SSI0); + CPM_GATE_Enable(CPM_Instance, CPM_CLKID_DMAC); + + /* 内部分频 */ + WRITE_REG(SSI0_Instance->SSIGR, 0x4a); + + /* gpio 初始化 (SSI0: PB0 ~ PB3) */ + LL_GPIO_setPinMode(PB_Instance, 0, GPIO_MODE_FUNCTION0); + LL_GPIO_setPinMode(PB_Instance, 1, GPIO_MODE_FUNCTION0); + LL_GPIO_setPinMode(PB_Instance, 2, GPIO_MODE_FUNCTION0); + LL_GPIO_setPinMode(PB_Instance, 3, GPIO_MODE_FUNCTION0); + + /*if (HAL_SPI_Init(&SpiHandle) != HAL_OK) { + prom_printk("DBEBUG: SPI Init error !, %s, %d\n", __func__, __LINE__); + Error_Handler(); + } + */ + + ll_request_irq(IRQ_INTC0_SSI0, HAL_SPI_IRQHandler, (void *)&SpiHandle); + + + SPI_DMA_Init(); + + if (HAL_SPI_Init(&SpiHandle) != HAL_OK) { + prom_printk("DBEBUG: SPI Init error !, %s, %d\n", __func__, __LINE__); + Error_Handler(); + } + + HAL_SPI_DMA_TransmitReceive(&SpiHandle, (uint8_t *)aTxBuffer, (uint8_t *)aRxBuffer,2); + HAL_Delay(4000); + + Flush_Cache_AllAddr(); + prom_printk("tx:0x%x\nrx:0x%x\n", aTxBuffer[0], aRxBuffer[0]); + + if(HAL_SPI_DMA_Transmit(&SpiHandle,(uint8_t *)aTxBuffer,2)!=HAL_OK) { + prom_printk("SPI Transmit only test is failed.\n"); + Error_Handler(); + } + + Flush_Cache_AllAddr(); + + HAL_Delay(1000); + prom_printk("SPI Transmit only test, Please check the waveform.\n"); + + if(HAL_SPI_DMA_Receive(&SpiHandle,(uint8_t *)aRxBuffer,3)!=HAL_OK){ + prom_printk("SPI Receive only test is failed.\n"); + Error_Handler(); + } + HAL_Delay(1000); + prom_printk("SPI Receive only test, Please check the waveform.\n"); + return 0; +} + +void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *SpiHandle) +{ + prom_printk("Error Callback !\n"); +} + +static void Error_Handler(void) +{ + prom_printk("Error Handler\n"); +} + +__attribute__((unused)) static void dump_spi_reg(void) +{ + prom_printk("SSICR0 :0x%08x\n", READ_REG(SSI0_Instance->SSICR0)); + prom_printk("SSICR1 :0x%08x\n", READ_REG(SSI0_Instance->SSICR1)); + prom_printk("SSISR :0x%08x\n", READ_REG(SSI0_Instance->SSISR)); + prom_printk("SSIITR :0x%08x\n", READ_REG(SSI0_Instance->SSIITR)); + prom_printk("SSIICR :0x%08x\n", READ_REG(SSI0_Instance->SSIICR)); + prom_printk("SSIGR :0x%08x\n", READ_REG(SSI0_Instance->SSIGR)); + prom_printk("SSIRCNT :0x%08x\n", READ_REG(SSI0_Instance->SSIRCNT)); +} + diff --git a/projects/x2660-halley/Examples/spi/spi_fullduplex_dma/riscv32-gcc.cmake b/projects/x2660-halley/Examples/spi/spi_fullduplex_dma/riscv32-gcc.cmake new file mode 100644 index 0000000000000000000000000000000000000000..d09813df61ac4d343b4b4890668528bf54e9cedc --- /dev/null +++ b/projects/x2660-halley/Examples/spi/spi_fullduplex_dma/riscv32-gcc.cmake @@ -0,0 +1,18 @@ +set(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_SYSTEM_PROCESSOR riscv32) + +# Some default GCC settings +set(TOOLCHAIN_PREFIX "riscv32-ingenicv0-elf-") + +set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc) +set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) +set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g++) + +set(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}objcopy) +set(CMAKE_SIZE ${TOOLCHAIN_PREFIX}size) + +set(CMAKE_EXECUTABLE_SUFFIX_ASM ".elf") +set(CMAKE_EXECUTABLE_SUFFIX_C ".elf") +set(CMAKE_EXECUTABLE_SUFFIX_CXX ".elf") + +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) diff --git a/projects/x2660-halley/Examples/spi/spi_fullduplex_it/CMakeLists.txt b/projects/x2660-halley/Examples/spi/spi_fullduplex_it/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..2293f83e09cf331d644bb4ace677ac63fbcb2a8f --- /dev/null +++ b/projects/x2660-halley/Examples/spi/spi_fullduplex_it/CMakeLists.txt @@ -0,0 +1,111 @@ +cmake_minimum_required(VERSION 3.8) +# +# Core project settings +# +Project(ssi) # Modified +enable_language(C CXX ASM) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +# Setup compiler settings +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_C_EXTENSIONS ON) +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS ON) +set(PROJ_PATH ${CMAKE_CURRENT_SOURCE_DIR}) +set(SDK_PATH ${PROJ_PATH}/../../../../../) +message("Build type: " ${CMAKE_BUILD_TYPE}) + +# Set linker script +set(linker_script_SRC ${SDK_PATH}/cpu/core-riscv/ld.lds) # Modified +set(EXECUTABLE ${CMAKE_PROJECT_NAME}) +set(CPU_PARAMETERS "-march=rv32imc -mabi=ilp32 -Wno-abi") + +set(CMAKE_ASM_FLAGS "${CPU_PARAMETERS} -D_ASSEMBLER_ -D__ASSEMBLY__") + +set(CMAKE_C_FLAGS "${CPU_PARAMETERS} -fno-pic -fno-builtin -fomit-frame-pointer -Wall -nostdlib -Wall -fdata-sections -ffunction-sections") + +# Compiler options + +if(CMAKE_BUILD_TYPE STREQUAL Debug) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -g -ggdb -DDEBUG") +else() + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2") +endif() + +set(CMAKE_CXX_FLAGS ${CMAKE_C_FLAGS}) + +set(CMAKE_LD_FLAGS "${CPU_PARAMETERS}") + + +set(sources_SRCS # Modified + ${SDK_PATH}/cpu/core-riscv/spinlock.c + ${SDK_PATH}/cpu/core-riscv/start.S + ${SDK_PATH}/cpu/core-riscv/genex.S + ${SDK_PATH}/cpu/core-riscv/traps.c + ${SDK_PATH}/cpu/soc-x2600/src/interrupt.c + ${SDK_PATH}/cpu/soc-x2600/src/serial.c + ${SDK_PATH}/cpu/soc-x2600/src/startup.c + ${SDK_PATH}/drivers/drivers-x2600/src/x2600_hal_def.c + ${SDK_PATH}/drivers/drivers-x2600/src/x2600_hal_ssi.c + ${SDK_PATH}/drivers/drivers-x2600/src/x2600_ll_gpio.c + ${SDK_PATH}/drivers/drivers-x2600/src/x2600_ll_cpm.c + ${SDK_PATH}/drivers/drivers-x2600/src/x2600_hal_pdma.c + ${SDK_PATH}/lib/libc/minimal/ctype.c + ${SDK_PATH}/lib/libc/minimal/div64.c + ${SDK_PATH}/lib/libc/minimal/string.c + ${SDK_PATH}/lib/libc/minimal/vsprintf.c + main.c + +) + +if(CMAKE_EXPORT_COMPILE_COMMANDS) + set(CMAKE_C_STANDARD_INCLUDE_DIRECTORIES ${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}) + set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}) +endif() + +# +# Include directories +# +#set(include_path_DIRS +# Modified + +include_directories( + ${PROJ_PATH}/include + ${SDK_PATH}/lib/libc/minimal/include + ${SDK_PATH}/drivers/drivers-x2600/include + ${SDK_PATH}/cpu/core-riscv/include + ${SDK_PATH}/cpu/soc-x2600/include + +) + +# +# -L libdirs. +# +link_directories( +#path/to/lib +) + +# Executable files +add_executable(${EXECUTABLE} ${sources_SRCS}) + +# Linker options +target_link_libraries(${EXECUTABLE} PRIVATE + -T${linker_script_SRC} + ${CMAKE_LD_FLAGS} + -Wl,-Map=${CMAKE_PROJECT_NAME}.map,--cref + -Wl,--gc-sections + -Wl,--start-group + -Wl,--end-group + -Wl,--print-memory-usage +) + +# Execute post-build to print size +add_custom_command(TARGET ${EXECUTABLE} POST_BUILD + COMMAND ${CMAKE_SIZE} $ +) + +# Convert output to hex and binary +add_custom_command(TARGET ${EXECUTABLE} POST_BUILD + COMMAND ${CMAKE_OBJCOPY} -O binary $ ${EXECUTABLE}.bin + ) diff --git a/projects/x2660-halley/Examples/spi/spi_fullduplex_it/Makefile b/projects/x2660-halley/Examples/spi/spi_fullduplex_it/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..2902837d3133a53d543b7b0e65fd0fa1cdb2b6a7 --- /dev/null +++ b/projects/x2660-halley/Examples/spi/spi_fullduplex_it/Makefile @@ -0,0 +1,176 @@ +###################################### +# target +###################################### +TARGET = ssi_it + +SDK_PATH = ../../../../../ + + +###################################### +# building variables +###################################### +# debug build? +DEBUG = 1 +# optimization +OPT = -Og -fno-pic -fno-builtin -fomit-frame-pointer -Wall -nostdlib -Werror-implicit-function-declaration + + +####################################### +# paths +####################################### +# Build path +BUILD_DIR = build + +###################################### +# source +###################################### +# C sources +C_SOURCES = \ +$(SDK_PATH)/cpu/core-riscv/traps.c \ +$(SDK_PATH)/cpu/core-riscv/spinlock.c \ +$(SDK_PATH)/cpu/soc-x2600/src/startup.c \ +$(SDK_PATH)/cpu/soc-x2600/src/serial.c \ +$(SDK_PATH)/cpu/soc-x2600/src/interrupt.c \ +$(SDK_PATH)/drivers/drivers-x2600/src/x2600_hal_def.c \ +$(SDK_PATH)/drivers/drivers-x2600/src/x2600_hal_pdma.c \ +$(SDK_PATH)/drivers/drivers-x2600/src/x2600_hal_ssi.c \ +$(SDK_PATH)/drivers/drivers-x2600/src/x2600_ll_cpm.c \ +$(SDK_PATH)/drivers/drivers-x2600/src/x2600_ll_gpio.c \ +$(SDK_PATH)/lib/libc/minimal/vsprintf.c \ +$(SDK_PATH)/lib/libc/minimal/string.c \ +$(SDK_PATH)/lib/libc/minimal/ctype.c \ +$(SDK_PATH)/lib/libc/minimal/div64.c \ +main.c + +# ASM sources +ASM_SOURCES = \ +$(SDK_PATH)/cpu/core-riscv/start.S \ +$(SDK_PATH)/cpu/core-riscv/genex.S + + +####################################### +# binaries +####################################### +PREFIX = riscv32-ingenicv0-elf- +# The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx) +# either it can be added to the PATH environment variable. +ifdef GCC_PATH +CC = $(GCC_PATH)/$(PREFIX)gcc +AS = $(GCC_PATH)/$(PREFIX)as +LD = $(GCC_PATH)/$(PREFIX)ld +CP = $(GCC_PATH)/$(PREFIX)objcopy +SZ = $(GCC_PATH)/$(PREFIX)size +else +CC = $(PREFIX)gcc +AS = $(PREFIX)as +LD = $(PREFIX)ld +CP = $(PREFIX)objcopy +SZ = $(PREFIX)size +endif +BIN = $(CP) -O binary -S + +####################################### +# CFLAGS +####################################### +# cpu +CPU = -march=rv32imc -mabi=ilp32 -Wno-abi + +# fpu +FPU = + +# float-abi +FLOAT-ABI = + +# mcu +#MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI) +MCU = $(CPU) $(FPU) $(FLOAT-ABI) + +# macros for gcc +# AS defines +AS_DEFS = -D_ASSEMBLER_ -D__ASSEMBLY__ + +# C defines +C_DEFS = + + +# AS includes +AS_INCLUDES = \ +-I$(SDK_PATH)/cpu/core-riscv/include \ +-I$(SDK_PATH)/lib/libc/minimal/include \ + +# C includes +C_INCLUDES = \ +-Iinclude \ +-I$(SDK_PATH)/cpu/core-riscv/include \ +-I$(SDK_PATH)/cpu/soc-x2600/include \ +-I$(SDK_PATH)/lib/libc/minimal/include \ +-I$(SDK_PATH)/drivers/drivers-x2600/include + + +# compile gcc flags +ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections + +CFLAGS = $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections + +ifeq ($(DEBUG), 1) +CFLAGS += -g -gdwarf-2 -O0 +endif + + +# Generate dependency information +CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)" + + +####################################### +# LDFLAGS +####################################### +# link script +LDSCRIPT = $(SDK_PATH)/cpu/core-riscv/ld.lds + +# libraries +#LIBS = -lc -lm -lnosys +LIBDIR = +LDFLAGS = $(MCU) -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections -nostdlib + +# default action: build all +all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).bin + + +####################################### +# build the application +####################################### +# list of objects +OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o))) +vpath %.c $(sort $(dir $(C_SOURCES))) +# list of ASM program objects +OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.S=.o))) +vpath %.S $(sort $(dir $(ASM_SOURCES))) + +$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) + $(CC) -c $(CFLAGS) $< -o $@ + +$(BUILD_DIR)/%.o: %.S Makefile | $(BUILD_DIR) + $(CC) -c $(ASFLAGS) -o $@ $< + +$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile + $(CC) $(OBJECTS) $(LDFLAGS) -o $@ + $(SZ) $@ + +$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR) + $(BIN) $< $@ + +$(BUILD_DIR): + mkdir $@ + +####################################### +# clean up +####################################### +clean: + -rm -fR $(BUILD_DIR) + +####################################### +# dependencies +####################################### +-include $(wildcard $(BUILD_DIR)/*.d) + +# *** EOF *** diff --git a/projects/x2660-halley/Examples/spi/spi_fullduplex_it/include/board_eth_phy_conf.h b/projects/x2660-halley/Examples/spi/spi_fullduplex_it/include/board_eth_phy_conf.h new file mode 100644 index 0000000000000000000000000000000000000000..c907ead4a2298d34794f0491a29781cf67ffdb68 --- /dev/null +++ b/projects/x2660-halley/Examples/spi/spi_fullduplex_it/include/board_eth_phy_conf.h @@ -0,0 +1,75 @@ +#ifndef __ETH_PHY_CONF_H +#define __ETH_PHY_CONF_H + +/* ################## Ethernet peripheral configuration ##################### */ + +/* Section 1 : Ethernet peripheral configuration */ + +/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ +#define MAC_ADDR0 0x00U +#define MAC_ADDR1 0x11U +#define MAC_ADDR2 0x22U +#define MAC_ADDR3 0x33U +#define MAC_ADDR4 0x44U +#define MAC_ADDR5 0x55U + +/* Definition of the Ethernet driver buffers size and count */ +#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ +#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ +#define ETH_RXBUFNB ((uint32_t)4U) /* 4 Rx buffers of size ETH_RX_BUF_SIZE */ +#define ETH_TXBUFNB ((uint32_t)4U) /* 4 Tx buffers of size ETH_TX_BUF_SIZE */ + +/* Section 2: PHY configuration section */ + +/* DP83848 PHY Address*/ +#define DP83848_PHY_ADDRESS 0x01U +/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ +#define PHY_RESET_DELAY ((uint32_t)0x000000FFU) +/* PHY Configuration delay */ +#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFFU) + +#define PHY_READ_TO ((uint32_t)0x0000FFFFU) +#define PHY_WRITE_TO ((uint32_t)0x0000FFFFU) + +/* Section 3: Common PHY Registers */ + +#define PHY_BCR ((uint16_t)0x00U) /*!< Transceiver Basic Control Register */ +#define PHY_BSR ((uint16_t)0x01U) /*!< Transceiver Basic Status Register */ + +#define PHY_RESET ((uint16_t)0x8000U) /*!< PHY Reset */ +#define PHY_LOOPBACK ((uint16_t)0x4000U) /*!< Select loop-back mode */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100U) /*!< Set the full-duplex mode at 100 Mb/s */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2600U) /*!< Set the half-duplex mode at 100 Mb/s */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100U) /*!< Set the full-duplex mode at 10 Mb/s */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000U) /*!< Set the half-duplex mode at 10 Mb/s */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000U) /*!< Enable auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200U) /*!< Restart auto-negotiation function */ +#define PHY_POWERDOWN ((uint16_t)0x0800U) /*!< Select the power down mode */ +#define PHY_ISOLATE ((uint16_t)0x0400U) /*!< Isolate PHY from MII */ + +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020U) /*!< Auto-Negotiation process completed */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< Valid link established */ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002U) /*!< Jabber condition detected */ + +/* Section 4: Extended PHY Registers */ + +#define PHY_SR ((uint16_t)0x10U) /*!< PHY status register Offset */ +#define PHY_MICR ((uint16_t)0x11U) /*!< MII Interrupt Control Register */ +#define PHY_MISR ((uint16_t)0x12U) /*!< MII Interrupt Status and Misc. Control Register */ + +#define PHY_LINK_STATUS ((uint16_t)0x0001U) /*!< PHY Link mask */ +#define PHY_SPEED_STATUS ((uint16_t)0x0002U) /*!< PHY Speed mask */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0004U) /*!< PHY Duplex mask */ + +#define PHY_MICR_INT_EN ((uint16_t)0x0002U) /*!< PHY Enable interrupts */ +#define PHY_MICR_INT_OE ((uint16_t)0x0001U) /*!< PHY Enable output interrupt events */ + +#define PHY_MISR_LINK_INT_EN ((uint16_t)0x0020U) /*!< Enable Interrupt on change of link status */ +#define PHY_LINK_INTERRUPT ((uint16_t)0x2600U) /*!< PHY link status interrupt mask */ + +/* ################## Ethernet peripheral configuration ##################### */ + + + +#endif // __ETH_PHY_CONF_H + diff --git a/projects/x2660-halley/Examples/spi/spi_fullduplex_it/include/x2600_hal_conf.h b/projects/x2660-halley/Examples/spi/spi_fullduplex_it/include/x2600_hal_conf.h new file mode 100644 index 0000000000000000000000000000000000000000..a2f6791bd3101b4d831ec77856f54637f8f771e0 --- /dev/null +++ b/projects/x2660-halley/Examples/spi/spi_fullduplex_it/include/x2600_hal_conf.h @@ -0,0 +1,116 @@ +#ifndef __X2600_HAL_CONF_H__ +#define __X2600_HAL_CONF_H__ +/* TODO: 本文件应该通过工具生成,在配置工程中选择不同的组件时,在此处包含不同的头文件 + 暂时包含全部头文件. +*/ + + +/* 1. Includes ---------------------------------------------------- */ + + +/* Hal Module selections. */ +#define HAL_MSC_ENABLED +#define HAL_I2C_ENABLED +#define HAL_UART_ENABLED +#define HAL_ADC_ENABLED +#define HAL_SPI_ENABLED +#define HAL_WDT_ENABLED +#define HAL_TCU_ENABLED +#define HAL_RTC_ENABLED +#define HAL_EFUSE_ENABLED +#define HAL_PWM_ENABLED +#define HAL_GMAC_ENABLED +#define HAL_USB_ENABLED + +/* 系统时钟配配置,通过工具生成,随开发板或者平台变化.*/ +#include +#include + +#include "x2600_hal_tick.h" +#include "x2600_ll_ost_core.h" +#include "x2600_ll_ost_global.h" +#include "x2600_ll_cpm.h" +#include "x2600_ll_gpio.h" + +#include "x2600_hal_pdma.h" + +//#include "x2600_hal_sfcnor.h" + +#ifdef HAL_MSC_ENABLED + +#endif + +#ifdef HAL_I2C_ENABLED +#include "x2600_hal_i2c.h" +#endif + +#ifdef HAL_UART_ENABLED +#include "x2600_hal_uart.h" +#endif + +#ifdef HAL_ADC_ENABLED +#include "x2600_hal_adc.h" +#endif + +#ifdef HAL_SPI_ENABLED +#include "x2600_hal_ssi.h" +#endif + +#ifdef HAL_WDT_ENABLED +#include "x2600_hal_wdt.h" +#endif + +#ifdef HAL_TCU_ENABLED +#include "x2600_hal_tcu.h" +#endif + +#ifdef HAL_RTC_ENABLED +#include "x2600_hal_rtc.h" +#endif + +#ifdef HAL_EFUSE_ENABLED +#include "x2600_ll_efuse.h" +#include "x2600_hal_efuse.h" +#endif + +#ifdef HAL_PWM_ENABLED +#include "x2600_hal_pwm.h" +#endif + +#ifdef HAL_GMAC_ENABLED +#include "x2600_hal_gmac.h" +#endif + +#ifdef HAL_USB_ENABLED +#include "x2600_hal_pcd.h" +#include "x2600_hal_pcd_ex.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* 2. Exported Types ---------------------------------------------- */ + +/* 3. Exported Constants ------------------------------------------ */ + +/* 4. Exported Macros --------------------------------------------- */ + +/* 5. Exported Funcs ---------------------------------------------- */ + +/* 6. Exported Variables ------------------------------------------ */ + +/* 7. Private Types ----------------------------------------------- */ + +/* 8. Private Constants ------------------------------------------- */ + +/* 9. Private Macros ---------------------------------------------- */ + +/* 10. Private Funcs ---------------------------------------------- */ + +/* 11. Private Variables ------------------------------------------ */ + +#ifdef __cplusplus +} +#endif +#endif /* __X2600_HAL_H__ */ diff --git a/projects/x2660-halley/Examples/spi/spi_fullduplex_it/include/x2600_sysclk_conf.h b/projects/x2660-halley/Examples/spi/spi_fullduplex_it/include/x2600_sysclk_conf.h new file mode 100644 index 0000000000000000000000000000000000000000..3c4888de77815e51f6a20b70226fc73892421676 --- /dev/null +++ b/projects/x2660-halley/Examples/spi/spi_fullduplex_it/include/x2600_sysclk_conf.h @@ -0,0 +1,68 @@ +/** + * @file x2600_sysclk_conf.h + * @author MPU系统软件部团队 + * @brief + * + * @copyright 版权所有 (北京君正集成电路股份有限公司) {2022} + * @copyright Copyright© 2022 Ingenic Semiconductor Co.,Ltd + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __X2600_SYSCLK_CONF_H__ +#define __X2600_SYSCLK_CONF_H__ + +#ifdef __cplusplus +extern "C" { +#endif +/* 1. Includes ---------------------------------------------------- */ + +/* 2. Exported Types ---------------------------------------------- */ + + +/* 3. Exported Constants ------------------------------------------ */ + +/* 4. Exported Macros --------------------------------------------- */ +#define SYSCLK_EXTAL (24000000) +#define SYSCLK_APLL (1200000000) +#define SYSCLK_MPLL (1200000000) + +#define SystemCoreClock SYSCLK_APLL + +#define CGU_CONFIG_MSC_APLL_24M { \ + .PLLMux = MSC1CDR_SCLK_A, \ + .Div = 24, \ + .Config = 0 } + +#define CGU_CONFIG_MSC_APLL_48M { \ + .PLLMux = MSC1CDR_SCLK_A, \ + .Div = 11, \ + .Config = 0 } + + +#define CGU_CONFIG_SSI_MPLL_500K { \ + .PLLMux = SSICDR_MPLL, \ + .Div = 15, \ + .Config = 0 } + +/* 5. Exported Funcs ---------------------------------------------- */ + +/* 6. Exported Variables ------------------------------------------ */ + +/* 7. Private Types ----------------------------------------------- */ + +/* 8. Private Constants ------------------------------------------- */ + +/* 9. Private Macros ---------------------------------------------- */ + +/* 10. Private Funcs ---------------------------------------------- */ + +/* 11. Private Variables ------------------------------------------ */ + +#ifdef __cplusplus +} +#endif +#endif /* __X2600_HAL_ADC_H__ */ diff --git a/projects/x2660-halley/Examples/spi/spi_fullduplex_it/main.c b/projects/x2660-halley/Examples/spi/spi_fullduplex_it/main.c new file mode 100644 index 0000000000000000000000000000000000000000..797c6f6b1c2d2b1758f34e79be7f153360decd45 --- /dev/null +++ b/projects/x2660-halley/Examples/spi/spi_fullduplex_it/main.c @@ -0,0 +1,156 @@ +#include + +#define COUNTOF(__BUFFER__) (sizeof(__BUFFER__) / sizeof(*(__BUFFER__))) +#define BUFFERSIZE (COUNTOF(aTxBuffer) - 1) +#define SSI_CDR_DIVISION(__VALUE__) ((__VALUE__) - 1) + +SPI_HandleTypeDef SpiHandle; +LL_CPM_CGU_ConfigTypeDef SpiCguConfig = CGU_CONFIG_SSI_MPLL_500K; +__IO ITStatus SpiReady = RESET; + +uint8_t aTxBuffer[] = "****SPI - Two Boards communication based on Interrupt **** SPI Message ******** SPI Message ******** SPI Message ******** SPI Message ******** SPI Message ****"; + +uint8_t aRxBuffer[BUFFERSIZE]; + +void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *SpiHandle); +void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *SpiHandle); +void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *SpiHandle); +static uint8_t Buffercmp(uint8_t *pBuffer1, uint8_t *pBuffer2, uint16_t BufferLength); +static void Error_Handler(void); +__attribute__((unused)) static void dump_spi_reg(void); + +int main(void) +{ + prom_printk("hello world %s, %d\n", __func__, __LINE__); + + /* config clk MPLL + * MPLL SSICDR SSIGR + * (1200000000) / (15+1) / (2*(74+1)) = 500k + */ + CPM_CGU_SSI_Start(CPM_Instance, &SpiCguConfig); + + /* 使能clock gate */ + CPM_GATE_Enable(CPM_Instance, CPM_CLKID_SSI0); + + /* 内部分频 */ + WRITE_REG(SSI0_Instance->SSIGR, 0x4a); + + /* gpio 初始化 (SSI0: PB0 ~ PB3) */ + LL_GPIO_setPinMode(PB_Instance, 0, GPIO_MODE_FUNCTION0); + LL_GPIO_setPinMode(PB_Instance, 1, GPIO_MODE_FUNCTION0); + LL_GPIO_setPinMode(PB_Instance, 2, GPIO_MODE_FUNCTION0); + LL_GPIO_setPinMode(PB_Instance, 3, GPIO_MODE_FUNCTION0); + + /* 实例化SPI句柄,并初始化SPI外围设备 */ + SpiHandle.Instance = SSI0_Instance; + SpiHandle.Init.DataSize = SPI_DATASIZE_8BIT; + SpiHandle.Init.TransferEndian = SPI_T_MSB_BYTE_MSB_BIT; + SpiHandle.Init.ReceiveEndian = SPI_R_MSB_BYTE_MSB_BIT; + SpiHandle.Init.FrameVaildLevel = SPI_CE0_LOW_CE1_LOW; + SpiHandle.Init.CLKPolarity = SPI_POLARITY_LOW; + SpiHandle.Init.CLKPhase = SPI_PHASE_1EDGE; + SpiHandle.Init.LoopMode = SPI_LOOP_DISABLE; + + if (HAL_SPI_Init(&SpiHandle) != HAL_OK) { + prom_printk("DBEBUG: SPI Init error !, %s, %d\n", __func__, __LINE__); + Error_Handler(); + } + + /* 请求中断 */ + + ll_request_irq(IRQ_INTC0_SSI0, HAL_SPI_IRQHandler, (void *)&SpiHandle); + + /* 测试1: 全双工发送和接收测试 */ + SpiReady = RESET; + if (HAL_SPI_TransmitReceive_IT(&SpiHandle, (uint8_t *)aTxBuffer, (uint8_t *)aRxBuffer, BUFFERSIZE) != HAL_OK) { + prom_printk("SPI Transmit Receive test is failed.\n"); + Error_Handler(); + } + + while (SpiReady != SET); + + prom_printk("tx:%s\nrx:%s\n", (uint8_t *)aTxBuffer, (uint8_t *)aRxBuffer); + if (Buffercmp((uint8_t *)aTxBuffer, (uint8_t *)aRxBuffer, BUFFERSIZE)) { + prom_printk("SPI Transmit Receive test is failed.\n"); + Error_Handler(); + } else { + prom_printk("SPI Transmit Receive test is success.\n"); + } + + + /* 测试2: 只发送测试 */ + SpiReady = RESET; + if (HAL_SPI_Transmit_IT(&SpiHandle, (uint8_t *)aTxBuffer, BUFFERSIZE) != HAL_OK) { + prom_printk("SPI Transmit only test is failed.\n"); + Error_Handler(); + } + + while (SpiReady != SET); + prom_printk("SPI Transmit only test, Please check the waveform.\n"); + + + /* 测试3: 只接收测试 */ + SpiReady = RESET; + if (HAL_SPI_Receive_IT(&SpiHandle, (uint8_t *)aTxBuffer, 3) != HAL_OK) { + prom_printk("SPI Receive only test is failed.\n"); + Error_Handler(); + } + + while (SpiReady != SET); + prom_printk("SPI Receive only test, Please check the waveform.\n"); + + while (1); + return 0; +} + +void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *SpiHandle) +{ + SpiReady = SET; +} + +void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *SpiHandle) +{ + SpiReady = SET; +} + +void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *SpiHandle) +{ + SpiReady = SET; +} + + +void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *SpiHandle) +{ + prom_printk("Error Callback !\n"); +} + +static uint8_t Buffercmp(uint8_t *pBuffer1, uint8_t *pBuffer2, uint16_t BufferLength) +{ + while (BufferLength--) { + if (*pBuffer1 != *pBuffer2) { + return 1; + } + + pBuffer1++; + pBuffer2++; + } + + return 0; +} + +static void Error_Handler(void) +{ + prom_printk("Error Handler\n"); +} + +__attribute__((unused)) static void dump_spi_reg(void) +{ + prom_printk("SSICR0 :0x%08x\n", READ_REG(SSI0_Instance->SSICR0)); + prom_printk("SSICR1 :0x%08x\n", READ_REG(SSI0_Instance->SSICR1)); + prom_printk("SSISR :0x%08x\n", READ_REG(SSI0_Instance->SSISR)); + prom_printk("SSIITR :0x%08x\n", READ_REG(SSI0_Instance->SSIITR)); + prom_printk("SSIICR :0x%08x\n", READ_REG(SSI0_Instance->SSIICR)); + prom_printk("SSIGR :0x%08x\n", READ_REG(SSI0_Instance->SSIGR)); + prom_printk("SSIRCNT :0x%08x\n", READ_REG(SSI0_Instance->SSIRCNT)); +} + diff --git a/projects/x2660-halley/Examples/spi/spi_fullduplex_it/riscv32-gcc.cmake b/projects/x2660-halley/Examples/spi/spi_fullduplex_it/riscv32-gcc.cmake new file mode 100644 index 0000000000000000000000000000000000000000..d09813df61ac4d343b4b4890668528bf54e9cedc --- /dev/null +++ b/projects/x2660-halley/Examples/spi/spi_fullduplex_it/riscv32-gcc.cmake @@ -0,0 +1,18 @@ +set(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_SYSTEM_PROCESSOR riscv32) + +# Some default GCC settings +set(TOOLCHAIN_PREFIX "riscv32-ingenicv0-elf-") + +set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc) +set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) +set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g++) + +set(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}objcopy) +set(CMAKE_SIZE ${TOOLCHAIN_PREFIX}size) + +set(CMAKE_EXECUTABLE_SUFFIX_ASM ".elf") +set(CMAKE_EXECUTABLE_SUFFIX_C ".elf") +set(CMAKE_EXECUTABLE_SUFFIX_CXX ".elf") + +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) diff --git a/projects/x2660-halley/Examples/spi/spi_fullduplex_polling/CMakeLists.txt b/projects/x2660-halley/Examples/spi/spi_fullduplex_polling/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..fcb61764b7c4e17ba7e0a268d15a7e502ad69d79 --- /dev/null +++ b/projects/x2660-halley/Examples/spi/spi_fullduplex_polling/CMakeLists.txt @@ -0,0 +1,113 @@ +cmake_minimum_required(VERSION 3.8) +# +# Core project settings +# +Project(ssi_polling) # Modified +enable_language(C CXX ASM) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +# Setup compiler settings +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_C_EXTENSIONS ON) +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS ON) +set(PROJ_PATH ${CMAKE_CURRENT_SOURCE_DIR}) +set(SDK_PATH ${PROJ_PATH}/../../../../../) +message("Build type: " ${CMAKE_BUILD_TYPE}) + +# Set linker script +set(linker_script_SRC ${SDK_PATH}/cpu/core-riscv/ld.lds) # Modified +set(EXECUTABLE ${CMAKE_PROJECT_NAME}) +set(CPU_PARAMETERS "-march=rv32imc -mabi=ilp32 -Wno-abi") + +set(CMAKE_ASM_FLAGS "${CPU_PARAMETERS} -D_ASSEMBLER_ -D__ASSEMBLY__") + +set(CMAKE_C_FLAGS "${CPU_PARAMETERS} -fno-pic -fno-builtin -fomit-frame-pointer -Wall -nostdlib -Wall -fdata-sections -ffunction-sections") + +# Compiler options + +if(CMAKE_BUILD_TYPE STREQUAL Debug) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -g -ggdb -DDEBUG") +else() + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2") +endif() + +set(CMAKE_CXX_FLAGS ${CMAKE_C_FLAGS}) + +set(CMAKE_LD_FLAGS "${CPU_PARAMETERS}") + + +set(sources_SRCS # Modified + ${SDK_PATH}/cpu/core-riscv/spinlock.c + ${SDK_PATH}/cpu/core-riscv/start.S + ${SDK_PATH}/cpu/core-riscv/genex.S + ${SDK_PATH}/cpu/core-riscv/traps.c + ${SDK_PATH}/cpu/soc-x2600/src/interrupt.c + ${SDK_PATH}/cpu/soc-x2600/src/serial.c + ${SDK_PATH}/cpu/soc-x2600/src/startup.c + ${SDK_PATH}/drivers/drivers-x2600/src/x2600_hal_def.c + ${SDK_PATH}/drivers/drivers-x2600/src/x2600_hal_ssi.c + ${SDK_PATH}/drivers/drivers-x2600/src/x2600_ll_gpio.c + ${SDK_PATH}/drivers/drivers-x2600/src/x2600_ll_cpm.c + ${SDK_PATH}/drivers/drivers-x2600/src/x2600_hal_pdma.c + ${SDK_PATH}/drivers/drivers-x2600/src/x2600_hal_tick_risc_ccu.c + ${SDK_PATH}/drivers/drivers-x2600/src/x2600_ll_risc_ccu.c + ${SDK_PATH}/lib/libc/minimal/ctype.c + ${SDK_PATH}/lib/libc/minimal/div64.c + ${SDK_PATH}/lib/libc/minimal/string.c + ${SDK_PATH}/lib/libc/minimal/vsprintf.c + main.c + +) + +if(CMAKE_EXPORT_COMPILE_COMMANDS) + set(CMAKE_C_STANDARD_INCLUDE_DIRECTORIES ${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}) + set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}) +endif() + +# +# Include directories +# +#set(include_path_DIRS +# Modified + +include_directories( + ${PROJ_PATH}/include + ${SDK_PATH}/lib/libc/minimal/include + ${SDK_PATH}/drivers/drivers-x2600/include + ${SDK_PATH}/cpu/core-riscv/include + ${SDK_PATH}/cpu/soc-x2600/include + +) + +# +# -L libdirs. +# +link_directories( +#path/to/lib +) + +# Executable files +add_executable(${EXECUTABLE} ${sources_SRCS}) + +# Linker options +target_link_libraries(${EXECUTABLE} PRIVATE + -T${linker_script_SRC} + ${CMAKE_LD_FLAGS} + -Wl,-Map=${CMAKE_PROJECT_NAME}.map,--cref + -Wl,--gc-sections + -Wl,--start-group + -Wl,--end-group + -Wl,--print-memory-usage +) + +# Execute post-build to print size +add_custom_command(TARGET ${EXECUTABLE} POST_BUILD + COMMAND ${CMAKE_SIZE} $ +) + +# Convert output to hex and binary +add_custom_command(TARGET ${EXECUTABLE} POST_BUILD + COMMAND ${CMAKE_OBJCOPY} -O binary $ ${EXECUTABLE}.bin + ) diff --git a/projects/x2660-halley/Examples/spi/spi_fullduplex_polling/Makefile b/projects/x2660-halley/Examples/spi/spi_fullduplex_polling/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..75d9c86472d362a8fd3b720386c6ac8dc3dbc174 --- /dev/null +++ b/projects/x2660-halley/Examples/spi/spi_fullduplex_polling/Makefile @@ -0,0 +1,178 @@ +##################################### +# target +###################################### +TARGET = ssi_polling + +SDK_PATH = ../../../../../ + + +###################################### +# building variables +###################################### +# debug build? +DEBUG = 1 +# optimization +OPT = -Og -fno-pic -fno-builtin -fomit-frame-pointer -Wall -nostdlib -Werror-implicit-function-declaration + + +####################################### +# paths +####################################### +# Build path +BUILD_DIR = build + +###################################### +# source +###################################### +# C sources +C_SOURCES = \ +$(SDK_PATH)/cpu/core-riscv/traps.c \ +$(SDK_PATH)/cpu/core-riscv/spinlock.c \ +$(SDK_PATH)/cpu/soc-x2600/src/startup.c \ +$(SDK_PATH)/cpu/soc-x2600/src/serial.c \ +$(SDK_PATH)/cpu/soc-x2600/src/interrupt.c \ +$(SDK_PATH)/drivers/drivers-x2600/src/x2600_hal_def.c \ +$(SDK_PATH)/drivers/drivers-x2600/src/x2600_hal_pdma.c \ +$(SDK_PATH)/drivers/drivers-x2600/src/x2600_hal_ssi.c \ +$(SDK_PATH)/drivers/drivers-x2600/src/x2600_ll_cpm.c \ +$(SDK_PATH)/drivers/drivers-x2600/src/x2600_ll_gpio.c \ +$(SDK_PATH)/drivers/drivers-x2600/src/x2600_hal_tick_risc_ccu.c \ +$(SDK_PATH)/drivers/drivers-x2600/src/x2600_ll_risc_ccu.c \ +$(SDK_PATH)/lib/libc/minimal/vsprintf.c \ +$(SDK_PATH)/lib/libc/minimal/string.c \ +$(SDK_PATH)/lib/libc/minimal/ctype.c \ +$(SDK_PATH)/lib/libc/minimal/div64.c \ +main.c + +# ASM sources +ASM_SOURCES = \ +$(SDK_PATH)/cpu/core-riscv/start.S \ +$(SDK_PATH)/cpu/core-riscv/genex.S + + +####################################### +# binaries +####################################### +PREFIX = riscv32-ingenicv0-elf- +# The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx) +# either it can be added to the PATH environment variable. +ifdef GCC_PATH +CC = $(GCC_PATH)/$(PREFIX)gcc +AS = $(GCC_PATH)/$(PREFIX)as +LD = $(GCC_PATH)/$(PREFIX)ld +CP = $(GCC_PATH)/$(PREFIX)objcopy +SZ = $(GCC_PATH)/$(PREFIX)size +else +CC = $(PREFIX)gcc +AS = $(PREFIX)as +LD = $(PREFIX)ld +CP = $(PREFIX)objcopy +SZ = $(PREFIX)size +endif +BIN = $(CP) -O binary -S + +####################################### +# CFLAGS +####################################### +# cpu +CPU = -march=rv32imc -mabi=ilp32 -Wno-abi + +# fpu +FPU = + +# float-abi +FLOAT-ABI = + +# mcu +#MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI) +MCU = $(CPU) $(FPU) $(FLOAT-ABI) + +# macros for gcc +# AS defines +AS_DEFS = -D_ASSEMBLER_ -D__ASSEMBLY__ + +# C defines +C_DEFS = + + +# AS includes +AS_INCLUDES = \ +-I$(SDK_PATH)/cpu/core-riscv/include \ +-I$(SDK_PATH)/lib/libc/minimal/include \ + +# C includes +C_INCLUDES = \ +-Iinclude \ +-I$(SDK_PATH)/cpu/core-riscv/include \ +-I$(SDK_PATH)/cpu/soc-x2600/include \ +-I$(SDK_PATH)/lib/libc/minimal/include \ +-I$(SDK_PATH)/drivers/drivers-x2600/include + + +# compile gcc flags +ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections + +CFLAGS = $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections + +ifeq ($(DEBUG), 1) +CFLAGS += -g -gdwarf-2 -O0 +endif + + +# Generate dependency information +CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)" + + +####################################### +# LDFLAGS +####################################### +# link script +LDSCRIPT = $(SDK_PATH)/cpu/core-riscv/ld.lds + +# libraries +#LIBS = -lc -lm -lnosys +LIBDIR = +LDFLAGS = $(MCU) -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections -nostdlib + +# default action: build all +all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).bin + + +####################################### +# build the application +####################################### +# list of objects +OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o))) +vpath %.c $(sort $(dir $(C_SOURCES))) +# list of ASM program objects +OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.S=.o))) +vpath %.S $(sort $(dir $(ASM_SOURCES))) + +$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) + $(CC) -c $(CFLAGS) $< -o $@ + +$(BUILD_DIR)/%.o: %.S Makefile | $(BUILD_DIR) + $(CC) -c $(ASFLAGS) -o $@ $< + +$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile + $(CC) $(OBJECTS) $(LDFLAGS) -o $@ + $(SZ) $@ + +$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR) + $(BIN) $< $@ + +$(BUILD_DIR): + mkdir $@ + +####################################### +# clean up +####################################### +clean: + -rm -fR $(BUILD_DIR) + +####################################### +# dependencies +####################################### +-include $(wildcard $(BUILD_DIR)/*.d) + +# *** EOF *** diff --git a/projects/x2660-halley/Examples/spi/spi_fullduplex_polling/include/board_eth_phy_conf.h b/projects/x2660-halley/Examples/spi/spi_fullduplex_polling/include/board_eth_phy_conf.h new file mode 100644 index 0000000000000000000000000000000000000000..c907ead4a2298d34794f0491a29781cf67ffdb68 --- /dev/null +++ b/projects/x2660-halley/Examples/spi/spi_fullduplex_polling/include/board_eth_phy_conf.h @@ -0,0 +1,75 @@ +#ifndef __ETH_PHY_CONF_H +#define __ETH_PHY_CONF_H + +/* ################## Ethernet peripheral configuration ##################### */ + +/* Section 1 : Ethernet peripheral configuration */ + +/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ +#define MAC_ADDR0 0x00U +#define MAC_ADDR1 0x11U +#define MAC_ADDR2 0x22U +#define MAC_ADDR3 0x33U +#define MAC_ADDR4 0x44U +#define MAC_ADDR5 0x55U + +/* Definition of the Ethernet driver buffers size and count */ +#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ +#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ +#define ETH_RXBUFNB ((uint32_t)4U) /* 4 Rx buffers of size ETH_RX_BUF_SIZE */ +#define ETH_TXBUFNB ((uint32_t)4U) /* 4 Tx buffers of size ETH_TX_BUF_SIZE */ + +/* Section 2: PHY configuration section */ + +/* DP83848 PHY Address*/ +#define DP83848_PHY_ADDRESS 0x01U +/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ +#define PHY_RESET_DELAY ((uint32_t)0x000000FFU) +/* PHY Configuration delay */ +#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFFU) + +#define PHY_READ_TO ((uint32_t)0x0000FFFFU) +#define PHY_WRITE_TO ((uint32_t)0x0000FFFFU) + +/* Section 3: Common PHY Registers */ + +#define PHY_BCR ((uint16_t)0x00U) /*!< Transceiver Basic Control Register */ +#define PHY_BSR ((uint16_t)0x01U) /*!< Transceiver Basic Status Register */ + +#define PHY_RESET ((uint16_t)0x8000U) /*!< PHY Reset */ +#define PHY_LOOPBACK ((uint16_t)0x4000U) /*!< Select loop-back mode */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100U) /*!< Set the full-duplex mode at 100 Mb/s */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2600U) /*!< Set the half-duplex mode at 100 Mb/s */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100U) /*!< Set the full-duplex mode at 10 Mb/s */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000U) /*!< Set the half-duplex mode at 10 Mb/s */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000U) /*!< Enable auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200U) /*!< Restart auto-negotiation function */ +#define PHY_POWERDOWN ((uint16_t)0x0800U) /*!< Select the power down mode */ +#define PHY_ISOLATE ((uint16_t)0x0400U) /*!< Isolate PHY from MII */ + +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020U) /*!< Auto-Negotiation process completed */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< Valid link established */ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002U) /*!< Jabber condition detected */ + +/* Section 4: Extended PHY Registers */ + +#define PHY_SR ((uint16_t)0x10U) /*!< PHY status register Offset */ +#define PHY_MICR ((uint16_t)0x11U) /*!< MII Interrupt Control Register */ +#define PHY_MISR ((uint16_t)0x12U) /*!< MII Interrupt Status and Misc. Control Register */ + +#define PHY_LINK_STATUS ((uint16_t)0x0001U) /*!< PHY Link mask */ +#define PHY_SPEED_STATUS ((uint16_t)0x0002U) /*!< PHY Speed mask */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0004U) /*!< PHY Duplex mask */ + +#define PHY_MICR_INT_EN ((uint16_t)0x0002U) /*!< PHY Enable interrupts */ +#define PHY_MICR_INT_OE ((uint16_t)0x0001U) /*!< PHY Enable output interrupt events */ + +#define PHY_MISR_LINK_INT_EN ((uint16_t)0x0020U) /*!< Enable Interrupt on change of link status */ +#define PHY_LINK_INTERRUPT ((uint16_t)0x2600U) /*!< PHY link status interrupt mask */ + +/* ################## Ethernet peripheral configuration ##################### */ + + + +#endif // __ETH_PHY_CONF_H + diff --git a/projects/x2660-halley/Examples/spi/spi_fullduplex_polling/include/x2600_hal_conf.h b/projects/x2660-halley/Examples/spi/spi_fullduplex_polling/include/x2600_hal_conf.h new file mode 100644 index 0000000000000000000000000000000000000000..a2f6791bd3101b4d831ec77856f54637f8f771e0 --- /dev/null +++ b/projects/x2660-halley/Examples/spi/spi_fullduplex_polling/include/x2600_hal_conf.h @@ -0,0 +1,116 @@ +#ifndef __X2600_HAL_CONF_H__ +#define __X2600_HAL_CONF_H__ +/* TODO: 本文件应该通过工具生成,在配置工程中选择不同的组件时,在此处包含不同的头文件 + 暂时包含全部头文件. +*/ + + +/* 1. Includes ---------------------------------------------------- */ + + +/* Hal Module selections. */ +#define HAL_MSC_ENABLED +#define HAL_I2C_ENABLED +#define HAL_UART_ENABLED +#define HAL_ADC_ENABLED +#define HAL_SPI_ENABLED +#define HAL_WDT_ENABLED +#define HAL_TCU_ENABLED +#define HAL_RTC_ENABLED +#define HAL_EFUSE_ENABLED +#define HAL_PWM_ENABLED +#define HAL_GMAC_ENABLED +#define HAL_USB_ENABLED + +/* 系统时钟配配置,通过工具生成,随开发板或者平台变化.*/ +#include +#include + +#include "x2600_hal_tick.h" +#include "x2600_ll_ost_core.h" +#include "x2600_ll_ost_global.h" +#include "x2600_ll_cpm.h" +#include "x2600_ll_gpio.h" + +#include "x2600_hal_pdma.h" + +//#include "x2600_hal_sfcnor.h" + +#ifdef HAL_MSC_ENABLED + +#endif + +#ifdef HAL_I2C_ENABLED +#include "x2600_hal_i2c.h" +#endif + +#ifdef HAL_UART_ENABLED +#include "x2600_hal_uart.h" +#endif + +#ifdef HAL_ADC_ENABLED +#include "x2600_hal_adc.h" +#endif + +#ifdef HAL_SPI_ENABLED +#include "x2600_hal_ssi.h" +#endif + +#ifdef HAL_WDT_ENABLED +#include "x2600_hal_wdt.h" +#endif + +#ifdef HAL_TCU_ENABLED +#include "x2600_hal_tcu.h" +#endif + +#ifdef HAL_RTC_ENABLED +#include "x2600_hal_rtc.h" +#endif + +#ifdef HAL_EFUSE_ENABLED +#include "x2600_ll_efuse.h" +#include "x2600_hal_efuse.h" +#endif + +#ifdef HAL_PWM_ENABLED +#include "x2600_hal_pwm.h" +#endif + +#ifdef HAL_GMAC_ENABLED +#include "x2600_hal_gmac.h" +#endif + +#ifdef HAL_USB_ENABLED +#include "x2600_hal_pcd.h" +#include "x2600_hal_pcd_ex.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* 2. Exported Types ---------------------------------------------- */ + +/* 3. Exported Constants ------------------------------------------ */ + +/* 4. Exported Macros --------------------------------------------- */ + +/* 5. Exported Funcs ---------------------------------------------- */ + +/* 6. Exported Variables ------------------------------------------ */ + +/* 7. Private Types ----------------------------------------------- */ + +/* 8. Private Constants ------------------------------------------- */ + +/* 9. Private Macros ---------------------------------------------- */ + +/* 10. Private Funcs ---------------------------------------------- */ + +/* 11. Private Variables ------------------------------------------ */ + +#ifdef __cplusplus +} +#endif +#endif /* __X2600_HAL_H__ */ diff --git a/projects/x2660-halley/Examples/spi/spi_fullduplex_polling/include/x2600_sysclk_conf.h b/projects/x2660-halley/Examples/spi/spi_fullduplex_polling/include/x2600_sysclk_conf.h new file mode 100644 index 0000000000000000000000000000000000000000..3c4888de77815e51f6a20b70226fc73892421676 --- /dev/null +++ b/projects/x2660-halley/Examples/spi/spi_fullduplex_polling/include/x2600_sysclk_conf.h @@ -0,0 +1,68 @@ +/** + * @file x2600_sysclk_conf.h + * @author MPU系统软件部团队 + * @brief + * + * @copyright 版权所有 (北京君正集成电路股份有限公司) {2022} + * @copyright Copyright© 2022 Ingenic Semiconductor Co.,Ltd + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __X2600_SYSCLK_CONF_H__ +#define __X2600_SYSCLK_CONF_H__ + +#ifdef __cplusplus +extern "C" { +#endif +/* 1. Includes ---------------------------------------------------- */ + +/* 2. Exported Types ---------------------------------------------- */ + + +/* 3. Exported Constants ------------------------------------------ */ + +/* 4. Exported Macros --------------------------------------------- */ +#define SYSCLK_EXTAL (24000000) +#define SYSCLK_APLL (1200000000) +#define SYSCLK_MPLL (1200000000) + +#define SystemCoreClock SYSCLK_APLL + +#define CGU_CONFIG_MSC_APLL_24M { \ + .PLLMux = MSC1CDR_SCLK_A, \ + .Div = 24, \ + .Config = 0 } + +#define CGU_CONFIG_MSC_APLL_48M { \ + .PLLMux = MSC1CDR_SCLK_A, \ + .Div = 11, \ + .Config = 0 } + + +#define CGU_CONFIG_SSI_MPLL_500K { \ + .PLLMux = SSICDR_MPLL, \ + .Div = 15, \ + .Config = 0 } + +/* 5. Exported Funcs ---------------------------------------------- */ + +/* 6. Exported Variables ------------------------------------------ */ + +/* 7. Private Types ----------------------------------------------- */ + +/* 8. Private Constants ------------------------------------------- */ + +/* 9. Private Macros ---------------------------------------------- */ + +/* 10. Private Funcs ---------------------------------------------- */ + +/* 11. Private Variables ------------------------------------------ */ + +#ifdef __cplusplus +} +#endif +#endif /* __X2600_HAL_ADC_H__ */ diff --git a/projects/x2660-halley/Examples/spi/spi_fullduplex_polling/main.c b/projects/x2660-halley/Examples/spi/spi_fullduplex_polling/main.c new file mode 100644 index 0000000000000000000000000000000000000000..972c4b5e4da9c3bbb4505e77d696296a540a287b --- /dev/null +++ b/projects/x2660-halley/Examples/spi/spi_fullduplex_polling/main.c @@ -0,0 +1,121 @@ +#include + +#define COUNTOF(__BUFFER__) (sizeof(__BUFFER__) / sizeof(*(__BUFFER__))) +#define BUFFERSIZE (COUNTOF(aTxBuffer) - 1) +#define SSI_CDR_DIVISION(__VALUE__) ((__VALUE__) - 1) + +SPI_HandleTypeDef SpiHandle; +LL_CPM_CGU_ConfigTypeDef SpiCguConfig = CGU_CONFIG_SSI_MPLL_500K; + +uint8_t aTxBuffer[] = "****SPI - Two Boards communication based on Polling **** SPI Message ******** SPI Message ******** SPI Message ******** SPI Message ******** SPI Message ****"; + +uint8_t aRxBuffer[BUFFERSIZE]; + +static uint8_t Buffercmp(uint8_t *pBuffer1, uint8_t *pBuffer2, uint16_t BufferLength); +static void Error_Handler(void); +__attribute__((unused)) static void dump_spi_reg(void); + +int main(void) +{ + prom_printk("hello world %s, %d\n", __func__, __LINE__); + + /* config clk MPLL + * MPLL SSICDR SSIGR + * (1200000000) / (15+1) / (2*(74+1)) = 500k + */ + CPM_CGU_SSI_Start(CPM_Instance, &SpiCguConfig); + + /* 使能clock gate */ + CPM_GATE_Enable(CPM_Instance, CPM_CLKID_SSI0); + + /* 内部分频 */ + WRITE_REG(SSI0_Instance->SSIGR, 0x4a); + + /* gpio 初始化 (SSI0: PB0 ~ PB3) */ + LL_GPIO_setPinMode(PB_Instance, 0, GPIO_MODE_FUNCTION0); + LL_GPIO_setPinMode(PB_Instance, 1, GPIO_MODE_FUNCTION0); + LL_GPIO_setPinMode(PB_Instance, 2, GPIO_MODE_FUNCTION0); + LL_GPIO_setPinMode(PB_Instance, 3, GPIO_MODE_FUNCTION0); + + /* 滴答时钟初始化 */ + HAL_InitTick(); + + /* 实例化SPI句柄,并初始化SPI外围设备 */ + SpiHandle.Instance = SSI0_Instance; + SpiHandle.Init.DataSize = SPI_DATASIZE_8BIT; + SpiHandle.Init.TransferEndian = SPI_T_MSB_BYTE_MSB_BIT; + SpiHandle.Init.ReceiveEndian = SPI_R_MSB_BYTE_MSB_BIT; + SpiHandle.Init.FrameVaildLevel = SPI_CE0_LOW_CE1_LOW; + SpiHandle.Init.CLKPolarity = SPI_POLARITY_LOW; + SpiHandle.Init.CLKPhase = SPI_PHASE_1EDGE; + SpiHandle.Init.LoopMode = SPI_LOOP_DISABLE; + + if (HAL_SPI_Init(&SpiHandle) != HAL_OK) { + prom_printk("DBEBUG: SPI Init error !, %s, %d\n", __func__, __LINE__); + Error_Handler(); + } + + /* 测试1: 全双工发送和接收测试 */ + if (HAL_SPI_TransmitReceive(&SpiHandle, (uint8_t *)aTxBuffer, (uint8_t *)aRxBuffer, BUFFERSIZE, 5000000) != HAL_OK) { + prom_printk("SPI Transmit Receive test is failed.\n"); + Error_Handler(); + } + + prom_printk("tx:%s\nrx:%s\n", (uint8_t *)aTxBuffer, (uint8_t *)aRxBuffer); + if (Buffercmp((uint8_t *)aTxBuffer, (uint8_t *)aRxBuffer, BUFFERSIZE)) { + prom_printk("SPI Transmit Receive test is failed.\n"); + Error_Handler(); + } else { + prom_printk("SPI Transmit Receive test is success.\n"); + } + + /* 测试2: 只发送测试 */ + if (HAL_SPI_Transmit(&SpiHandle, (uint8_t *)aTxBuffer, BUFFERSIZE, 5000000) != HAL_OK) { + prom_printk("SPI Transmit only test is failed.\n"); + Error_Handler(); + } else { + prom_printk("SPI Transmit only test, Please check the waveform.\n"); + } + + /* 测试3: 只接收测试 */ + if (HAL_SPI_Receive(&SpiHandle, (uint8_t *)aTxBuffer, 3, 5000000) != HAL_OK) { + prom_printk("SPI Receive only test is failed.\n"); + Error_Handler(); + } else { + prom_printk("SPI Receive only test, Please check the waveform.\n"); + } + + + while (1); + return 0; +} + +uint8_t Buffercmp(uint8_t *pBuffer1, uint8_t *pBuffer2, uint16_t BufferLength) +{ + while (BufferLength--) { + if (*pBuffer1 != *pBuffer2) { + return 1; + } + + pBuffer1++; + pBuffer2++; + } + + return 0; +} + +static void Error_Handler(void) +{ + prom_printk("Error Handler\n"); +} + +__attribute__((unused)) static void dump_spi_reg(void) +{ + prom_printk("SSICR0 :0x%08x\n", READ_REG(SSI0_Instance->SSICR0)); + prom_printk("SSICR1 :0x%08x\n", READ_REG(SSI0_Instance->SSICR1)); + prom_printk("SSISR :0x%08x\n", READ_REG(SSI0_Instance->SSISR)); + prom_printk("SSIITR :0x%08x\n", READ_REG(SSI0_Instance->SSIITR)); + prom_printk("SSIICR :0x%08x\n", READ_REG(SSI0_Instance->SSIICR)); + prom_printk("SSIGR :0x%08x\n", READ_REG(SSI0_Instance->SSIGR)); + prom_printk("SSIRCNT :0x%08x\n", READ_REG(SSI0_Instance->SSIRCNT)); +} diff --git a/projects/x2660-halley/Examples/spi/spi_fullduplex_polling/riscv32-gcc.cmake b/projects/x2660-halley/Examples/spi/spi_fullduplex_polling/riscv32-gcc.cmake new file mode 100644 index 0000000000000000000000000000000000000000..d09813df61ac4d343b4b4890668528bf54e9cedc --- /dev/null +++ b/projects/x2660-halley/Examples/spi/spi_fullduplex_polling/riscv32-gcc.cmake @@ -0,0 +1,18 @@ +set(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_SYSTEM_PROCESSOR riscv32) + +# Some default GCC settings +set(TOOLCHAIN_PREFIX "riscv32-ingenicv0-elf-") + +set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc) +set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) +set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g++) + +set(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}objcopy) +set(CMAKE_SIZE ${TOOLCHAIN_PREFIX}size) + +set(CMAKE_EXECUTABLE_SUFFIX_ASM ".elf") +set(CMAKE_EXECUTABLE_SUFFIX_C ".elf") +set(CMAKE_EXECUTABLE_SUFFIX_CXX ".elf") + +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)