diff options
Diffstat (limited to 'lib/chibios-contrib/ext/mcux-sdk/components/pca9420/fsl_pca9420.c')
-rw-r--r-- | lib/chibios-contrib/ext/mcux-sdk/components/pca9420/fsl_pca9420.c | 542 |
1 files changed, 542 insertions, 0 deletions
diff --git a/lib/chibios-contrib/ext/mcux-sdk/components/pca9420/fsl_pca9420.c b/lib/chibios-contrib/ext/mcux-sdk/components/pca9420/fsl_pca9420.c new file mode 100644 index 000000000..b016ebdbf --- /dev/null +++ b/lib/chibios-contrib/ext/mcux-sdk/components/pca9420/fsl_pca9420.c | |||
@@ -0,0 +1,542 @@ | |||
1 | /* | ||
2 | * Copyright 2018-2020 NXP | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * SPDX-License-Identifier: BSD-3-Clause | ||
6 | */ | ||
7 | |||
8 | #include "fsl_common.h" | ||
9 | #include "fsl_pca9420.h" | ||
10 | #include "fsl_power.h" | ||
11 | |||
12 | /******************************************************************************* | ||
13 | * Definitions | ||
14 | ******************************************************************************/ | ||
15 | |||
16 | /******************************************************************************* | ||
17 | * Prototypes | ||
18 | ******************************************************************************/ | ||
19 | |||
20 | /******************************************************************************* | ||
21 | * Variables | ||
22 | ******************************************************************************/ | ||
23 | |||
24 | /******************************************************************************* | ||
25 | * Code | ||
26 | ******************************************************************************/ | ||
27 | void PCA9420_GetDefaultConfig(pca9420_config_t *config) | ||
28 | { | ||
29 | assert(config); | ||
30 | |||
31 | /* Set callback function to NULL Pointer. */ | ||
32 | config->I2C_SendFunc = NULL; | ||
33 | config->I2C_ReceiveFunc = NULL; | ||
34 | |||
35 | /* Enable power up sequence when VIN on */ | ||
36 | config->powerUpCfg = kPCA9420_ShipWkup_PowerUp; | ||
37 | /* Disable power down sequence. */ | ||
38 | config->startPowerDown = kPCA9420_PwrDnDisabled; | ||
39 | /* Continue charging when wdog timeout. */ | ||
40 | config->wdogChargeCtrl = kPCA9420_ChgInWatchdogChargerContinue; | ||
41 | /* Enable power good detection. */ | ||
42 | config->powerGoodEnable = kPCA9420_PGoodEnabled; | ||
43 | /* VIN current limit. */ | ||
44 | config->vinCurrentLimit = kPCA9420_VinIlim_370_425_489; | ||
45 | /* VIN over voltage protection set to 5.5V. */ | ||
46 | config->vinOvpThreshold = kPCA9420_VinOvpSel5V5; | ||
47 | /* VIN under voltage lockout set to 3.1V. */ | ||
48 | config->vinUvloThreshold = kPCA9420_VinUvloSel3V1; | ||
49 | /* VSYS pre-warning voltage set to 3.5V. */ | ||
50 | config->asysPreWarnThreshold = kPCA9420_AsysPreWarn3V5; | ||
51 | /* VSYS input source set to either VBAT or VIN. */ | ||
52 | config->asysInputSource = kPCA9420_AsysInputSelVbatVin; | ||
53 | /* VSYS under voltage lockout set to 2.7V. */ | ||
54 | config->asysUvloThreshold = kPCA9420_AsysUvloSel2V7; | ||
55 | /* Fast charge timer enabled. */ | ||
56 | config->chargeTermDisable = kPCA9420_ChargeTermEnabled; | ||
57 | /* Thermal shutdown temperature set to 110 degree Celsius. */ | ||
58 | config->thermalShutdownThreshold = kPCA9420_ThemShdn110C; | ||
59 | /* Die warning temperature set to 85 degree Celsius. */ | ||
60 | config->tempWarnThreshold = kPCA9420_DieTempWarn85C; | ||
61 | /* ON pin long glitch timer set to 8 seconds. */ | ||
62 | config->onPinTimer = kPCA9420_OnGltLong8s; | ||
63 | /* Enable active discharge control for all regulators. */ | ||
64 | config->disableSw1Bleed = false; | ||
65 | config->disableSw2Bleed = false; | ||
66 | config->disableLdo1Bleed = false; | ||
67 | config->disableLdo2Bleed = false; | ||
68 | /* I2C slave address. */ | ||
69 | config->slaveAddress = PCA9420_DEFAULT_I2C_ADDR; | ||
70 | } | ||
71 | |||
72 | void PCA9420_Init(pca9420_handle_t *handle, const pca9420_config_t *config) | ||
73 | { | ||
74 | uint8_t topCtl[4], regCtl; | ||
75 | bool result; | ||
76 | |||
77 | assert(handle); | ||
78 | assert(config); | ||
79 | |||
80 | /* Initialize Callback functions. */ | ||
81 | handle->I2C_SendFunc = config->I2C_SendFunc; | ||
82 | handle->I2C_ReceiveFunc = config->I2C_ReceiveFunc; | ||
83 | /* Set Slave Address. */ | ||
84 | handle->slaveAddress = config->slaveAddress; | ||
85 | |||
86 | topCtl[0] = (uint8_t)(((uint32_t)config->vinCurrentLimit) | ((uint32_t)config->powerUpCfg) | | ||
87 | ((uint32_t)config->startPowerDown) | ((uint32_t)config->wdogChargeCtrl) | | ||
88 | ((uint32_t)config->powerGoodEnable)); | ||
89 | topCtl[1] = (uint8_t)(((uint32_t)config->asysPreWarnThreshold) | ((uint32_t)config->asysInputSource) | | ||
90 | ((uint32_t)config->vinOvpThreshold) | ((uint32_t)config->vinUvloThreshold)); | ||
91 | topCtl[2] = (uint8_t)(((uint32_t)config->asysUvloThreshold) | ((uint32_t)config->chargeTermDisable) | | ||
92 | ((uint32_t)config->thermalShutdownThreshold) | ((uint32_t)config->tempWarnThreshold)); | ||
93 | topCtl[3] = ((uint8_t)config->onPinTimer); | ||
94 | regCtl = (config->disableSw1Bleed ? (uint8_t)kPCA9420_RegCtlSw1Bleed : 0U) | | ||
95 | (config->disableSw2Bleed ? (uint8_t)kPCA9420_RegCtlSw2Bleed : 0U) | | ||
96 | (config->disableLdo1Bleed ? (uint8_t)kPCA9420_RegCtlLdo1Bleed : 0U) | | ||
97 | (config->disableLdo2Bleed ? (uint8_t)kPCA9420_RegCtlLdo2Bleed : 0U); | ||
98 | |||
99 | result = PCA9420_WriteRegs(handle, PCA9420_TOP_CNTL0, topCtl, sizeof(topCtl)); | ||
100 | result = result ? PCA9420_WriteRegs(handle, PCA9420_ACT_DISCHARGE_CNTL_1, ®Ctl, 1U) : result; | ||
101 | if (!result) | ||
102 | { | ||
103 | assert(false); | ||
104 | } | ||
105 | } | ||
106 | |||
107 | void PCA9420_GetDefaultModeConfig(pca9420_modecfg_t *config) | ||
108 | { | ||
109 | /* Don't enter ship mode in this PMIC mode. */ | ||
110 | config->shipModeEnable = kPCA9420_ShipModeDisabled; | ||
111 | /* Use Pin to select mode. */ | ||
112 | config->modeSel = kPCA9420_ModeSelPin; | ||
113 | /* No mode switch on ON pin falling edge. */ | ||
114 | config->onCfg = kPCA9420_OnCfgDisableModeSwitch; | ||
115 | /* Watch dog disabled. */ | ||
116 | config->wdogTimerCfg = kPCA9420_WdTimerDisabled; | ||
117 | /* SW1 output set to 1.0V. */ | ||
118 | config->sw1OutVolt = kPCA9420_Sw1OutVolt1V000; | ||
119 | /* SW2 output set to 1.8V. */ | ||
120 | config->sw2OutVolt = kPCA9420_Sw2OutVolt1V800; | ||
121 | /* LDO1 output set to 1.8V. */ | ||
122 | config->ldo1OutVolt = kPCA9420_Ldo1OutVolt1V800; | ||
123 | /* LDO2 output set to 3.3V. */ | ||
124 | config->ldo2OutVolt = kPCA9420_Ldo2OutVolt3V300; | ||
125 | /* All regulators output enabled. */ | ||
126 | config->enableSw1Out = true; | ||
127 | config->enableSw2Out = true; | ||
128 | config->enableLdo1Out = true; | ||
129 | config->enableLdo2Out = true; | ||
130 | } | ||
131 | |||
132 | void PCA9420_GetRegulatorVolt(pca9420_modecfg_t *config, pca9420_regulator_mv_t *volt) | ||
133 | { | ||
134 | assert(config); | ||
135 | assert(volt); | ||
136 | |||
137 | /* SW1 voltage */ | ||
138 | if (config->sw1OutVolt <= kPCA9420_Sw1OutVolt1V500) | ||
139 | { | ||
140 | volt->mVoltSw1 = 500U + (uint32_t)config->sw1OutVolt * 25U; | ||
141 | } | ||
142 | else if (config->sw1OutVolt < kPCA9420_Sw1OutVolt1V800) | ||
143 | { | ||
144 | volt->mVoltSw1 = 1500U; | ||
145 | } | ||
146 | else | ||
147 | { | ||
148 | volt->mVoltSw1 = 1800U; | ||
149 | } | ||
150 | /* SW2 voltage */ | ||
151 | if (config->sw2OutVolt <= kPCA9420_Sw2OutVolt2V100) | ||
152 | { | ||
153 | volt->mVoltSw2 = 1500U + (uint32_t)config->sw2OutVolt * 25U; | ||
154 | } | ||
155 | else if (config->sw2OutVolt < kPCA9420_Sw2OutVolt2V700) | ||
156 | { | ||
157 | volt->mVoltSw2 = 2100U; | ||
158 | } | ||
159 | else if (config->sw2OutVolt <= kPCA9420_Sw2OutVolt3V300) | ||
160 | { | ||
161 | volt->mVoltSw2 = 2700U + ((uint32_t)config->sw2OutVolt - (uint32_t)kPCA9420_Sw2OutVolt2V700) * 25U; | ||
162 | } | ||
163 | else | ||
164 | { | ||
165 | volt->mVoltSw2 = 3300U; | ||
166 | } | ||
167 | /* LDO1 voltage */ | ||
168 | if (config->ldo1OutVolt <= kPCA9420_Ldo1OutVolt1V900) | ||
169 | { | ||
170 | volt->mVoltLdo1 = 1700U + (((uint32_t)config->ldo1OutVolt) >> PCA9420_MODECFG_2_LDO1_OUT_SHIFT) * 25U; | ||
171 | } | ||
172 | else | ||
173 | { | ||
174 | volt->mVoltLdo1 = 1900U; | ||
175 | } | ||
176 | /* LDO2 voltage */ | ||
177 | if (config->ldo2OutVolt <= kPCA9420_Ldo2OutVolt2V100) | ||
178 | { | ||
179 | volt->mVoltLdo2 = 1500U + (uint32_t)config->ldo2OutVolt * 25U; | ||
180 | } | ||
181 | else if (config->ldo2OutVolt < kPCA9420_Ldo2OutVolt2V700) | ||
182 | { | ||
183 | volt->mVoltLdo2 = 2100U; | ||
184 | } | ||
185 | else if (config->ldo2OutVolt <= kPCA9420_Ldo2OutVolt3V300) | ||
186 | { | ||
187 | volt->mVoltLdo2 = 2700U + ((uint32_t)config->ldo2OutVolt - (uint32_t)kPCA9420_Ldo2OutVolt2V700) * 25U; | ||
188 | } | ||
189 | else | ||
190 | { | ||
191 | volt->mVoltLdo2 = 3300U; | ||
192 | } | ||
193 | } | ||
194 | |||
195 | void PCA9420_WriteModeConfigs(pca9420_handle_t *handle, | ||
196 | pca9420_mode_t modeBase, | ||
197 | const pca9420_modecfg_t *configs, | ||
198 | uint32_t num) | ||
199 | { | ||
200 | uint8_t modeCfgRegBase = PCA9420_MODECFG_0_0; | ||
201 | uint8_t modeCfg[16]; | ||
202 | uint32_t i; | ||
203 | bool result; | ||
204 | |||
205 | assert((num >= 1U) && (num <= 4U)); | ||
206 | |||
207 | switch (modeBase) | ||
208 | { | ||
209 | case kPCA9420_Mode0: | ||
210 | modeCfgRegBase = PCA9420_MODECFG_0_0; | ||
211 | break; | ||
212 | case kPCA9420_Mode1: | ||
213 | modeCfgRegBase = PCA9420_MODECFG_1_0; | ||
214 | break; | ||
215 | case kPCA9420_Mode2: | ||
216 | modeCfgRegBase = PCA9420_MODECFG_2_0; | ||
217 | break; | ||
218 | case kPCA9420_Mode3: | ||
219 | modeCfgRegBase = PCA9420_MODECFG_3_0; | ||
220 | break; | ||
221 | default: | ||
222 | assert(false); | ||
223 | break; | ||
224 | } | ||
225 | |||
226 | for (i = 0; i < num; i++) | ||
227 | { | ||
228 | modeCfg[i * 4U] = (uint8_t)(((uint32_t)(configs[i].shipModeEnable)) | ((uint32_t)(configs[i].modeSel)) | | ||
229 | ((uint32_t)(configs[i].sw1OutVolt))); | ||
230 | modeCfg[i * 4U + 1U] = (uint8_t)(((uint32_t)(configs[i].onCfg)) | ((uint32_t)(configs[i].sw2OutVolt))); | ||
231 | modeCfg[i * 4U + 2U] = (uint8_t)(((uint32_t)(configs[i].ldo1OutVolt)) | | ||
232 | (configs[i].enableSw1Out ? (uint32_t)kPCA9420_RegulatorSwitch1 : 0U) | | ||
233 | (configs[i].enableSw2Out ? (uint32_t)kPCA9420_RegulatorSwitch2 : 0U) | | ||
234 | (configs[i].enableLdo1Out ? (uint32_t)kPCA9420_RegulatorLdo1 : 0U) | | ||
235 | (configs[i].enableLdo2Out ? (uint32_t)kPCA9420_RegulatorLdo2 : 0U)); | ||
236 | modeCfg[i * 4U + 3U] = (uint8_t)(((uint32_t)(configs[i].wdogTimerCfg)) | ((uint32_t)(configs[i].ldo2OutVolt))); | ||
237 | } | ||
238 | |||
239 | result = PCA9420_WriteRegs(handle, modeCfgRegBase, modeCfg, 4U * num); | ||
240 | if (!result) | ||
241 | { | ||
242 | assert(false); | ||
243 | } | ||
244 | } | ||
245 | |||
246 | void PCA9420_ReadModeConfigs(pca9420_handle_t *handle, | ||
247 | pca9420_mode_t modeBase, | ||
248 | pca9420_modecfg_t *configs, | ||
249 | uint32_t num) | ||
250 | { | ||
251 | uint8_t modeCfgRegBase = PCA9420_MODECFG_0_0; | ||
252 | uint8_t modeCfg[16] = {0U}; | ||
253 | uint32_t i; | ||
254 | bool result; | ||
255 | |||
256 | assert((num >= 1U) && (num <= 4U)); | ||
257 | |||
258 | switch (modeBase) | ||
259 | { | ||
260 | case kPCA9420_Mode0: | ||
261 | modeCfgRegBase = PCA9420_MODECFG_0_0; | ||
262 | break; | ||
263 | case kPCA9420_Mode1: | ||
264 | modeCfgRegBase = PCA9420_MODECFG_1_0; | ||
265 | break; | ||
266 | case kPCA9420_Mode2: | ||
267 | modeCfgRegBase = PCA9420_MODECFG_2_0; | ||
268 | break; | ||
269 | case kPCA9420_Mode3: | ||
270 | modeCfgRegBase = PCA9420_MODECFG_3_0; | ||
271 | break; | ||
272 | default: | ||
273 | assert(false); | ||
274 | break; | ||
275 | } | ||
276 | |||
277 | result = PCA9420_ReadRegs(handle, modeCfgRegBase, modeCfg, 4U * num); | ||
278 | if (!result) | ||
279 | { | ||
280 | assert(false); | ||
281 | } | ||
282 | |||
283 | for (i = 0; i < num; i++) | ||
284 | { | ||
285 | configs[i].shipModeEnable = (pca9420_ship_en_t)(uint8_t)(modeCfg[i * 4U] & PCA9420_MODECFG_0_SHIP_EN_MASK); | ||
286 | configs[i].modeSel = (pca9420_mode_sel_t)(uint8_t)(modeCfg[i * 4U] & PCA9420_MODECFG_0_MODE_CTRL_SEL_MASK); | ||
287 | configs[i].sw1OutVolt = (pca9420_sw1_out_t)(uint8_t)(modeCfg[i * 4U] & PCA9420_MODECFG_0_SW1_OUT_MASK); | ||
288 | |||
289 | configs[i].onCfg = (pca9420_on_cfg_t)(uint8_t)(modeCfg[i * 4U + 1U] & PCA9420_MODECFG_1_ON_CFG_MASK); | ||
290 | configs[i].sw2OutVolt = (pca9420_sw2_out_t)(uint8_t)(modeCfg[i * 4U + 1U] & PCA9420_MODECFG_1_SW2_OUT_MASK); | ||
291 | |||
292 | configs[i].ldo1OutVolt = (pca9420_ldo1_out_t)(uint8_t)(modeCfg[i * 4U + 2U] & PCA9420_MODECFG_2_LDO1_OUT_MASK); | ||
293 | configs[i].enableSw1Out = ((modeCfg[i * 4U + 2U] & ((uint8_t)kPCA9420_RegulatorSwitch1)) != 0U) ? true : false; | ||
294 | configs[i].enableSw2Out = ((modeCfg[i * 4U + 2U] & ((uint8_t)kPCA9420_RegulatorSwitch2)) != 0U) ? true : false; | ||
295 | configs[i].enableLdo1Out = ((modeCfg[i * 4U + 2U] & ((uint8_t)kPCA9420_RegulatorLdo1)) != 0U) ? true : false; | ||
296 | configs[i].enableLdo2Out = ((modeCfg[i * 4U + 2U] & ((uint8_t)kPCA9420_RegulatorLdo2)) != 0U) ? true : false; | ||
297 | |||
298 | configs[i].wdogTimerCfg = (pca9420_wd_timer_t)(uint8_t)(modeCfg[i * 4U + 3U] & PCA9420_MODECFG_3_WD_TIMER_MASK); | ||
299 | configs[i].ldo2OutVolt = (pca9420_ldo2_out_t)(uint8_t)(modeCfg[i * 4U + 3U] & PCA9420_MODECFG_3_LDO2_OUT_MASK); | ||
300 | } | ||
301 | } | ||
302 | |||
303 | static bool PCA9420_ModeControlledByI2C(pca9420_handle_t *handle, pca9420_mode_t mode) | ||
304 | { | ||
305 | uint8_t modeCfgReg = PCA9420_MODECFG_0_0; | ||
306 | uint8_t modeCfg0 = 0U; | ||
307 | bool result; | ||
308 | |||
309 | switch (mode) | ||
310 | { | ||
311 | case kPCA9420_Mode0: | ||
312 | modeCfgReg = PCA9420_MODECFG_0_0; | ||
313 | break; | ||
314 | case kPCA9420_Mode1: | ||
315 | modeCfgReg = PCA9420_MODECFG_1_0; | ||
316 | break; | ||
317 | case kPCA9420_Mode2: | ||
318 | modeCfgReg = PCA9420_MODECFG_2_0; | ||
319 | break; | ||
320 | case kPCA9420_Mode3: | ||
321 | modeCfgReg = PCA9420_MODECFG_3_0; | ||
322 | break; | ||
323 | default: | ||
324 | assert(false); | ||
325 | break; | ||
326 | } | ||
327 | result = PCA9420_ReadRegs(handle, modeCfgReg, &modeCfg0, 1); | ||
328 | assert(result); | ||
329 | if ((modeCfg0 & PCA9420_MODECFG_0_MODE_CTRL_SEL_MASK) == (uint8_t)kPCA9420_ModeSelI2C) | ||
330 | { | ||
331 | result = true; | ||
332 | } | ||
333 | else | ||
334 | { | ||
335 | result = false; | ||
336 | } | ||
337 | |||
338 | return result; | ||
339 | } | ||
340 | |||
341 | bool PCA9420_SwitchMode(pca9420_handle_t *handle, pca9420_mode_t mode) | ||
342 | { | ||
343 | bool result; | ||
344 | |||
345 | /* Switch by Pins first */ | ||
346 | POWER_SetPmicMode((uint32_t)mode, kCfg_Run); | ||
347 | |||
348 | /* Switch by I2C next to make sure switch succeeds no matter modes are controlled by Pins or I2C. */ | ||
349 | result = PCA9420_ModifyReg(handle, PCA9420_TOP_CNTL3, PCA9420_TOP_CNTL3_MODE_I2C_MASK, | ||
350 | ((uint8_t)mode) << PCA9420_TOP_CNTL3_MODE_I2C_SHIFT); | ||
351 | |||
352 | return result; | ||
353 | } | ||
354 | |||
355 | bool PCA9420_GetCurrentMode(pca9420_handle_t *handle, pca9420_mode_t *mode) | ||
356 | { | ||
357 | bool result = true; | ||
358 | uint8_t regValue = 0U; | ||
359 | pca9420_mode_t pinMode, i2cMode; | ||
360 | |||
361 | assert(mode); | ||
362 | |||
363 | pinMode = (pca9420_mode_t)(POWER_GetPmicMode(kCfg_Run)); | ||
364 | |||
365 | if (!PCA9420_ModeControlledByI2C(handle, pinMode)) | ||
366 | { | ||
367 | *mode = pinMode; | ||
368 | } | ||
369 | else | ||
370 | { | ||
371 | result = PCA9420_ReadRegs(handle, PCA9420_TOP_CNTL3, ®Value, 1); | ||
372 | if (result) | ||
373 | { | ||
374 | i2cMode = (pca9420_mode_t)(uint8_t)((regValue & PCA9420_TOP_CNTL3_MODE_I2C_MASK) >> | ||
375 | PCA9420_TOP_CNTL3_MODE_I2C_SHIFT); | ||
376 | *mode = i2cMode; | ||
377 | } | ||
378 | } | ||
379 | |||
380 | return result; | ||
381 | } | ||
382 | |||
383 | uint8_t PCA9420_GetRegulatorStatus(pca9420_handle_t *handle) | ||
384 | { | ||
385 | bool result; | ||
386 | uint8_t status = 0; | ||
387 | |||
388 | /* powerGoodEnable must be configured to true, otherwise the status is always 0. */ | ||
389 | result = PCA9420_ReadRegs(handle, PCA9420_REG_STATUS, &status, 1); | ||
390 | if (!result) | ||
391 | { | ||
392 | assert(false); | ||
393 | } | ||
394 | |||
395 | return status; | ||
396 | } | ||
397 | |||
398 | void PCA9420_FeedWatchDog(pca9420_handle_t *handle) | ||
399 | { | ||
400 | uint8_t regValue = 1; | ||
401 | |||
402 | (void)PCA9420_WriteRegs(handle, PCA9420_TOP_CNTL4, ®Value, 1); | ||
403 | } | ||
404 | |||
405 | bool PCA9420_WriteRegs(pca9420_handle_t *handle, uint8_t regBase, uint8_t *val, uint32_t size) | ||
406 | { | ||
407 | assert(handle); | ||
408 | assert(handle->I2C_SendFunc); | ||
409 | assert(val); | ||
410 | |||
411 | return (kStatus_Success == handle->I2C_SendFunc(handle->slaveAddress, regBase, 1U, val, size)) ? true : false; | ||
412 | } | ||
413 | |||
414 | bool PCA9420_ReadRegs(pca9420_handle_t *handle, uint8_t regBase, uint8_t *val, uint32_t size) | ||
415 | { | ||
416 | assert(handle); | ||
417 | assert(handle->I2C_ReceiveFunc); | ||
418 | assert(val); | ||
419 | |||
420 | return (kStatus_Success == handle->I2C_ReceiveFunc(handle->slaveAddress, regBase, 1U, val, size)) ? true : false; | ||
421 | } | ||
422 | |||
423 | bool PCA9420_ModifyReg(pca9420_handle_t *handle, uint8_t reg, uint8_t mask, uint8_t val) | ||
424 | { | ||
425 | bool result; | ||
426 | uint8_t regValue = 0U; | ||
427 | |||
428 | assert(handle); | ||
429 | |||
430 | /* Read back the register content. */ | ||
431 | result = PCA9420_ReadRegs(handle, reg, ®Value, 1); | ||
432 | if (result) | ||
433 | { | ||
434 | /* Modify the bit-fields you want to change. */ | ||
435 | regValue &= (uint8_t)~mask; | ||
436 | regValue |= val; | ||
437 | |||
438 | /* Write back the content to the registers. */ | ||
439 | result = PCA9420_WriteRegs(handle, reg, ®Value, 1); | ||
440 | } | ||
441 | |||
442 | return result; | ||
443 | } | ||
444 | |||
445 | void PCA9420_EnableInterrupts(pca9420_handle_t *handle, uint32_t source) | ||
446 | { | ||
447 | bool result; | ||
448 | uint8_t regValues[6]; | ||
449 | |||
450 | assert(handle); | ||
451 | |||
452 | /* Read back the register content. */ | ||
453 | result = PCA9420_ReadRegs(handle, PCA9420_SUB_INT0, regValues, sizeof(regValues)); | ||
454 | if (!result) | ||
455 | { | ||
456 | assert(false); | ||
457 | } | ||
458 | |||
459 | regValues[0] = regValues[2] = regValues[4] = 0U; /* Don't clear int status */ | ||
460 | |||
461 | regValues[1] &= (uint8_t)(~(source & 0xFFU)); /* SUB_INT0_MASK */ | ||
462 | regValues[3] &= (uint8_t)(~((source >> 8) & 0xFFU)); /* SUB_INT1_MASK */ | ||
463 | regValues[5] &= (uint8_t)(~((source >> 16) & 0xFFU)); /* SUB_INT2_MASK */ | ||
464 | |||
465 | result = PCA9420_WriteRegs(handle, PCA9420_SUB_INT0, regValues, sizeof(regValues)); | ||
466 | if (!result) | ||
467 | { | ||
468 | assert(false); | ||
469 | } | ||
470 | } | ||
471 | |||
472 | void PCA9420_DisableInterrupts(pca9420_handle_t *handle, uint32_t source) | ||
473 | { | ||
474 | bool result; | ||
475 | uint8_t regValues[6]; | ||
476 | |||
477 | assert(handle); | ||
478 | |||
479 | /* Read back the register content. */ | ||
480 | result = PCA9420_ReadRegs(handle, PCA9420_SUB_INT0, regValues, sizeof(regValues)); | ||
481 | if (!result) | ||
482 | { | ||
483 | assert(false); | ||
484 | } | ||
485 | |||
486 | regValues[0] = regValues[2] = regValues[4] = 0U; /* Don't clear int status */ | ||
487 | |||
488 | regValues[1] |= (uint8_t)(source & 0xFFU); /* SUB_INT0_MASK */ | ||
489 | regValues[3] |= (uint8_t)((source >> 8) & 0xFFU); /* SUB_INT1_MASK */ | ||
490 | regValues[5] |= (uint8_t)((source >> 16) & 0xFFU); /* SUB_INT2_MASK */ | ||
491 | |||
492 | result = PCA9420_WriteRegs(handle, PCA9420_SUB_INT0, regValues, sizeof(regValues)); | ||
493 | if (!result) | ||
494 | { | ||
495 | assert(false); | ||
496 | } | ||
497 | } | ||
498 | |||
499 | uint32_t PCA9420_GetInterruptStatus(pca9420_handle_t *handle) | ||
500 | { | ||
501 | bool result; | ||
502 | uint8_t regValues[6] = {0U}; | ||
503 | |||
504 | assert(handle); | ||
505 | |||
506 | /* Read back the register content. */ | ||
507 | result = PCA9420_ReadRegs(handle, PCA9420_SUB_INT0, regValues, sizeof(regValues)); | ||
508 | if (!result) | ||
509 | { | ||
510 | assert(false); | ||
511 | } | ||
512 | |||
513 | return (((uint32_t)regValues[4]) << 16) | (((uint32_t)regValues[2]) << 8) | (uint32_t)regValues[0]; | ||
514 | } | ||
515 | |||
516 | void PCA9420_ClearInterruptStatus(pca9420_handle_t *handle, uint32_t source) | ||
517 | { | ||
518 | bool result; | ||
519 | uint8_t regValues[6]; | ||
520 | |||
521 | assert(handle); | ||
522 | |||
523 | /* Read back the register content. */ | ||
524 | result = PCA9420_ReadRegs(handle, PCA9420_SUB_INT0, regValues, sizeof(regValues)); | ||
525 | if (!result) | ||
526 | { | ||
527 | assert(false); | ||
528 | } | ||
529 | |||
530 | regValues[0] = (uint8_t)(source & 0xFFU); /* SUB_INT1 */ | ||
531 | regValues[2] = (uint8_t)((source >> 8) & 0xFFU); /* SUB_INT2 */ | ||
532 | regValues[4] = (uint8_t)((source >> 16) & 0xFFU); /* SUB_INT3 */ | ||
533 | |||
534 | result = PCA9420_WriteRegs(handle, PCA9420_SUB_INT0, regValues, sizeof(regValues)); | ||
535 | if (!result) | ||
536 | { | ||
537 | assert(false); | ||
538 | } | ||
539 | } | ||
540 | /******************************************************************************* | ||
541 | * EOF | ||
542 | ******************************************************************************/ | ||