1 /*
2  * Copyright  2021-2022 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "fsl_sx1502.h"
9 
10 /*******************************************************************************
11  * Definitions
12  ******************************************************************************/
13 
14 /*******************************************************************************
15  * Prototypes
16  ******************************************************************************/
17 static status_t SX1502_I2C_Send(void *handle,
18                                 uint8_t deviceAddress,
19                                 uint32_t subAddress,
20                                 uint8_t subaddressSize,
21                                 uint8_t *txBuff,
22                                 uint8_t txBuffSize);
23 
24 static status_t SX1502_I2C_Receive(void *handle,
25                                    uint8_t deviceAddress,
26                                    uint32_t subAddress,
27                                    uint8_t subaddressSize,
28                                    uint8_t *rxBuff,
29                                    uint8_t rxBuffSize);
30 
31 static status_t SX1502_I2C_Deinit(void *handle);
32 
33 static status_t SX1502_I2C_Init(void *handle, uint32_t i2cInstance, uint32_t i2cBaudrate, uint32_t i2cSourceClockHz);
34 /*******************************************************************************
35  * Code
36  ******************************************************************************/
SX1502_I2C_Receive(void * handle,uint8_t deviceAddress,uint32_t subAddress,uint8_t subaddressSize,uint8_t * rxBuff,uint8_t rxBuffSize)37 static status_t SX1502_I2C_Receive(void *handle,
38                                    uint8_t deviceAddress,
39                                    uint32_t subAddress,
40                                    uint8_t subaddressSize,
41                                    uint8_t *rxBuff,
42                                    uint8_t rxBuffSize)
43 {
44     hal_i2c_master_transfer_t masterXfer;
45 
46     masterXfer.slaveAddress   = deviceAddress;
47     masterXfer.direction      = kHAL_I2cRead;
48     masterXfer.subaddress     = (uint32_t)subAddress;
49     masterXfer.subaddressSize = subaddressSize;
50     masterXfer.data           = rxBuff;
51     masterXfer.dataSize       = rxBuffSize;
52     masterXfer.flags          = (uint32_t)kHAL_I2cTransferDefaultFlag;
53 
54     return (status_t)HAL_I2cMasterTransferBlocking((hal_i2c_master_handle_t *)handle, &masterXfer);
55 }
56 
SX1502_I2C_Send(void * handle,uint8_t deviceAddress,uint32_t subAddress,uint8_t subaddressSize,uint8_t * txBuff,uint8_t txBuffSize)57 static status_t SX1502_I2C_Send(void *handle,
58                                 uint8_t deviceAddress,
59                                 uint32_t subAddress,
60                                 uint8_t subaddressSize,
61                                 uint8_t *txBuff,
62                                 uint8_t txBuffSize)
63 {
64     hal_i2c_master_transfer_t masterXfer;
65 
66     masterXfer.slaveAddress   = deviceAddress;
67     masterXfer.direction      = kHAL_I2cWrite;
68     masterXfer.subaddress     = (uint32_t)subAddress;
69     masterXfer.subaddressSize = subaddressSize;
70     masterXfer.data           = txBuff;
71     masterXfer.dataSize       = txBuffSize;
72     masterXfer.flags          = (uint32_t)kHAL_I2cTransferDefaultFlag;
73 
74     return (status_t)HAL_I2cMasterTransferBlocking((hal_i2c_master_handle_t *)handle, &masterXfer);
75 }
76 
SX1502_I2C_Deinit(void * handle)77 static status_t SX1502_I2C_Deinit(void *handle)
78 {
79     return (status_t)HAL_I2cMasterDeinit((hal_i2c_master_handle_t *)handle);
80 }
81 
SX1502_I2C_Init(void * handle,uint32_t i2cInstance,uint32_t i2cBaudrate,uint32_t i2cSourceClockHz)82 static status_t SX1502_I2C_Init(void *handle, uint32_t i2cInstance, uint32_t i2cBaudrate, uint32_t i2cSourceClockHz)
83 {
84     hal_i2c_master_config_t masterConfig;
85 
86     masterConfig.enableMaster = true;
87     masterConfig.baudRate_Bps = i2cBaudrate;
88     masterConfig.srcClock_Hz  = i2cSourceClockHz;
89     masterConfig.instance     = (uint8_t)i2cInstance;
90 
91     return (status_t)HAL_I2cMasterInit((hal_i2c_master_handle_t *)handle, &masterConfig);
92 }
93 
94 /*!
95  * brief SX1502 write register.
96  *
97  * param handle SX1502 handle structure.
98  * param reg register address.
99  * param value value to write.
100  * return kStatus_Success, else failed.
101  */
SX1502_WriteRegister(sx1502_handle_t * handle,uint8_t reg,uint8_t value)102 status_t SX1502_WriteRegister(sx1502_handle_t *handle, uint8_t reg, uint8_t value)
103 {
104     assert(handle != NULL);
105     assert(handle->slaveAddress != 0U);
106 
107     return SX1502_I2C_Send(handle->i2cHandle, handle->slaveAddress, reg, 1U, (uint8_t *)&value, 1U);
108 }
109 
110 /*!
111  * brief SX1502 read register.
112  *
113  * param handle SX1502 handle structure.
114  * param reg register address.
115  * param value value to read.
116  * return kStatus_Success, else failed.
117  */
SX1502_ReadRegister(sx1502_handle_t * handle,uint8_t reg,uint8_t * value)118 status_t SX1502_ReadRegister(sx1502_handle_t *handle, uint8_t reg, uint8_t *value)
119 {
120     assert(handle != NULL);
121     assert(handle->slaveAddress != 0U);
122 
123     status_t retval   = 0;
124     uint8_t readValue = 0U;
125 
126     retval = SX1502_I2C_Receive(handle->i2cHandle, handle->slaveAddress, (uint32_t)reg, 1U, (uint8_t *)&readValue, 1U);
127 
128     *value = readValue;
129 
130     return retval;
131 }
132 
133 /*!
134  * brief SX1502 modify register.
135  *
136  * param handle SX1502 handle structure.
137  * param reg register address.
138  * oaram mask register bits mask.
139  * param value value to write.
140  * return kStatus_Success, else failed.
141  */
SX1502_ModifyRegister(sx1502_handle_t * handle,uint8_t reg,uint8_t mask,uint8_t value)142 status_t SX1502_ModifyRegister(sx1502_handle_t *handle, uint8_t reg, uint8_t mask, uint8_t value)
143 {
144     status_t result;
145     uint8_t regValue;
146 
147     result = SX1502_ReadRegister(handle, reg, &regValue);
148     if (result != kStatus_Success)
149     {
150         return result;
151     }
152 
153     regValue &= (uint8_t)~mask;
154     regValue |= value;
155 
156     return SX1502_WriteRegister(handle, reg, regValue);
157 }
158 
159 /*!
160  * brief Initializes SX1502.
161  *
162  * param handle SX1502 handle structure.
163  * param sx1502_config SX1502 configuration structure.
164  */
SX1502_Init(sx1502_handle_t * handle,const sx1502_config_t * sx1502Config)165 status_t SX1502_Init(sx1502_handle_t *handle, const sx1502_config_t *sx1502Config)
166 {
167     assert(handle != NULL);
168     assert(sx1502Config != NULL);
169 
170     status_t result;
171     handle->slaveAddress = SX1502_I2C_ADDRESS;
172 
173     /* i2c bus initialization */
174     result = SX1502_I2C_Init(handle->i2cHandle, sx1502Config->sx1502I2CInstance, SX1502_I2C_BITRATE,
175                              sx1502Config->sx1502I2CSourceClock);
176     if (result != (status_t)kStatus_HAL_I2cSuccess)
177     {
178         return kStatus_Fail;
179     }
180 
181     result = SX1502_WriteRegister(handle, SX1502_REGPLDMODE, 0U);
182     if (result != kStatus_Success)
183     {
184         return result;
185     }
186 
187     result = SX1502_WriteRegister(handle, SX1502_REGDATA, sx1502Config->initRegDataValue);
188     if (result != kStatus_Success)
189     {
190         return result;
191     }
192 
193     result = SX1502_WriteRegister(handle, SX1502_REGDIR, sx1502Config->initRegDirValue);
194     if (result != kStatus_Success)
195     {
196         return result;
197     }
198 
199     result = SX1502_WriteRegister(handle, SX1502_REGPULLUP, 0U);
200     if (result != kStatus_Success)
201     {
202         return result;
203     }
204 
205     result = SX1502_WriteRegister(handle, SX1502_REGPULLDOWN, 0U);
206     if (result != kStatus_Success)
207     {
208         return result;
209     }
210 
211     result = SX1502_WriteRegister(handle, SX1502_REGADVANCED, 0U);
212     if (result != kStatus_Success)
213     {
214         return result;
215     }
216 
217     return result;
218 }
219 
220 /*!
221  * brief Deinitializes the SX1502.
222  *
223  * param handle SX1502 handle structure.
224  * return kStatus_Success if successful, different code otherwise.
225  */
SX1502_Deinit(sx1502_handle_t * handle)226 status_t SX1502_Deinit(sx1502_handle_t *handle)
227 {
228     return SX1502_I2C_Deinit(handle->i2cHandle);
229 }
230 
231 /*!
232  * brief SX1502 IO Set.
233  *
234  * param handle SX1502 handle structure.
235  * param ioMask bits to be set,it can be a single IO or multiple IO,control multiple IO with or operation.
236  * eg.Set IO1~IO3,ioMask is kSX1502_IO1|kSX1502_IO2|kSX1502_IO3.
237  * return kStatus_Success, else failed.
238  */
SX1502_IO_Set(sx1502_handle_t * handle,uint8_t ioMask)239 status_t SX1502_IO_Set(sx1502_handle_t *handle, uint8_t ioMask)
240 {
241     uint8_t dataValue;
242     status_t result;
243 
244     result = SX1502_ReadRegister(handle, SX1502_REGDATA, &dataValue);
245     if (result != kStatus_Success)
246     {
247         return result;
248     }
249 
250     dataValue |= (ioMask);
251 
252     result = SX1502_WriteRegister(handle, SX1502_REGDATA, dataValue);
253     if (result != kStatus_Success)
254     {
255         return result;
256     }
257 
258     return SX1502_IO_SetDirection(handle, ioMask, kSX1502_IO_Output);
259 }
260 
261 /*!
262  * brief SX1502 IO Clear.
263  *
264  * param handle SX1502 handle structure.
265  * param ioMask bits to be set,it can be a single IO or multiple IO,control multiple IO with or operation.
266  * eg.Clear IO1~IO3,ioMask is kSX1502_IO1|kSX1502_IO2|kSX1502_IO3.
267  * return kStatus_Success, else failed.
268  */
SX1502_IO_Clear(sx1502_handle_t * handle,uint8_t ioMask)269 status_t SX1502_IO_Clear(sx1502_handle_t *handle, uint8_t ioMask)
270 {
271     uint8_t dataValue;
272     status_t result;
273 
274     result = SX1502_ReadRegister(handle, SX1502_REGDATA, &dataValue);
275     if (result != kStatus_Success)
276     {
277         return result;
278     }
279 
280     dataValue &= ~(ioMask);
281 
282     result = SX1502_WriteRegister(handle, SX1502_REGDATA, dataValue);
283     if (result != kStatus_Success)
284     {
285         return result;
286     }
287 
288     return SX1502_IO_SetDirection(handle, ioMask, kSX1502_IO_Output);
289 }
290 
291 /*!
292  * brief SX1502 IO Direction to input or output.
293  *
294  * This API is used to set the direction of any IO combination.For example,set the direction of IO0~IO3 as output.
295  * SX1502_IO_SetDirection(handle, kSX1502_IO0|kSX1502_IO1|kSX1502_IO2|kSX1502_IO3, kSX1502_IO_Output);
296  *
297  * param handle SX1502 handle structure.
298  * param ioMask bits to be set,it can be a single IO or multiple IO,control multiple IO with or operation.
299  * param ioDirection set IO direction to input or output.
300  * return kStatus_Success, else failed.
301  */
SX1502_IO_SetDirection(sx1502_handle_t * handle,uint8_t ioMask,sx1502_io_dir_t ioDirection)302 status_t SX1502_IO_SetDirection(sx1502_handle_t *handle, uint8_t ioMask, sx1502_io_dir_t ioDirection)
303 {
304     uint8_t dirValue;
305     status_t result;
306 
307     result = SX1502_ReadRegister(handle, SX1502_REGDIR, &dirValue);
308     if (result != kStatus_Success)
309     {
310         return result;
311     }
312 
313     switch (ioDirection)
314     {
315         case kSX1502_IO_Output:
316             dirValue &= ~(ioMask);
317             break;
318         case kSX1502_IO_Input:
319             dirValue |= (ioMask);
320             break;
321         default:
322             /* Avoid MISRA 16.4 violation */
323             break;
324     }
325 
326     return SX1502_WriteRegister(handle, SX1502_REGDIR, dirValue);
327 }
328 
329 /*!
330  * brief SX1502 IO output status in a pattern.
331  *
332  * This API is used to set any IO combination and output in any pattern.
333  * For example,set IO0~IO3 as output and iopattern as 0101,iopattern is 0x05U.
334  * SX1502_IO_OutputControl(handle, kSX1502_IO0|kSX1502_IO1|kSX1502_IO2|kSX1502_IO3, 0x05U);
335  *
336  * param handle SX1502 handle structure.
337  * param ioMask bits to be set,it can be a single IO or multiple IO,control multiple IO with or operation.
338  * param ioPattern ioPattern is the pattern of IO status to set.0-output low,1-output high.
339  * return kStatus_Success, else failed.
340  */
SX1502_IO_OutputControl(sx1502_handle_t * handle,uint8_t ioMask,uint8_t ioPattern)341 status_t SX1502_IO_OutputControl(sx1502_handle_t *handle, uint8_t ioMask, uint8_t ioPattern)
342 {
343     uint8_t dataValue;
344     status_t result;
345 
346     result = SX1502_ReadRegister(handle, SX1502_REGDATA, &dataValue);
347     if (result != kStatus_Success)
348     {
349         return result;
350     }
351 
352     dataValue = (dataValue & ~ioMask) | ioPattern;
353 
354     result = SX1502_WriteRegister(handle, SX1502_REGDATA, dataValue);
355     if (result != kStatus_Success)
356     {
357         return result;
358     }
359 
360     return SX1502_IO_SetDirection(handle, ioMask, kSX1502_IO_Output);
361 }
362