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
|
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-07-30 Emuzit first version
*/
#ifndef __CH56X_SPI_H__
#define __CH56X_SPI_H__
#include "soc.h"
#include "ch56x_gpio.h"
#ifdef __cplusplus
extern "C" {
#endif
#define SPI0_BUS_NAME "spi0"
#define SPI1_BUS_NAME "spi1"
#ifndef SPI0_SCS_PIN
#define SPI0_SCS_PIN GET_PIN(A, 12)
#endif
#define SPI0_SCK_PIN GET_PIN(A, 13)
#define SPI0_MOSI_PIN GET_PIN(A, 14)
#define SPI0_MISO_PIN GET_PIN(A, 15)
#ifdef SOC_SERIES_CH569
#ifndef SPI1_SCS_PIN
#define SPI1_SCS_PIN GET_PIN(B, 11)
#endif
#define SPI1_SCK_PIN GET_PIN(B, 12)
#define SPI1_MOSI_PIN GET_PIN(B, 13)
#define SPI1_MISO_PIN GET_PIN(B, 14)
#else
#define SPI1_SCK_PIN GET_PIN(A, 0)
#define SPI1_MOSI_PIN GET_PIN(A, 1)
#define SPI1_MISO_PIN GET_PIN(A, 2)
#endif
#define SPI_FIFO_SIZE 8
union _spi_ctrl_mod
{
uint8_t reg;
struct
{
uint8_t mode_slave : 1; // RW, SPI master/slave (0/1) mode select
uint8_t all_clear : 1; // RW, clear FIFO/count/int-flag
uint8_t two_wire : 1; // RW, 2/3-wire mode (0/1), SPI slave
uint8_t mst_sck_mod : 1; // RW, mode0/mode3 (0/1) for SCK idle L/H
uint8_t fifo_dir : 1; // RW, FIFO direction is output/input (0/1)
uint8_t sck_oe : 1; // RW, SCK pin output enable
uint8_t mosi_oe : 1; // RW, MOSI pin output enable
uint8_t miso_oe : 1; // RW, MISO pin output enable
};
struct
{
uint8_t stuff_0 : 3;
uint8_t slv_cmd_mod : 1; // RW, 1st byte is data/cmd (0/1), SPI slave
uint8_t stuff_4 : 4;
};
};
#define RB_SPI_MODE_SLAVE 0x01
#define RB_SPI_ALL_CLEAR 0x02
#define RB_SPI_2WIRE_MOD 0x04
#define RB_SPI_MST_SCK_MOD 0x08
#define RB_SPI_SLV_CMD_MOD 0x08
#define RB_SPI_FIFO_DIR 0x10
#define RB_SPI_SCK_OE 0x20
#define RB_SPI_MOSI_OE 0x40
#define RB_SPI_MISO_OE 0x80
#define MST_SCK_MOD_0 0
#define MST_SCK_MOD_3 1
#define SPI_FIFO_DIR_OUTPUT 0
#define SPI_FIFO_DIR_INPUT 1
union _spi_ctrl_cfg
{
uint8_t reg;
struct
{
uint8_t dma_enable : 1; // RW, enable DMA function
uint8_t resv_1 : 1;
uint8_t dma_loop : 1; // RW, enable DMA loop mode (0 => single)
uint8_t resv_3 : 1;
uint8_t auto_if : 1; // RW, enable auto clear RB_SPI_IF_BYTE_END
uint8_t bit_order : 1; // RW, data bit ordering, LSB/MSB first (0/1)
uint8_t resv_6 : 2;
};
};
#define RB_SPI_DMA_ENABLE 0x01
#define RB_SPI_DMA_LOOP 0x04
#define RB_SPI_AUTO_IF 0x10
#define RB_SPI_BIT_ORDER 0x20
#define SPI_BIT_ORDER_MSB 0
#define SPI_BIT_ORDER_LSB 1
union _spi_inter_en
{
uint8_t reg;
struct
{
uint8_t cnt_end : 1; // RW, IE for all bytes transfered
uint8_t byte_end : 1; // RW, IE for single byte transfered
uint8_t fifo_hf : 1; // RW, IE for FIFO half full
uint8_t dma_end : 1; // RW, IE for end of DMA
uint8_t fifo_ov : 1; // RW, IE for FIFO full or empty
uint8_t resv_5 : 2;
uint8_t fst_byte : 1; // RW, IE for 1st byte received, SPI slave
};
};
#define RB_SPI_IE_CNT_END 0x01
#define RB_SPI_IE_BYTE_END 0x02
#define RB_SPI_IE_FIFO_HF 0x04
#define RB_SPI_IE_DMA_END 0x08
#define RB_SPI_IE_FIFO_OV 0x10
#define RB_SPI_IE_FST_BYTE 0x80
union _spi_run_flag
{
uint8_t reg;
struct
{
uint8_t resv_0 : 4;
uint8_t slv_cmd_act : 1; // RO, SPI slave cmd received
uint8_t fifo_ready : 1; // RO, SPI FIFO ready to transfer
uint8_t slv_cs_load : 1; // RO, SPI slave is loading R8_SPIx_SLAVE_PRE
uint8_t slv_select : 1; // RO, SPI slave CS active (selected)
};
};
#define RB_SPI_SLV_CMD_ACT 0x10
#define RB_SPI_FIFO_READY 0x20
#define RB_SPI_SLV_CS_LOAD 0x40
#define RB_SPI_SLV_SELECT 0x80
union _spi_int_flag
{
uint8_t reg;
struct
{
uint8_t cnt_end : 1; // RW1, IF for all bytes transfered
uint8_t byte_end : 1; // RW1, IF for single byte transfered
uint8_t fifo_hf : 1; // RW1, IF for FIFO half full
uint8_t dma_end : 1; // RW1, IF for end of DMA
uint8_t fifo_ov : 1; // RW1, IF for FIFO full or empty
uint8_t resv_5 : 1;
uint8_t free : 1; // RO, current SPI state is free
uint8_t fst_byte : 1; // RW1, IF for 1st byte received, SPI slave
};
};
#define RB_SPI_IF_CNT_END 0x01
#define RB_SPI_IF_BYTE_END 0x02
#define RB_SPI_IF_FIFO_HF 0x04
#define RB_SPI_IF_DMA_END 0x08
#define RB_SPI_IF_FIFO_OV 0x10
#define RB_SPI_FREE 0x40
#define RB_SPI_IF_FST_BYTE 0x80
/*
* 0x00 R8_SPIx_CTRL_MOD: SPI mode setting register
* 0x01 R8_SPIx_CTRL_CFG: SPI configuration register
* 0x02 R8_SPIx_INTER_EN: SPI interrupt enable register
* 0x03 R8_SPIx_CLOCK_DIV: SPI master clock divisor, minimum 2
* 0x03 R8_SPIx_SLAVE_PRE: SPI slave preset data (reset as 10h)
* 0x04 R8_SPIx_BUFFER: SPI data buffer
* 0x05 R8_SPIx_RUN_FLAG: SPI working state register
* 0x06 R8_SPIx_INT_FLAG: SPI interrupt flags register
* 0x07 R8_SPIx_FIFO_COUNT: SPI FIFO data count
* 0x0c R16_SPIx_TOTAL_CNT: SPI total data length to transfer
* 0x10 R8_SPIx_FIFO: SPI FIFO
* 0x13 R8_SPIx_FIFO_COUNT1: SPI FIFO data count
* 0x14 R32_SPIx_DMA_NOW: SPI DMA current address
* 0x18 R32_SPIx_DMA_BEG: SPI DMA start address
* 0x1c R32_SPIx_DMA_END: SPI DMA end address
*/
struct spi_registers
{
union _spi_ctrl_mod CTRL_MOD;
union _spi_ctrl_cfg CTRL_CFG;
union _spi_inter_en INTER_EN;
union
{
uint8_t CLOCK_DIV;
uint8_t SLAVE_PRE;
};
uint8_t BUFFER;
union _spi_run_flag RUN_FLAG;
union _spi_int_flag INT_FLAG;
uint8_t FIFO_COUNT;
uint32_t resv_8;
uint16_t TOTAL_COUNT;
uint16_t resv_0e;
uint8_t FIFO;
uint8_t resv_11[2];
uint8_t FIFO_COUNT1;
uint32_t DMA_NOW;
uint32_t DMA_BIG;
uint32_t DMA_END;
};
CHECK_STRUCT_SIZE(struct spi_registers, 0x20);
rt_err_t spi_cs_pin_assign(int spi_n, rt_base_t cs_pin);
#ifdef __cplusplus
}
#endif
#endif
|