• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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