summaryrefslogtreecommitdiff
path: root/bsp/phytium/libraries/standalone/doc/reference/driver/fspim.md
blob: 909cd4dfe5e1f1d5dbc6656f83c74293c85f728a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
# FSPIM 驱动程序

## 1. 概述


- SPI 总线是一种4线总线,提供了一种高速、高效率的串行通信技术。SPI 通信通常有一个主设备和一个或多个从设备,需要至少4根线,它们是 MISO(主设备数据输入)、MOSI(主设备数据输出)、SCLK(时钟)、CS(片选)

- 其中,CS是从芯片是否被主芯片选中的控制信号,SCLK提供时钟脉冲,SDI,SDO则基于此脉冲完成数据传输

- 本驱动程序提供了FT2000/4、D2000平台的SPI主设备功能

- FT2000/4、D2000上包含 2 个通用 SPI 接口,仅作为通用 SPI 主设备使用,外部最多挂载 4 个 SPI 从设备


## 2. 功能


- 驱动相关的源文件如下,
- drivers/spi/fspim

```
.
├── fspim.c
├── fspim.h
├── fspim_g.c
├── fspim_hw.c
├── fspim_hw.h
├── fspim_intr.c
├── fspim_options.c
└── fspim_sinit.c
```

- FSPIM 常用于读写Nor-flash,其应用可以参考以下结构,最底层的硬件是 SPI 主机控制器和 Nor-flash, 其上由 FSPIM 驱动和 SFUD 提供 Spi Nor-flash的读写接口,面向SPI文件系统,如 LittleFS 和 SPIFFS,文件系统提供负载均衡、坏块检测和断电保护等特性,并为上层应用提供文件创建/读写等接口,使用方法参考`4 应用示例` 

![spi_app](./figs/spi_app.png)

## 3. 配置方法


以下部分将指导您完成 FSPIM 驱动的软件配置:

### 3.1 使用 SFUD 通用SPI协议框架

- 使能 CONFIG_USE_FSPIM 和 CONFIG_USE_SFUD 配置
- 初始化 SFUD 框架
- 调用 SFUD 提供的 API 读写 SPI 从设备

关于 SFUD 框架的使用,可以参考[sfud.md](./sfud.md)

### 3.2 不使用 SFUD 通用SPI协议框架

- 使能 CONFIG_USE_FSPIM 配置
- 初始 FSPIM 驱动
- 调用 FSPIM 提供的 API 读写 SPI 从设备,需要按照 SPI 从设备的手册实现相关的命令和协议

## 4 应用示例

### [SPI 回环测试](../../../baremetal/example/peripheral/spi/fspim_loopback/README.md)

### [SPI Norflash读写测试](../../../baremetal/example/storage/spi_sfud/README.md)

### [SPI Norflash文件系统测试-LittleFS](../../../baremetal/example/storage/littlefs_test/README.md)

### [SPI Norflash文件系统测试-SPIFFS](../../../baremetal/example/storage/spiffs_test/README.md)

## 4. API参考

### 4.1 用户数据结构

- SPIM 驱动配置数据
```c
typedef struct
{
    u32                  instance_id;  /* Device instance id */
    uintptr              base_addr;    /* Device base address */
    u32                  irq_num;      /* Device intrrupt id */
    u32                  irq_prority;  /* Device intrrupt priority */    
    FSpimSlaveDevice     slave_dev_id; /* Slave device id */
    u32                  max_freq_hz;  /* Clock frequency in Hz */
    FSpimTransByte       n_bytes;      /* Bytes in transfer */
    FSpimCpolType        cpol;         /* Polarity of the clock */
    FSpimCphaType        cpha;         /* Phase of the clock */
    boolean              en_test;      /* Enable test mode */
} FSpimConfig;
```

