1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author            Notes
8  * 2022-07-30     Emuzit            first version
9  */
10 #ifndef __CH56X_SPI_H__
11 #define __CH56X_SPI_H__
12 
13 #include "soc.h"
14 #include "ch56x_gpio.h"
15 
16 #ifdef __cplusplus
17 extern "C" {
18 #endif
19 
20 #define SPI0_BUS_NAME       "spi0"
21 #define SPI1_BUS_NAME       "spi1"
22 
23 #ifndef SPI0_SCS_PIN
24 #define SPI0_SCS_PIN        GET_PIN(A, 12)
25 #endif
26 #define SPI0_SCK_PIN        GET_PIN(A, 13)
27 #define SPI0_MOSI_PIN       GET_PIN(A, 14)
28 #define SPI0_MISO_PIN       GET_PIN(A, 15)
29 
30 #ifdef SOC_SERIES_CH569
31 #ifndef SPI1_SCS_PIN
32 #define SPI1_SCS_PIN        GET_PIN(B, 11)
33 #endif
34 #define SPI1_SCK_PIN        GET_PIN(B, 12)
35 #define SPI1_MOSI_PIN       GET_PIN(B, 13)
36 #define SPI1_MISO_PIN       GET_PIN(B, 14)
37 
38 #else
39 #define SPI1_SCK_PIN        GET_PIN(A, 0)
40 #define SPI1_MOSI_PIN       GET_PIN(A, 1)
41 #define SPI1_MISO_PIN       GET_PIN(A, 2)
42 #endif
43 
44 #define SPI_FIFO_SIZE       8
45 
46 union _spi_ctrl_mod
47 {
48     uint8_t reg;
49     struct
50     {
51         uint8_t mode_slave  : 1;  // RW, SPI master/slave (0/1) mode select
52         uint8_t all_clear   : 1;  // RW, clear FIFO/count/int-flag
53         uint8_t two_wire    : 1;  // RW, 2/3-wire mode (0/1), SPI slave
54         uint8_t mst_sck_mod : 1;  // RW, mode0/mode3 (0/1) for SCK idle L/H
55         uint8_t fifo_dir    : 1;  // RW, FIFO direction is output/input (0/1)
56         uint8_t sck_oe      : 1;  // RW, SCK pin output enable
57         uint8_t mosi_oe     : 1;  // RW, MOSI pin output enable
58         uint8_t miso_oe     : 1;  // RW, MISO pin output enable
59     };
60     struct
61     {
62         uint8_t stuff_0     : 3;
63         uint8_t slv_cmd_mod : 1;  // RW, 1st byte is data/cmd (0/1), SPI slave
64         uint8_t stuff_4     : 4;
65     };
66 };
67 #define RB_SPI_MODE_SLAVE   0x01
68 #define RB_SPI_ALL_CLEAR    0x02
69 #define RB_SPI_2WIRE_MOD    0x04
70 #define RB_SPI_MST_SCK_MOD  0x08
71 #define RB_SPI_SLV_CMD_MOD  0x08
72 #define RB_SPI_FIFO_DIR     0x10
73 #define RB_SPI_SCK_OE       0x20
74 #define RB_SPI_MOSI_OE      0x40
75 #define RB_SPI_MISO_OE      0x80
76 
77 #define MST_SCK_MOD_0       0
78 #define MST_SCK_MOD_3       1
79 
80 #define SPI_FIFO_DIR_OUTPUT 0
81 #define SPI_FIFO_DIR_INPUT  1
82 
83 union _spi_ctrl_cfg
84 {
85     uint8_t reg;
86     struct
87     {
88         uint8_t dma_enable  : 1;  // RW, enable DMA function
89         uint8_t resv_1      : 1;
90         uint8_t dma_loop    : 1;  // RW, enable DMA loop mode (0 => single)
91         uint8_t resv_3      : 1;
92         uint8_t auto_if     : 1;  // RW, enable auto clear RB_SPI_IF_BYTE_END
93         uint8_t bit_order   : 1;  // RW, data bit ordering, LSB/MSB first (0/1)
94         uint8_t resv_6      : 2;
95     };
96 };
97 #define RB_SPI_DMA_ENABLE   0x01
98 #define RB_SPI_DMA_LOOP     0x04
99 #define RB_SPI_AUTO_IF      0x10
100 #define RB_SPI_BIT_ORDER    0x20
101 
102 #define SPI_BIT_ORDER_MSB   0
103 #define SPI_BIT_ORDER_LSB   1
104 
105 union _spi_inter_en
106 {
107     uint8_t reg;
108     struct
109     {
110         uint8_t cnt_end     : 1;  // RW, IE for all bytes transfered
111         uint8_t byte_end    : 1;  // RW, IE for single byte transfered
112         uint8_t fifo_hf     : 1;  // RW, IE for FIFO half full
113         uint8_t dma_end     : 1;  // RW, IE for end of DMA
114         uint8_t fifo_ov     : 1;  // RW, IE for FIFO full or empty
115         uint8_t resv_5      : 2;
116         uint8_t fst_byte    : 1;  // RW, IE for 1st byte received, SPI slave
117     };
118 };
119 #define RB_SPI_IE_CNT_END   0x01
120 #define RB_SPI_IE_BYTE_END  0x02
121 #define RB_SPI_IE_FIFO_HF   0x04
122 #define RB_SPI_IE_DMA_END   0x08
123 #define RB_SPI_IE_FIFO_OV   0x10
124 #define RB_SPI_IE_FST_BYTE  0x80
125 
126 union _spi_run_flag
127 {
128     uint8_t reg;
129     struct
130     {
131         uint8_t resv_0      : 4;
132         uint8_t slv_cmd_act : 1;  // RO, SPI slave cmd received
133         uint8_t fifo_ready  : 1;  // RO, SPI FIFO ready to transfer
134         uint8_t slv_cs_load : 1;  // RO, SPI slave is loading R8_SPIx_SLAVE_PRE
135         uint8_t slv_select  : 1;  // RO, SPI slave CS active (selected)
136     };
137 };
138 #define RB_SPI_SLV_CMD_ACT  0x10
139 #define RB_SPI_FIFO_READY   0x20
140 #define RB_SPI_SLV_CS_LOAD  0x40
141 #define RB_SPI_SLV_SELECT   0x80
142 
143 union _spi_int_flag
144 {
145     uint8_t reg;
146     struct
147     {
148         uint8_t cnt_end     : 1;  // RW1, IF for all bytes transfered
149         uint8_t byte_end    : 1;  // RW1, IF for single byte transfered
150         uint8_t fifo_hf     : 1;  // RW1, IF for FIFO half full
151         uint8_t dma_end     : 1;  // RW1, IF for end of DMA
152         uint8_t fifo_ov     : 1;  // RW1, IF for FIFO full or empty
153         uint8_t resv_5      : 1;
154         uint8_t free        : 1;  // RO, current SPI state is free
155         uint8_t fst_byte    : 1;  // RW1, IF for 1st byte received, SPI slave
156     };
157 };
158 #define RB_SPI_IF_CNT_END   0x01
159 #define RB_SPI_IF_BYTE_END  0x02
160 #define RB_SPI_IF_FIFO_HF   0x04
161 #define RB_SPI_IF_DMA_END   0x08
162 #define RB_SPI_IF_FIFO_OV   0x10
163 #define RB_SPI_FREE         0x40
164 #define RB_SPI_IF_FST_BYTE  0x80
165 
166 /*
167  * 0x00  R8_SPIx_CTRL_MOD:    SPI mode setting register
168  * 0x01  R8_SPIx_CTRL_CFG:    SPI configuration register
169  * 0x02  R8_SPIx_INTER_EN:    SPI interrupt enable register
170  * 0x03  R8_SPIx_CLOCK_DIV:   SPI master clock divisor, minimum 2
171  * 0x03  R8_SPIx_SLAVE_PRE:   SPI slave preset data (reset as 10h)
172  * 0x04  R8_SPIx_BUFFER:      SPI data buffer
173  * 0x05  R8_SPIx_RUN_FLAG:    SPI working state register
174  * 0x06  R8_SPIx_INT_FLAG:    SPI interrupt flags register
175  * 0x07  R8_SPIx_FIFO_COUNT:  SPI FIFO data count
176  * 0x0c  R16_SPIx_TOTAL_CNT:  SPI total data length to transfer
177  * 0x10  R8_SPIx_FIFO:        SPI FIFO
178  * 0x13  R8_SPIx_FIFO_COUNT1: SPI FIFO data count
179  * 0x14  R32_SPIx_DMA_NOW:    SPI DMA current address
180  * 0x18  R32_SPIx_DMA_BEG:    SPI DMA start address
181  * 0x1c  R32_SPIx_DMA_END:    SPI DMA end address
182  */
183 struct spi_registers
184 {
185     union _spi_ctrl_mod     CTRL_MOD;
186     union _spi_ctrl_cfg     CTRL_CFG;
187     union _spi_inter_en     INTER_EN;
188     union
189     {
190         uint8_t             CLOCK_DIV;
191         uint8_t             SLAVE_PRE;
192     };
193     uint8_t                 BUFFER;
194     union _spi_run_flag     RUN_FLAG;
195     union _spi_int_flag     INT_FLAG;
196     uint8_t                 FIFO_COUNT;
197     uint32_t                resv_8;
198     uint16_t                TOTAL_COUNT;
199     uint16_t                resv_0e;
200     uint8_t                 FIFO;
201     uint8_t                 resv_11[2];
202     uint8_t                 FIFO_COUNT1;
203     uint32_t                DMA_NOW;
204     uint32_t                DMA_BIG;
205     uint32_t                DMA_END;
206 };
207 CHECK_STRUCT_SIZE(struct spi_registers, 0x20);
208 
209 rt_err_t spi_cs_pin_assign(int spi_n, rt_base_t cs_pin);
210 
211 #ifdef __cplusplus
212 }
213 #endif
214 
215 #endif
216