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, ®Value);
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