- SPIM 驱动控制数据
```c
typedef struct
{
    FSpimConfig         config;      /* Current active configs */
    u32                 is_ready;    /* Device is initialized and ready */
    u32                 length;      /* Data length in transfer */
    const void          *tx_buff;    /* Tx buffer beg */
    void                *rx_buff;    /* Rx buffer beg */
    const void          *tx_buff_end; /* Tx buffer end */
    void                *rx_buff_end; /* Rx buffer end */
    u32                 tx_fifo_len;  /* Depth of tx fifo */
    u32                 rx_fifo_len;  /* Depth of rx fifo */
    FSpimEvtHandler     evt_handler[FSPIM_INTR_EVT_NUM];  /* event handler for interrupt */
    void                *evt_param[FSPIM_INTR_EVT_NUM];   /* parameters ptr of event handler */
} FSpim;
```

- SPI 从设备ID,最多支持4个从设备
```c
enum
{
    FSPIM_SLAVE_DEV_0 = 0,
    FSPIM_SLAVE_DEV_1,
    FSPIM_SLAVE_DEV_2,
    FSPIM_SLAVE_DEV_3,

    FSPIM_NUM_OF_SLAVE_DEV
};
```

- 一次 SPI 传输的数据量,一个字节或者两个字节
```c
enum
{
    FSPIM_1_BYTE = 1,
    FSPIM_2_BYTE = 2,

    FSPIM_MAX_BYTES_NUM
};
```

- SPI传输,选择接收/发送
```c
enum
{
    FSPIM_TRANS_MODE_RX_TX = 0x0,
    FSPIM_TRANS_MODE_TX_ONLY = 0x1,
    FSPIM_TRANS_MODE_RX_ONLY = 0x2,
    FSPIM_TRANS_MODE_READ_EEPROM = 0x3,

    FSPIM_TRANS_MODE_MAX
};
```

- SPI的时钟极性和相位
```c
enum
{
    FSPIM_CPOL_LOW  = 0,
    FSPIM_CPOL_HIGH
};

enum
{
    FSPIM_CPHA_1_EDGE = 0,
    FSPIM_CPHA_2_EDGE
};
```

### 4.2 错误码定义

- 模块错误码编号:0x1060000
- [0x0] FSPIM_SUCCESS : fspim success
- [0x1060000] FSPIM_SUCCESS : fspim success
- [0x1060001] FSPIM_ERR_INVAL_STATE : fspim invalid state
- [0x1060002] FSPIM_ERR_NOT_READY : fspim driver not ready
- [0x1060003] FSPIM_ERR_INVAL_PARAM : fspim invalid input parameters
- [0x1060004] FSPIM_ERR_BUS_BUSY : fspim bus is busy
- [0x1060005] FSPIM_ERR_NOT_SUPPORT : fspim not support operation
- [0x1060006] FSPIM_ERR_TIMEOUT : fspim wait timeout

### 4.3 用户API接口

#### FSpimLookupConfig

- 获取FSPIM驱动的默认配置参数

```c
const FSpimConfig *FSpimLookupConfig(u32 instance_id)
```

Note:

- 用户可以通过此接口获取驱动默认配置的副本,进行修改后,作为`FSpimCfgInitialize`函数的入参使用

Input:

- u32 instance_id, 选择的FSPIM控制器实例号

Return:

- const FSpimConfig *, 返回的默认驱动配置,返回NULL表示失败


#### FSpimCfgInitialize

- 完成FSPIM驱动实例的初始化,使之可以使用

```c
FError FSpimCfgInitialize(FSpim *instance_p, const FSpimConfig *cofig_p);
```

Note:

- 此函数会重置FSPIM控制器和FSPIM控制数据

Input:

- FSpim *instance_p, FSPIM驱动控制数据

- const FSpimConfig *input_config_p, FSPIM驱动配置数据

Return:

- FError, 驱动初始化的错误码信息,FSPIM_SUCCESS 表示初始化成功,其它返回值表示初始化失败

#### FSpimDeInitialize

- 完成FSPIM驱动实例去初始化,之后不能使用

```c
void FSpimDeInitialize(FSpim *instance_p)
```

Note:

- 此函数会重置FSPIM控制数据

Input:

- FSpim *instance_p, FSPIM驱动控制数据

