5.2.4. 设计说明¶
5.2.4.1. 源码说明¶
相关模块 |
源码路径 |
---|---|
PSRAM Driver |
bsp/artinchip/drv_bare/psram |
HAL |
bsp/artinchip/hal/xspi |
5.2.4.2. 模块架构¶

图 5.31 Luban-Lite XSPI PSRAM 框图¶
ArtInChip 提供了 XSPI HAL 层,并且实现了对接 DRV_BARE 的驱动层。 由于 XSPI 传输需要使用 SYSCFG 和 CMU,因此 SYSCFG HAL 和 CMU HAL 是相关模块。
5.2.4.3. HAL 与 DRV¶
ArtInChip 的 PSRAM 驱动按照 HAL 层 + Driver 层的结构进行设计,其中 HAL 层为硬件抽象层, 提供系统无关的硬件驱动实现;在 HAL 层之上,可根据不同 RTOS 的驱动框架,实现对应的 PSRAM DRV 层进行对接。

图 5.32 HAL and DRV¶
XSPI HAL 的特点:
无状态
支持 XIP,AHB 模式
XSPI HAL 相关的设备操作都需要通过 Handle 的方式进行。 由于 HAL 其内部无状态,不会进行空间分配,因此 Handle 的空间需要外部申请并且传入, 由 HAL 层进行使用。
5.2.4.4. 关键流程¶
在 bootloader 板级初始化过程中,会调用 aic_xspi_psram_init() 函数,对XSPI控制器、PSRAM设备初始化,
并开启XIP模式,系统可以通过PSRAM映射地址进行内存访问 0x40000000-0x5FFFFFFF
。
aic_xspi_psram_init(); // application\baremetal\bootloader\main.c
|-> hal_xspi_init(); // bsp\artinchip\drv_bare\psram\xspi_psram.c
|-> aic_xspi_psram_dev_init(); // bsp\artinchip\drv_bare\psram\xspi_psram.c
|-> hal_xspi_set_boudary(); // bsp\artinchip\drv_bare\psram\xspi_psram.c
|-> aic_xspi_psram_xip(); // bsp\artinchip\drv_bare\psram\xspi_psram.c
|-> hal_xspi_dll_training() // bsp\artinchip\drv_bare\psram\xspi_psram.c
|-> hal_xspi_set_parallel_mode(); // bsp\artinchip\drv_bare\psram\xspi_psram.c
5.2.4.5. 数据结构¶
5.2.4.5.1. Driver层主要数据接口¶
struct aic_xspi
{
char *name;
u32 idx;
u32 clk_id;
u32 clk_in_hz;
u32 dma_port_id;
u32 irq_num;
hal_xspi_handle handle;
bool inited;
};
小技巧
name, idx, clk_id, clk_in_hz
属性需要有相应的值,
其中 clk_id
使用 aic_clk_id.h
文件的宏定义, clk_in_hz
从配置文件中获取
5.2.4.5.2. HAL 层主要数据结构¶
struct hal_xspi_config {
u32 idx;
u32 clk_in_hz;
u32 clk_id;
u32 cs0_port;
u32 cs1_port;
bool bit_mode;
bool wire3_en;
bool lsb_en;
bool cs_auto;
u8 cs_polarity;
u8 cpol;
u8 cpha;
};
struct hal_xspi_transfer {
u8 *tx_data;
u8 *rx_data;
u32 data_len;
};
struct hal_xspi_proto_cfg {
u8 mode;
u8 clk_mode;
u8 parallel_mode;
u8 wr_cmd_clk_mode;
u8 wr_cmd_lines;
u8 wr_cmd_val;
u8 rd_cmd_clk_mode;
u8 rd_cmd_lines;
u8 rd_cmd_val;
u8 addr_clk_mode;
u8 addr_lines;
u8 addr_width;
u8 wr_dummy;
u8 rd_dummy;
u8 wr_cnt_lines;
u32 wr_cnt;
u8 rd_cnt_lines;
u32 rd_cnt;
};
struct hal_xspi_state {
u32 idx;
hal_xspi_async_cb cb;
void *cb_priv;
u32 status;
u32 clk_id;
u32 bus_hz;
u32 bus_width;
struct hal_xspi_dma_config dma_cfg;
void *dma_tx;
void *dma_rx;
u8 *async_tx; /* Used in Async Non-DMA mode */
u8 *async_rx; /* Used in Async Non-DMA mode */
u32 async_tx_remain; /* Used in Async Non-DMA mode */
u32 async_rx_remain; /* Used in Async Non-DMA mode */
u32 work_mode;
u32 done_mask;
};
5.2.4.6. 接口设计¶
5.2.4.6.1. Driver接口设计¶
5.2.4.6.1.1. aic_get_xspi_by_index¶
函数原型 |
static struct aic_xspi *aic_get_xspi_by_index(u32 idx) |
功能说明 |
获取具体XSPI控制设备 |
参数定义 |
u32 idx
XSPI 控制器编号,XSPI当前只有 0可选择。
|
返回值 |
NULL: 失败
aic_xspi 实例: 成功
|
注意事项 |
5.2.4.6.1.2. aic_xspi_psram_dev_reset¶
函数原型 |
static u32 aic_xspi_psram_dev_reset(hal_xspi_handle *handle) |
功能说明 |
reset PSRAM 模块,当前只支持 APS3208K |
参数定义 |
hal_xspi_handle *handle
XSPI 控制器句柄, 经过hal_xspi_init初始化后可得到。
|
返回值 |
0: 操作完成
|
注意事项 |
5.2.4.6.1.3. aic_xspi_psram_dev_init¶
函数原型 |
static u32 aic_xspi_psram_dev_init(hal_xspi_handle *handle) |
功能说明 |
初始化PSRAM设备 |
参数定义 |
hal_xspi_handle *handle
XSPI 控制器句柄, 经过hal_xspi_init初始化后可得到。
|
返回值 |
0: 操作完成
|
注意事项 |
5.2.4.6.1.4. aic_xspi_psram_read_id¶
函数原型 |
static u32 aic_xspi_psram_read_id(hal_xspi_handle *handle) |
功能说明 |
读取PSRAM的ID |
参数定义 |
hal_xspi_handle *handle
XSPI 控制器句柄, 经过hal_xspi_init初始化后可得到。
|
返回值 |
0: 操作完成
|
注意事项 |
该接口只是读取一遍,没有实际作用,仅作为调试使用 |
5.2.4.6.1.5. aic_xspi_psram_xip¶
函数原型 |
static u32 aic_xspi_psram_xip(hal_xspi_handle *handle, hal_xspi_proto_cfg_t proto) |
功能说明 |
读取PSRAM的ID |
参数定义 |
hal_xspi_handle *handle
XSPI 控制器句柄, 经过hal_xspi_init初始化后可得到。
hal_xspi_proto_cfg_t proto
关于XIP的相关配置
|
返回值 |
0: 操作完成
|
注意事项 |
5.2.4.6.1.6. aic_xspi_psram_icp_calc¶
函数原型 |
u32 aic_xspi_psram_icp_calc(u32 clk_in_hz) |
功能说明 |
根据配置的clock,获取ICP时钟等级 |
参数定义 |
u32 clk_in_hz
配置给XSPI的时钟值
|
返回值 |
0: AIC_XSPI_ICP_50_100M
1:AIC_XSPI_ICP_100_150M
2: AIC_XSPI_ICP_150_200M
|
注意事项 |
返回结果一般作为aic_xspi_psram_training接口的reg_icp参数。 |
5.2.4.6.1.7. aic_xspi_psram_mem_test¶
函数原型 |
static u8 aic_xspi_psram_mem_test(long address, u32 size) |
功能说明 |
PSRAM的training使用的memtest |
参数定义 |
long address
training buffer的起始地址
u32 size
training buffer的空间大小
|
返回值 |
0: 成功完成
1:失败
|
注意事项 |
需要判断是否成功 |
5.2.4.6.1.8. aic_xspi_psram_training¶
函数原型 |
u32 aic_xspi_psram_training(hal_xspi_handle *h, u8 sel, u8 reg_icp, void *psram_buf, u32 len) |
功能说明 |
PSRAM的training |
参数定义 |
hal_xspi_handle *h
XSPI 控制器 Handle
u8 sel
XSPI的CS选择,0, 1
u8 reg_icp
XSPI的时钟范围选择,ICP__50_100M = 0x0, ICP_100_150M = 0x1,
ICP_150_200M = 0x2, ICP_200_266M = 0x3.
void *psram_buf
psram的training地址,取psram的地址空间
u32 len
地址空间大小,建议256KB以上
|
返回值 |
0: 传输成功完成
1:传输失败
|
注意事项 |
需要判断是否traning成功 |
5.2.4.6.1.9. aic_xspi_psram_init¶
函数原型 |
u32 aic_xspi_psram_init(void) |
功能说明 |
读取PSRAM的ID |
参数定义 |
无
|
返回值 |
0: 操作完成
|
注意事项 |
training失败时,会打印 trainning failed, 并停止系统启动。 |
5.2.4.6.2. HAL接口设计¶
5.2.4.6.2.1. hal_xspi_init¶
函数原型 |
int hal_xspi_init(hal_xspi_handle *h, struct hal_xspi_config *cfg) |
功能说明 |
XSPI 控制器的初始化函数 |
参数定义 |
hal_xspi_handle *h
XSPI 控制器 Handle
struct hal_xspi_config *cfg
XSPI 控制器的初始化配置参数
|
返回值 |
0: 成功
其他: 失败
|
注意事项 |
初始化时,Handle 的空间由使用者负责分配和释放 |
5.2.4.6.2.2. hal_xspi_set_cmd_width¶
函数原型 |
int hal_xspi_set_cmd_width(hal_xspi_handle *h, u8 ddr_sdr_mode, u8 lines) |
功能说明 |
设置CMD传输所使用的模式和总线位宽 |
参数定义 |
hal_xspi_handle *h
XSPI 控制器 Handle
u8 ddr_sdr_mode
cmd数据设置ddr,sdr模式
u8 lines
cmd数据设置1/2/4/8线传输
|
返回值 |
0: 成功
其他: 失败
|
注意事项 |
5.2.4.6.2.3. hal_xspi_set_cmd¶
函数原型 |
int hal_xspi_set_cmd(hal_xspi_handle *h, u8 ddr_sdr_mode, u8 cmd) |
功能说明 |
设置 CMD 的模式和opcode |
参数定义 |
hal_xspi_handle *h
XSPI 控制器 Handle
u8 ddr_sdr_mode
cmd数据设置ddr,sdr模式
u8 cmd
设置 CMD 的 opcode
|
返回值 |
0: 成功
其他: 失败
|
注意事项 |
5.2.4.6.2.4. hal_xspi_set_addr_width¶
函数原型 |
int hal_xspi_set_addr_width(hal_xspi_handle *h, u8 ddr_sdr_mode, u8 lines, u8 bw_3_4_bytes) |
功能说明 |
设置 addr 的模式,传输线数,地址宽度 |
参数定义 |
hal_xspi_handle *h
XSPI 控制器 Handle
u8 ddr_sdr_mode
ADDR数据设置ddr,sdr模式, 0x0是sdr, 0x01是ddr
u8 lines
ADDR数据设置1/2/4/8线传输, 可取值 0, 1, 2, 3
u8 bw_3_4_bytes
ADDR数据的宽度,可取值 3、4
|
返回值 |
0: 成功
其他: 失败
|
注意事项 |
5.2.4.6.2.5. hal_xspi_set_addr¶
函数原型 |
int hal_xspi_set_addr(hal_xspi_handle *h, u8 addr) |
功能说明 |
设置addr的opcode |
参数定义 |
hal_xspi_handle *h
XSPI 控制器 Handle
u8 addr
addr的opcode
|
返回值 |
0: 成功
其他: 失败
|
注意事项 |
5.2.4.6.2.6. hal_xspi_set_dummy¶
函数原型 |
int hal_xspi_set_dummy(hal_xspi_handle *h, u8 lines, u8 dummy) |
功能说明 |
配置read dummy |
参数定义 |
hal_xspi_handle *h
XSPI 控制器 Handle
u8 lines
设置1/2/4/8线传输, 可取值 0, 1, 2, 3(可固定任意值)
u8 dummy
dummy个数
|
返回值 |
0: 成功
其他: 失败
|
注意事项 |
line可以设置任意值,dummy不受传输线限制 |
5.2.4.6.2.7. hal_xspi_set_write_cnt¶
函数原型 |
int hal_xspi_set_write_cnt(hal_xspi_handle *h, u8 ddr_sdr_mode, u8 lines, u32 count) |
功能说明 |
配置写data的个数 |
参数定义 |
hal_xspi_handle *h
XSPI 控制器 Handle
u8 ddr_sdr_mode
写数据设置ddr,sdr模式, 0x0是sdr, 0x01是ddr
u8 lines
设置1/2/4/8线传输, 可取值 0, 1, 2, 3
u32 count
设置写入data的个数,bytes为单位
|
返回值 |
0: 成功
其他: 失败
|
注意事项 |
u8 lines需要根据实际配置,传入的lines和count硬件会控制输出的cycle |
5.2.4.6.2.8. hal_xspi_set_read_cnt¶
函数原型 |
int hal_xspi_set_read_cnt(hal_xspi_handle *h, u8 ddr_sdr_mode, u8 lines, u32 count) |
功能说明 |
配置读data的个数 |
参数定义 |
hal_xspi_handle *h
XSPI 控制器 Handle
u8 ddr_sdr_mode
读数据设置ddr,sdr模式, 0x0是sdr, 0x01是ddr
u8 lines
设置1/2/4/8线传输, 可取值 0, 1, 2, 3
u32 count
设置读入data的个数,bytes为单位
|
返回值 |
0: 成功
其他: 失败
|
注意事项 |
u8 lines需要根据实际配置,传入的lines和count硬件会控制输出的cycle |
5.2.4.6.2.9. hal_xspi_start_transfer¶
函数原型 |
int hal_xspi_start_transfer(hal_xspi_handle *h) |
功能说明 |
开始传输使能 |
参数定义 |
hal_xspi_handle *h
XSPI 控制器 Handle
|
返回值 |
0: 成功
其他: 失败
|
注意事项 |
5.2.4.6.2.10. hal_xspi_transfer_cpu_sync¶
函数原型 |
int hal_xspi_transfer_cpu_sync(hal_xspi_handle *h, struct hal_xspi_transfer *t) |
功能说明 |
数据传输配置,写入fifo。 |
参数定义 |
hal_xspi_handle *h
XSPI 控制器 Handle
struct hal_xspi_transfer *t
数据结构体
|
返回值 |
0: 传输成功完成
|
注意事项 |
5.2.4.6.2.11. hal_xspi_xip_cfg¶
函数原型 |
int hal_xspi_xip_cfg(hal_xspi_handle *h, hal_xspi_proto_cfg_t xip_proto_cfg) |
功能说明 |
XSPI 的XIP配置,根据实际的psram设备协议写入XIP指令 |
参数定义 |
hal_xspi_handle *h
XSPI 控制器 Handle
hal_xspi_proto_cfg_t xip_proto_cfg
psram设备协议XIP指令
|
返回值 |
0: 设置完成
|
注意事项 |
5.2.4.6.2.12. hal_xspi_xip_enable¶
函数原型 |
int hal_xspi_xip_enable( hal_xspi_handle *h) |
功能说明 |
XSPI 的XIP使能 |
参数定义 |
hal_xspi_handle *h
XSPI 控制器 Handle
|
返回值 |
0: 设置完成
|
注意事项 |
在hal_xspi_xip_cfg()后调用 |
5.2.4.6.2.13. hal_xspi_set_cs¶
函数原型 |
int hal_xspi_set_cs(hal_xspi_handle *h, u8 sel) |
功能说明 |
数据传输配置,写入fifo。 |
参数定义 |
hal_xspi_handle *h
XSPI 控制器 Handle
u8 sel
XSPI的CS选择,0, 1
|
返回值 |
0: 设置完成
|
注意事项 |
5.2.4.6.2.14. hal_xspi_set_boudary¶
函数原型 |
int hal_xspi_set_boudary(hal_xspi_handle *h, u8 by) |
功能说明 |
数据切割,根据具体psram配置 |
参数定义 |
hal_xspi_handle *h
XSPI 控制器 Handle
u8 by
数据长度切割,可选xspi_2k = 0x0, xspi_1k = 0x1,
|
返回值 |
0: 设置完成
|
注意事项 |
5.2.4.6.2.15. hal_xspi_set_parallel_mode¶
函数原型 |
int hal_xspi_set_parallel_mode(hal_xspi_handle *h, u8 mode) |
功能说明 |
使用双/单片 PSRAM配置。 |
参数定义 |
hal_xspi_handle *h
XSPI 控制器 Handle
u8 mode
单片或双片配置,可选single_mode = 0x0, parellel_mode = 0x1
|
返回值 |
0: 设置完成
|
注意事项 |
5.2.4.6.2.16. hal_xspi_set_dll_ctl¶
函数原型 |
int hal_xspi_set_dll_ctl(hal_xspi_handle *h, u8 sel, u8 reg_icp, u8 phase_sel) |
功能说明 |
时钟采样相位和时钟频率等级配置,需要传入与时钟频率等级和相位值,一般在training得到稳定相位时传入。 |
参数定义 |
hal_xspi_handle *h
XSPI 控制器 Handle
u8 sel
XSPI的CS选择,0, 1
u8 reg_icp
时钟频率等级,ICP_50_100M,ICP_100_150M, ICP_150_200M。
u8 phase_sel
相位等级配置(0x00-0x0f)
|
返回值 |
0: 设置完成
|
注意事项 |
5.2.4.6.2.17. hal_xspi_set_phase_sel¶
函数原型 |
int hal_xspi_set_phase_sel(hal_xspi_handle *h, u8 sel, u8 phase_sel) |
功能说明 |
时钟采样相位配置,需要传入相位值,一般在training过程尝试不同相位时配置。 |
参数定义 |
hal_xspi_handle *h
XSPI 控制器 Handle
u8 sel
XSPI的CS选择,0, 1
u8 phase_sel
相位等级配置(0x00-0x0f)
|
返回值 |
0: 设置完成
|
注意事项 |