rt-thread/bsp/phytium/libraries/standalone/drivers/spi/fspim/fspim_hw.h

588 lines
18 KiB
C
Raw Normal View History

/*
* Copyright : (C) 2022 Phytium Information Technology, Inc.
* All Rights Reserved.
*
* This program is OPEN SOURCE software: you can redistribute it and/or modify it
* under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
* either version 1.0 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the Phytium Public License for more details.
*
*
* FilePath: fspim_hw.h
* Date: 2022-02-10 14:53:42
* LastEditTime: 2022-02-18 09:08:05
* Description:  This files is for
*
* Modify History:
* Ver   Who        Date         Changes
* ----- ------     --------    --------------------------------------
* 1.0 zhugengyu 2021-12-3 init commit
* 1.1 zhugengyu 2022-4-15 support test mode
* 1.2 zhugengyu 2022-5-13 support spi dma
*/
#ifndef DRIVERS_FSPIM_M_HW_H
#define DRIVERS_FSPIM_M_HW_H
#ifdef __cplusplus
extern "C"
{
#endif
/***************************** Include Files *********************************/
#include "fparameters.h"
#include "fkernel.h"
#include "fio.h"
#include "ftypes.h"
/************************** Constant Definitions *****************************/
/** @name Register Map
*
* Register offsets from the base address of an SD device.
* @{
*/
/* offset map of SPI register */
#define FSPIM_CTRL_R0_OFFSET 0x00 /* Ctrl register 0 */
#define FSPIM_CTRL_R1_OFFSET 0x04 /* Ctrl register 1 */
#define FSPIM_SSIENR_OFFSET 0x08 /* SPI enable register */
#define FSPIM_MWCR_OFFSET 0x0c /* Microwire ctrl register */
#define FSPIM_SER_OFFSET 0x10 /* Slave enable register */
#define FSPIM_BAUD_R_OFFSET 0x14 /* Baudrate set register */
#define FSPIM_TXFTL_R_OFFSET 0x18 /* Tx threshold register */
#define FSPIM_RXFTL_R_OFFSET 0x1c /* Rx threshold register */
#define FSPIM_TXFLR_OFFSET 0x20 /* Tx level register */
#define FSPIM_RXFLR_OFFSET 0x24 /* Rx level register */
#define FSPIM_SR_OFFSET 0x28 /* Status register */
#define FSPIM_IMR_OFFSET 0x2c /* Intr mask register */
#define FSPIM_ISR_OFFSET 0x30 /* Irq Status register */
#define FSPIM_RIS_R_OFFSET 0x34 /* Intr status register */
#define FSPIM_TXOI_CR_OFFSET 0x38 /* TX FIFO overflow intr clear register */
#define FSPIM_RXOI_CR_OFFSET 0x3c /* RX FIFO overflow intr clear register */
#define FSPIM_RXUI_CR_OFFSET 0x40 /* TX FIFO underflow intr clear register */
#define FSPIM_MSTI_CR_OFFSET 0x44 /* Multi slave intr clear register */
#define FSPIM_ICR_OFFSET 0x48 /* Intr clear register */
#define FSPIM_DMA_CR_OFFSET 0x4c /* DMA ctrl register */
#define FSPIM_DMA_TDLR_OFFSET 0x50 /* DMA TX Data level register */
#define FSPIM_DMA_RDLR_OFFSET 0x54 /* DMA RX Data level register */
#define FSPIM_IDR_OFFSET 0x58 /* Identification register */
#define FSPIM_DR_OFFSET 0x60 /* Data register */
#define FSPIM_RX_SAMPLE_DLY_OFFSET 0xfc /* RX Data delay register */
#define FSPIM_CS_OFFSET 0x100 /* Chip selection register */
/** @name FSPIM_CTRL_R0_OFFSET Register
*/
#define FSPIM_CTRL_R0_DFS_MASK GENMASK(3, 0)
#define FSPIM_CTRL_R0_DFS(x) (FSPIM_CTRL_R0_DFS_MASK & ((x) << 0)) /* 选择数据长度 */
#define FSPIM_CTRL_R0_FRF(x) (GENMASK(5, 4) & ((x) << 4)) /* 选择传输模式 */
#define FSPIM_CTRL_R0_SCPHA(x) ((x) << 6) /* 串行时钟相位 */
#define FSPIM_CTRL_R0_SCPHA_MASK BIT(6)
enum
{
FSPIM_SCPHA_SWITCH_DATA_MID = 0x0,
FSPIM_SCPHA_SWITCH_DATA_BEG = 0x1
};
#define FSPIM_CTRL_R0_SCPOL(x) ((x) << 7) /* 串行时钟极性 */
#define FSPIM_CTRL_R0_SCPOL_MASK BIT(7)
enum
{
FSPIM_SCPOL_INACTIVE_LOW = 0,
FSPIM_SCPOL_INACTIVE_HIGH = 1
};
#define FSPIM_CTRL_R0_TMOD_MASK GENMASK(9, 8)
#define FSPIM_CTRL_R0_TMOD(x) (FSPIM_CTRL_R0_TMOD_MASK & ((x) << 8)) /* 传输模式控制位 */
#define FSPIM_CTRL_R0_TMOD_SHIFT 8
enum
{
FSPIM_TMOD_RX_TX = 0b00,
FSPIM_TMOD_TX_ONLY = 0b01,
FSPIM_TMOD_RX_ONLY = 0b10,
FSPIM_TMOD_RD_EEPROM = 0b11
};
#define FSPIM_CTRL_R0_SLV_OE(x) ((x) << 10) /* 从机发送逻辑使能位 */
#define FSPIM_CTRL_R0_SLV_OE_MASK BIT(10)
enum
{
FSPIM_SLAVE_TX_ENABLE = 0,
FSPIM_SLAVE_TX_DISALE = 1
};
#define FSPIM_CTRL_R0_SLV_SRL(x) ((x) << 11) /* 移位寄存器回环 */
enum
{
FSPIM_SRL_NORAML = 0,
FSPIM_SRL_TEST = 1
};
#define FSPIM_CTRL_R0_CFS(x) (GENMASK(5, 12) & ((x) << 12)) /* 数据大小控制位,用于 Microwire 模式 */
/** @name FSPIM_CTRL_R1_OFFSET Register
*/
/* FSPIM_TMOD_RX_ONLY 或 FSPIM_TMOD_RD_EEPROM 该字段设置为 SPI 连续接收的数据量 */
#define FSPIM_CTRL_R1_NDF(x) (GENMASK(15, 0) & ((x) << 0))
#define FSPIM_CTRL_R1_NDF_64KB 0b11
/** @name FSPIM_SSIENR_OFFSET Register
*/
#define FSPIM_SSIENR_SSI_EN(x) ((x) << 0) /* SPI 使能启用和禁用所有 SPI 操作 */
/** @name FSPIM_MWCR_OFFSET Register
*/
#define FSPIM_MWCR_MW_MOD(x) ((x) << 0) /* Microwire 传输模式 */
enum
{
FSPIM_MWMODE_NO_CONT_TRANS = 0, /* 非连续传输 */
FSPIM_MWMODE_CONT_TRANS = 1 /* 连续传输 */
};
#define FSPIM_MWCR_MDD(x) ((x) << 1) /* Microwire 控制位 */
enum
{
FSPIM_MWCR_RX_EXT = 0, /* 从外部串行设备接收数据 */
FSPIM_MWCR_TX_EXT /* 数据发送到外部串行设备 */
};
#define FSPIM_MWCR_MHS(x) ((x) << 2) /* Microwire 握手 */
enum
{
FSPU_MWCR_DISABLE_HANDSHAKING = 0,
FSPU_MWCR_ENABLE_HANDSHAKING = 1
};
/** @name FSPIM_SER_OFFSET Register
*/
#define FSPIM_SER(x) (GENMASK(3, 0) & ((x) << 0)) /* 从机选择信号启动标志 */
/* 寄存器中的每一个位都对应来自 SPI 主机的从选信号(ss_x_n]).当此寄
1 , */
enum
{
FSPIM_SER_UNSELECT = 0x0,
FSPIM_SER_SELECT = 0x1
};
/** @name FSPIM_BAUD_R_OFFSET Register
*/
#define FSPIM_BAUD_R_SCKDV(x) (GENMASK(15, 0) & ((x) << 0)) /* SCKDV 为 2 ~ 65534 之间的任何偶数值 */
#define FSPIM_BAUD_R_SCKDV_MIN 2
#define FSPIM_BAUD_R_SCKDV_MAX 65534
#define FSPIM_BAUD_R_SCKDV_IS_VALID(x) (0 == (x) % 2)
/** @name FSPIM_TXFTL_R_OFFSET Register
*/
#define FSPIM_TXFTL_R_TFT(x) (GENMASK(2, 0) & ((x) << 0)) /* 发送 FIFO 阙值 */
/** @name FSPIM_RXFTL_R_OFFSET Register
*/
#define FSPIM_RXFTL_R_RFT(x) (GENMASK(3, 0) & ((x) << 0)) /* 接收 FIFO 阙值 */
/** @name FSPIM_TXFLR_OFFSET Register
*/
#define FSPIM_TXFLR_TXTFL(x) (GENMASK(3, 0) & ((x) << 0)) /* 发送 FIFO 等级 */
/** @name FSPIM_RXFLR_OFFSET Register
*/
#define FSPIM_RXFLR_RXTFL(x) (GENMASK(3, 0) & ((x) << 0)) /* 接收 FIFO 等级 */
/** @name FSPIM_SR_OFFSET Register, RO
*/
#define FSPIM_SR_BUSY BIT(0) /* SPI 总线繁忙标志位 */
#define FSPIM_SR_TFNF BIT(1) /* 发送 FIFO 不满 */
#define FSPIM_SR_TFE BIT(2) /* 发送 FIFO 为空 */
#define FSPIM_SR_RFNE BIT(3) /* 接收 FIFO 不为空 */
#define FSPIM_SR_RFF BIT(4) /* 接收 FIFO 满 */
#define FSPIM_SR_TXE BIT(5) /* 传输错误 */
#define FSPIM_SR_DCOL BIT(6) /* 传输数据冲突错误 */
#define FSPIM_SR_ALL_BITS GENMASK(0, 6)
/** @name FSPIM_IMR_OFFSET Register
*/
#define FSPIM_IMR_TXEIS BIT(0) /* 发送 FIFO 空中断 */
#define FSPIM_IMR_TXOIS BIT(1) /* 发送 FIFO 上溢中断 */
#define FSPIM_IMR_RXUIS BIT(2) /* 接收 FIFO 下溢中断 */
#define FSPIM_IMR_RXOIS BIT(3) /* 接收 FIFO 上溢中断 */
#define FSPIM_IMR_RXFIS BIT(4) /* 接收 FIFO 满中断 */
#define FSPIM_IMR_ALL_BITS GENMASK(4, 0)
/** @name FSPIM_ISR_OFFSET Register
*/
#define FSPIM_ISR_TXEIS BIT(0) /* 发送 FIFO 空中断状态 */
#define FSPIM_ISR_TXOIS BIT(1) /* 发送 FIFO 上溢中断状态 */
#define FSPIM_ISR_RXUIS BIT(2) /* 接收 FIFO 下溢中断状态 */
#define FSPIM_ISR_RXOIS BIT(3) /* 接收 FIFO 上溢中断状态 */
#define FSPIM_ISR_RXFIS BIT(4) /* 接收 FIFO 满中断状态 */
#define FSPIM_ISR_MSTIS BIT(5) /* 多主机竞争中断状态 */
/** @name FSPIM_RIS_R_OFFSET Register
*/
#define FSPIM_RIS_R_TXEIR BIT(0) /* 传输 FIFO 空生成中断状态 */
#define FSPIM_RIS_R_TXOIR BIT(1) /* 传输 FIFO 上溢生成中断状态 */
#define FSPIM_RIS_R_RXUIR BIT(2) /* 接收 FIFO 下溢生成中断状态 */
#define FSPIM_RIS_R_RXOIR BIT(3) /* 接收 FIFO 上溢生成中断状态 */
#define FSPIM_RIS_R_RXFIR BIT(4) /* 接收 FIFO 满生成中断状态 */
#define FSPIM_RIS_R_MSTIR BIT(5) /* 多主机冲突生成中断状态 */
#define FSPIM_RIS_R_ALL_BITS GENMASK(5, 0)
/** @name FSPIM_TXOI_CR_OFFSET Register
*/
#define FSPIM_TXOICR BIT(0) /* 清除传输 FIFO 溢出中断 */
/** @name FSPIM_RXOI_CR_OFFSET Register
*/
#define FSPIM_RXOICR BIT(0) /* 清除传输 FIFO 溢出中断 */
/** @name FSPIM_RXUI_CR_OFFSET Register
*/
#define FSPIM_RXUICR BIT(0) /* 清除传输 FIFO 下溢中断 */
/** @name FSPIM_MSTI_CR_OFFSET Register
*/
#define FSPIM_MSTICR BIT(0) /* 清除多主争用中断 */
/** @name FSPIM_ICR_OFFSET Register
*/
#define FSPIM_ICR BIT(0) /* 清除中断 */
/** @name FSPIM_DMA_CR_OFFSET Register
*/
#define FSPIM_DMA_CR_RDMAE BIT(0) /* DMA 接收使能 */
#define FSPIM_DMA_CR_TDMAE BIT(1) /* DMA 发送使能 */
/** @name FSPIM_DMA_TDLR_OFFSET Register
*/
#define FSPIM_DMATDL(x) (GENMASK(2, 0) & ((x) << 0)) /* 发送数据等级 */
/** @name FSPIM_DMA_RDLR_OFFSET Register
*/
#define FSPIM_DMARDL(x) (GENMASK(2, 0) & ((x) << 0)) /* 接收数据等级 */
/** @name FSPIM_IDR_OFFSET Register
*/
#define FSPIM_IDCODE(x) (GENMASK(31, 0) & ((x) << 0)) /* 识别码。即外部设备标识代码 */
/** @name FSPIM_DR_OFFSET Register
*/
#define FSPIM_DR(x) (GENMASK(15, 0) & ((x) << 0)) /* 数据寄存器 */
/** @name FSPIM_RX_SAMPLE_DLY_OFFSET Register
*/
#define FSPIM_RSD(x) (GENMASK(7, 0) & ((x) << 0)) /* 接收数据延时 */
/** @name FSPIM_CS_OFFSET Register
*/
#define FSPIM_NUM_OF_CS 4U
#define FSPIM_CHIP_SEL_EN(cs) BIT((cs) + FSPIM_NUM_OF_CS) /* 1: enable chip selection */
#define FSPIM_CHIP_SEL(cs) BIT(cs)
#define FSPIM_DEFAULT_DFS 0x7
#define FSPIM_DEFAULT_FRF 0x0
#define FSPIM_DEFAULT_RSD 0x6
#define FSPIM_DEFAULT_CFS 0x0
#define FSPIM_MIN_FIFO_DEPTH 0
#define FSPIM_MAX_FIFO_DEPTH 256
#define FSPIM_TIMEOUT 256
#define FSPIM_TX_DMA_LEVEL 0x10
#define FSPIM_RX_DMA_LEVEL 0xf
/**************************** Type Definitions *******************************/
/************************** Variable Definitions *****************************/
/***************** Macros (Inline Functions) Definitions *********************/
#define FSPIM_READ_REG32(addr, reg_offset) FtIn32((addr) + (u32)(reg_offset))
#define FSPIM_WRITE_REG32(addr, reg_offset, reg_value) FtOut32((addr) + (u32)(reg_offset), (u32)(reg_value))
/**
* @name: FSpimSetCtrlR0
* @msg: CTRL_R0寄存器
* @return {*}
* @param {uintptr} base_addr
* @param {u32} val
*/
static inline void FSpimSetCtrlR0(uintptr base_addr, u32 val)
{
FSPIM_WRITE_REG32(base_addr, FSPIM_CTRL_R0_OFFSET, val);
}
/**
* @name: FSpimGetCtrlR0
* @msg: CTRL_R0寄存器的值
* @return {*}
* @param {uintptr} base_addr
*/
static inline u32 FSpimGetCtrlR0(uintptr base_addr)
{
return FSPIM_READ_REG32(base_addr, FSPIM_CTRL_R0_OFFSET);
}
/**
* @name: FSpimSetCtrlR0
* @msg: CTRL_R1寄存器
* @return {*}
* @param {uintptr} base_addr
* @param {u32} val
*/
static inline void FSpimSetCtrlR1(uintptr base_addr, u32 val)
{
FSPIM_WRITE_REG32(base_addr, FSPIM_CTRL_R1_OFFSET, val);
}
/**
* @name: FSpimSetTxFifoThreshold
* @msg: TX Fifo阈值
* @return {*}
* @param {uintptr} base_addr
* @param {u32} val
*/
static inline void FSpimSetTxFifoThreshold(uintptr base_addr, u32 val)
{
FSPIM_WRITE_REG32(base_addr, FSPIM_TXFTL_R_OFFSET, val);
}
/**
* @name: FSpimGetTxFifoThreshold
* @msg: TX Fifo阈值
* @return {*}
* @param {uintptr} base_addr
*/
static inline u32 FSpimGetTxFifoThreshold(uintptr base_addr)
{
return FSPIM_READ_REG32(base_addr, FSPIM_TXFTL_R_OFFSET);
}
/**
* @name: FSpimSetRxFifoThreshold
* @msg: RX Fifo阈值
* @return {*}
* @param {uintptr} base_addr
* @param {u32} val
*/
static inline void FSpimSetRxFifoThreshold(uintptr base_addr, u32 val)
{
FSPIM_WRITE_REG32(base_addr, FSPIM_RXFTL_R_OFFSET, val);
}
/**
* @name: FSpimGetRxFifoThreshold
* @msg: RX Fifo阈值
* @return {*}
* @param {uintptr} base_addr
*/
static inline u32 FSpimGetRxFifoThreshold(uintptr base_addr)
{
return FSPIM_READ_REG32(base_addr, FSPIM_RXFTL_R_OFFSET);
}
/**
* @name: FSpimGetTxFifoLevel
* @msg: TX Fifo等级
* @return {*}
* @param {uintptr} base_addr
*/
static inline u32 FSpimGetTxFifoLevel(uintptr base_addr)
{
return FSPIM_READ_REG32(base_addr, FSPIM_TXFLR_OFFSET);
}
/**
* @name: FSpimGetRxFifoLevel
* @msg: RX Fifo等级
* @return {*}
* @param {uintptr} base_addr
*/
static inline u32 FSpimGetRxFifoLevel(uintptr base_addr)
{
return FSPIM_READ_REG32(base_addr, FSPIM_RXFLR_OFFSET);
}
/**
* @name: FSpimGetTxDMALevel
* @msg: TX DMA等级
* @return {*}
* @param {uintptr} base_addr
*/
static inline u32 FSpimGetTxDMALevel(uintptr base_addr)
{
return FSPIM_READ_REG32(base_addr, FSPIM_DMA_TDLR_OFFSET);
}
/**
* @name: FSpimGetRxDMALevel
* @msg: RX DMA等级
* @return {*}
* @param {uintptr} base_addr
*/
static inline u32 FSpimGetRxDMALevel(uintptr base_addr)
{
return FSPIM_READ_REG32(base_addr, FSPIM_DMA_RDLR_OFFSET);
}
/**
* @name: FSpimSetTxDMALevel
* @msg: TX DMA等级
* @return {*}
* @param {uintptr} base_addr
* @param {u32} level, TX DMA等级, FIFO阈值保持一致
*/
static inline void FSpimSetTxDMALevel(uintptr base_addr, u32 level)
{
FSPIM_WRITE_REG32(base_addr, FSPIM_DMA_TDLR_OFFSET, level);
}
/**
* @name: FSpimSetRxDMALevel
* @msg: RX DMA等级
* @return {*}
* @param {uintptr} base_addr
* @param {u32} level, RX DMA等级, FIFO阈值保持一致
*/
static inline void FSpimSetRxDMALevel(uintptr base_addr, u32 level)
{
FSPIM_WRITE_REG32(base_addr, FSPIM_DMA_RDLR_OFFSET, level);
}
/**
* @name: FSpimGetEnable
* @msg: FSPIM控制器的使能状态
* @return {*}
* @param {uintptr} base_addr
*/
static inline boolean FSpimGetEnable(uintptr base_addr)
{
return FSPIM_READ_REG32(base_addr, FSPIM_SSIENR_OFFSET);
}
/**
* @name: FSpimSetEnable
* @msg: 使/使FSPIM控制器
* @return {*}
* @param {uintptr} base_addr
* @param {boolean} enable
*/
static inline void FSpimSetEnable(uintptr base_addr, boolean enable)
{
if (enable)
FSPIM_WRITE_REG32(base_addr, FSPIM_SSIENR_OFFSET, FSPIM_SSIENR_SSI_EN(1));
else
FSPIM_WRITE_REG32(base_addr, FSPIM_SSIENR_OFFSET, FSPIM_SSIENR_SSI_EN(0));
}
/**
* @name: FSpimMaskIrq
* @msg: 使
* @return {*}
* @param {uintptr} base_addr
* @param {u32} mask
*/
static inline void FSpimMaskIrq(uintptr base_addr, u32 mask)
{
u32 curr_mask;
curr_mask = FSPIM_READ_REG32(base_addr, FSPIM_IMR_OFFSET) & ~mask; /* = 0 中断不活动*/
FSPIM_WRITE_REG32(base_addr, FSPIM_IMR_OFFSET, curr_mask);
}
/**
* @name: FSpimUmaskIrq
* @msg: 使
* @return {*}
* @param {uintptr} base_addr
* @param {u32} mask
*/
static inline void FSpimUmaskIrq(uintptr base_addr, u32 mask)
{
u32 curr_mask;
curr_mask = FSPIM_READ_REG32(base_addr, FSPIM_IMR_OFFSET) | mask; /* = 1 中断活动 */
FSPIM_WRITE_REG32(base_addr, FSPIM_IMR_OFFSET, curr_mask);
}
/**
* @name: FSpimGetMask
* @msg:
* @return {*}
* @param {uintptr} base_addr
*/
static inline u32 FSpimGetMask(uintptr base_addr)
{
return FSPIM_IMR_ALL_BITS & FSPIM_READ_REG32(base_addr, FSPIM_IMR_OFFSET);
}
/**
* @name: FSpimGetTransMode
* @msg:
* @return {*}
* @param {uintptr} base_addr
*/
static inline u32 FSpimGetTransMode(uintptr base_addr)
{
return ((FSpimGetCtrlR0(base_addr) & FSPIM_CTRL_R0_TMOD_MASK) >> FSPIM_CTRL_R0_TMOD_SHIFT);
}
/**
* @name: FSpimGetStatus
* @msg: FSPIM控制器状态
* @return {*}
* @param {uintptr} base_addr
*/
static inline u32 FSpimGetStatus(uintptr base_addr)
{
return FSPIM_READ_REG32(base_addr, FSPIM_SR_OFFSET);
}
/**
* @name: FSpimWriteData
* @msg: SPI数据
* @return {*}
* @param {uintptr} base_addr
* @param {u16} dat
*/
static inline void FSpimWriteData(uintptr base_addr, u16 dat)
{
FSPIM_WRITE_REG32(base_addr, FSPIM_DR_OFFSET, FSPIM_DR(dat));
}
/**
* @name: FSpimReadData
* @msg: SPI数据
* @return {*}
* @param {uintptr} base_addr
*/
static inline u16 FSpimReadData(uintptr base_addr)
{
return (u16)(FSPIM_READ_REG32(base_addr, FSPIM_DR_OFFSET));
}
/************************** Function Prototypes ******************************/
/* 使能/去使能和从设备的连接 */
void FSpimSetSlaveEnable(uintptr base_addr, boolean enable);
/* 获取TX Fifo可以设置的最大深度 */
u32 FSpimGetTxFifoDepth(uintptr base_addr);
/* 获取RX Fifo可以设置的最大深度 */
u32 FSpimGetRxFifoDepth(uintptr base_addr);
/* 选择SPI从设备 */
void FSpimSelSlaveDev(uintptr base_addr, u32 slave_dev_id);
/* 设置SPI传输速度 */
FError FSpimSetSpeed(uintptr base_addr, u32 speed);
/* 设置SPI传输模式 */
void FSpimSetTransMode(uintptr base_addr, u32 trans_mode);
/* 设置串行时钟相位 */
void FSpimSetCpha(uintptr base_addr, u32 cpha_mode);
/* 设置串行时钟极性 */
void FSpimSetCpol(uintptr base_addr, u32 cpol_mode);
#ifdef __cplusplus
}
#endif
#endif // !