Return:

无

#### FSpimTransferPollFifo
- 先发送后接收数据 (阻塞处理),利用Fifo进行处理

```c
FError FSpimTransferPollFifo(FSpim *instance_p, const void *tx_buf, void *rx_buf, fsize_t len);
```

Note:

- 使用此函数前需要确保FSPIM驱动初始化成功
- 从函数不会使用中断,会按照TX FIFO的深度进行传输,每次发送填满TX FIFO后触发发送/接收动作

Input:

- FSpim *instance_p, FSPIM驱动控制数据

- const void *tx_buf, 写缓冲区,可以为空,为空时表示只关注读数据,此时驱动会发送0xff读数据

- void *rx_buf, 读缓冲区, 可以为空,为空时表示值关注写数据,此时SPI总线上返回的数据会被抛弃

- fsize_t len, 进行传输的长度,如果tx_buf或者rx_buf不为空,则两个buf的长度必须为len

Return:

- FError, 驱动初始化的错误码信息,FSPIM_SUCCESS 表示数据交换成功,其它返回值表示交换失败

#### FSpimTransferByInterrupt

- 先发送后接收数据 (中断处理),利用Fifo进行处理

```c
FError FSpimTransferByInterrupt(FSpim *instance_p, const void *tx_buf, void *rx_buf, fsize_t len);
```

Note:

- 使用此函数前需要确保FSPIM驱动初始化成功
- 此函数会安装TX FIFO的深度进行传输,每次发送填满TX FIFO后在中断中处理发送/接收动作,用户需要注册FSPIM_INTR_EVT_RX_DONE事件,传输过程中用户处理其它任务,等待传输完成后从tx_buf和rx_buf中读数据

Input:

- FSpim *instance_p, FSPIM驱动控制数据

- const void *tx_buf, 写缓冲区,可以为空,为空时表示只关注读数据,此时驱动会发送0xff读数据

- void *rx_buf, 读缓冲区, 可以为空,为空时表示值关注写数据,此时SPI总线上返回的数据会被抛弃

- fsize_t len, 进行传输的长度,如果tx_buf或者rx_buf不为空,则两个buf的长度必须为len

Return:

- FError, 驱动初始化的错误码信息,FSPIM_SUCCESS 表示数据交换成功,其它返回值表示交换失败

#### FSpimInterruptHandler

- SPIM中断处理函数 

```c
void FSpimInterruptHandler(s32 vector, void *param);
```

Note:

- 此函数给用户注册在中断处理模块中,从而在中断触发时进行处理
- 使用此函数前,用户需要打开部分中断屏蔽位

Input:

- s32 vector, 中断向量号,此处不关心此参数

- void *param, 中断输入参数, 指向FSPIM的驱动控制实例

Return:

无

#### FSpimRegisterIntrruptHandler
- SPIM中断事件注册函数

```c
void FSpimRegisterIntrruptHandler(FSpim *instance_p, u32 evt, FSpimEvtHandler handler, void *param)
```

Note:

- 此函数与FSpimInterruptHandler配套使用,为中断处理注册事件回调函数

Input:

- FSpim *instance_p, FSPIM驱动控制数据

- u32 evt, 中断事件号码,参考FSPIM_INTR_EVT_NUM

- FSpimEvtHandler handler, 中断事件回调函数

- void *param, 中断事件回调函数的入参,取决于中断事件回调函数的实现

Return:

无

#### FSpimErrorToMessage

- 获取FSPIM驱动错误码 

```c
const char *FSpimErrorToMessage(FError error);
```

Note:

无

Input:

- FError error, FSPIM模块错误码

Return:

const char *, FSPIM模块错误码对应的信息

#### FSpimSetChipSelection

- 获取FSPIM驱动错误码 

```c
void FSpimSetChipSelection(FSpim *instance_p, boolean on);
```

Note:

无

Input:

- {FSpim} *instance_p, 驱动控制数据
- {boolean} on, TRUE: 片选打开, FALSE: 片选关闭

Return:

- 无