1 /*
2 * Copyright (c) 2022 FuZhou Lockzhiner Electronic Co., Ltd. All rights reserved.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 /**
17 * @addtogroup Lockzhiner
18 *
19 * @file spi.h
20 */
21
22 #ifndef LZ_HARDWARE_SPI_H
23 #define LZ_HARDWARE_SPI_H
24
25 #include "stdint.h"
26 #include "stdbool.h"
27 /* SPI_CONFIG mode */
28 #define SPI_CPHA (1<<0) /* bit[0]:CPHA, clock phase */
29 #define SPI_CPOL (1<<1) /* bit[1]:CPOL, clock polarity */
30 /**
31 * At CPOL=0 the base value of the clock is zero
32 * - For CPHA=0, data are captured on the clock's rising edge (low->high transition)
33 * and data are propagated on a falling edge (high->low clock transition).
34 * - For CPHA=1, data are captured on the clock's falling edge and data are
35 * propagated on a rising edge.
36 * At CPOL=1 the base value of the clock is one (inversion of CPOL=0)
37 * - For CPHA=0, data are captured on clock's falling edge and data are propagated
38 * on a rising edge.
39 * - For CPHA=1, data are captured on clock's rising edge and data are propagated
40 * on a falling edge.
41 */
42 #define SPI_LSB (0<<2) /* bit[2]: 0-LSB */
43 #define SPI_MSB (1<<2) /* bit[2]: 1-MSB */
44
45 #define SPI_MASTER (0<<3) /* SPI master device */
46 #define SPI_SLAVE (1<<3) /* SPI slave device */
47
48 #define SPI_CSM_SHIFT (4)
49 #define SPI_CSM_MASK (0x3 << 4) /* SPI master ss_n hold cycles for MOTO SPI master */
50
51 #define SPI_MODE_0 (0 | 0) /* CPOL = 0, CPHA = 0 */
52 #define SPI_MODE_1 (0 | SPI_CPHA) /* CPOL = 0, CPHA = 1 */
53 #define SPI_MODE_2 (SPI_CPOL | 0) /* CPOL = 1, CPHA = 0 */
54 #define SPI_MODE_3 (SPI_CPOL | SPI_CPHA) /* CPOL = 1, CPHA = 1 */
55 #define SPI_MODE_MASK (SPI_CPHA | SPI_CPOL | SPI_MSB)
56 #define SPI_INT_TXFIM (1 << SPI_IMR_TXFIM_SHIFT)
57 enum {
58 SPI_PERWORD_8BITS,
59 SPI_PERWORD_16BITS,
60 };
61
62 enum {
63 SPI_CMS_ZERO_CYCLES = 0,
64 SPI_CMS_HALF_CYCLES,
65 SPI_CMS_ONE_CYCLES,
66 };
67
68 /**
69 * @ingroup LzSpiConfig
70 *
71 *
72 *
73 * @bitsPerWord Indicates select a bits_per_word for transfer.
74 * @firstBit: Indicates whether data transfers start from MSB or LSB bit.
75 * @mode Indicates the clock polarity(SCPOL) and clock phase(SCPH).
76 * 0: SCPH=0 SCPOL=0
77 * 1: SCPH=0 SCPOL=1
78 * 2: SCPH=1 SCPOL=0
79 * 3: SCPH=1 SCPOL=1
80 * @speed Indicates the Baud Rate prescaler value which will be
81 used to configure the transmit and receive SCK clock, unit Hz.
82 * @nCycles: Specifies Motorola SPI Master SS_N high cycles for each frame data is transfer.
83 * @isSlave Indictates Whether spi work as slave mode.
84 */
85 typedef struct _LzSpiConfig {
86 unsigned int bitsPerWord;
87 unsigned int firstBit;
88 unsigned int mode;
89 unsigned int speed;
90 unsigned int nCycles;
91 unsigned int csm;
92 bool isSlave;
93 } LzSpiConfig;
94
95 /**
96 * @ingroup LzSpiMsg
97 *
98 *
99 * @chn: Indicates the spi channel based on CSn.
100 * @csTake: Indicates take the CS signal.
101 * @csRelease: Indicates release the CS signal.
102 * @txBuf Indicates the data to be written, or NULL.
103 * @rxBuf Indicates the data to be read, or NULL.
104 * @len Indicates the bytes of data to transfer.
105 */
106 typedef struct _LzSpiMsg {
107 unsigned int chn;
108 bool csTake;
109 bool csRelease;
110 const void *txBuf;
111 void *rxBuf;
112 unsigned int len;
113 } LzSpiMsg;
114
115 /**
116 * @brief Sets configure information for an SPI device.
117 *
118 * @param id Indicates the SPI device ID.
119 * @param conf Indicates the SPI configure to set.
120 * @return Returns {@link LZ_HARDWARE_SUCCESS} if the configure is set;
121 * returns {@link LZ_HARDWARE_FAILURE} otherwise. For details about other return values, see the chip description.
122 */
123 unsigned int LzSpiSetConfig(unsigned int id, LzSpiConfig conf);
124
125 /**
126 * @brief Initializes an SPI device with a specified transfer speed.
127 *
128 *
129 *
130 * @param id Indicates the SPI device ID.
131 * @param conf Indicates the SPI configure to set.
132 * @return Returns {@link LZ_HARDWARE_SUCCESS} if the SPI device is initialized;
133 * returns {@link LZ_HARDWARE_FAILURE} otherwise. For details about other return values, see the chip description.
134 */
135 unsigned int LzSpiInit(unsigned int id, LzSpiConfig conf);
136
137 /**
138 * @brief Deinitializes an SPI device.
139 *
140 * @param id Indicates the SPI device ID.
141 * @return Returns {@link LZ_HARDWARE_SUCCESS} if the SPI device is deinitialized;
142 * returns {@link LZ_HARDWARE_FAILURE} otherwise. For details about other return values, see the chip description.
143 */
144 unsigned int LzSpiDeinit(unsigned int id);
145
146 /**
147 * @brief transfer data with an SPI device.
148 *
149 *
150 *
151 * @param id Indicates the SPI device ID.
152 * @param msg Indicates the pointer to the message.
153 * @return Returns {@link LZ_HARDWARE_SUCCESS} if the data is written to the SPI device successfully;
154 * returns {@link LZ_HARDWARE_FAILURE} otherwise. For details about other return values, see the chip description.
155 */
156 unsigned int LzSpiTransfer(unsigned int id, LzSpiMsg *msg);
157
LzSpiRead(unsigned int id,unsigned int chn,void * buf,unsigned int len)158 static inline unsigned int LzSpiRead(unsigned int id, unsigned int chn, void *buf, unsigned int len)
159 {
160 LzSpiMsg msg;
161
162 msg.chn = chn;
163 msg.csTake = true;
164 msg.csRelease = true;
165 msg.txBuf = NULL;
166 msg.rxBuf = buf;
167 msg.len = len;
168
169 return LzSpiTransfer(id, &msg);
170 }
171
LzSpiWrite(unsigned int id,unsigned int chn,const void * buf,unsigned int len)172 static inline unsigned int LzSpiWrite(unsigned int id, unsigned int chn, const void *buf, unsigned int len)
173 {
174 LzSpiMsg msg;
175
176 msg.chn = chn;
177 msg.csTake = true;
178 msg.csRelease = true;
179 msg.txBuf = buf;
180 msg.rxBuf = NULL;
181 msg.len = len;
182
183 return LzSpiTransfer(id, &msg);
184 }
185
LzSpiWriteAndRead(unsigned int id,unsigned int chn,const void * txBuf,void * rxBuf,unsigned int len)186 static inline unsigned int LzSpiWriteAndRead(unsigned int id, unsigned int chn,
187 const void *txBuf, void *rxBuf,
188 unsigned int len)
189 {
190 LzSpiMsg msg;
191
192 msg.chn = chn;
193 msg.csTake = true;
194 msg.csRelease = true;
195 msg.txBuf = txBuf;
196 msg.rxBuf = rxBuf;
197 msg.len = len;
198
199 return LzSpiTransfer(id, &msg);
200 }
201
LzSpiWriteThenRead(unsigned int id,unsigned int chn,const void * txBuf,unsigned int txLen,void * rxBuf,unsigned int rxLen)202 static inline unsigned int LzSpiWriteThenRead(unsigned int id, unsigned int chn,
203 const void *txBuf, unsigned int txLen,
204 void *rxBuf, unsigned int rxLen)
205 {
206 int ret;
207 LzSpiMsg msg;
208
209 msg.chn = chn;
210 msg.csTake = true;
211 msg.csRelease = false;
212 msg.txBuf = txBuf;
213 msg.rxBuf = NULL;
214 msg.len = txLen;
215
216 ret = LzSpiTransfer(id, &msg);
217 if (ret != LZ_HARDWARE_SUCCESS) {
218 return ret;
219 }
220
221 msg.chn = chn;
222 msg.csTake = false;
223 msg.csRelease = true;
224 msg.txBuf = NULL;
225 msg.rxBuf = rxBuf;
226 msg.len = rxLen;
227
228 return LzSpiTransfer(id, &msg);
229 }
230
231 #endif