-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathNCA9595_ex.c
127 lines (88 loc) · 3.96 KB
/
NCA9595_ex.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*!\file NCA9595_ex.c
** \author SMFSW
** \copyright MIT (c) 2017-2024, SMFSW
** \brief NCA9595 Driver extensions
** \details NCA9595: Low-voltage 16-bit I²C and SMBus I/O expander
**/
/****************************************************************/
#include "NCA9595.h"
#if defined(HAL_I2C_MODULE_ENABLED)
#if defined(I2C_NCA9595)
/****************************************************************/
/*!\brief Write Register with mask for NCA9595 peripheral
** \param[in,out] pCpnt - Pointer to NCA9595 component
** \param[in] val - Value to write
** \param[in] mask - Mask for write
** \param[in] reg - Register address
** \return Error code
**/
static FctERR NONNULL__ NCA9595_Write_Reg_Mask(NCA9595_t * const pCpnt, const uint16_t val, const uint16_t mask, const NCA9595_wreg reg)
{
uint16_t data;
const FctERR err = NCA9595_Read_Word(pCpnt->cfg.slave_inst, &data, reg);
if (err) { return err; }
const uint16_t final_mask = ~pCpnt->cfg.NCA9595_Cfg.Word & mask;
SET_BITS_VAL(data, final_mask, val);
return NCA9595_Write_Word(pCpnt->cfg.slave_inst, &data, reg);
}
FctERR NONNULL__ NCA9595_Read_Inputs(NCA9595_t * const pCpnt, uint16_t * const in)
{
const FctERR err = NCA9595_Read_Word(pCpnt->cfg.slave_inst, &pCpnt->NCA9595_in.Word, NCA9595__InputPorts);
if (!err) { *in = pCpnt->NCA9595_in.Word; }
return err;
}
FctERR NONNULL__ NCA9595_Write_Outputs(NCA9595_t * const pCpnt, const uint16_t out)
{
const uint16_t data = out & ~pCpnt->cfg.NCA9595_Cfg.Word; // Keep outputs only
const FctERR err = NCA9595_Write_Word(pCpnt->cfg.slave_inst, &data, NCA9595__OutputPorts);
if (!err) { pCpnt->NCA9595_out.Word = data; }
return err;
}
FctERR NONNULL__ NCA9595_Write_Outputs_Mask(NCA9595_t * const pCpnt, const uint16_t out, const uint16_t mask)
{
const uint16_t final_mask = ~pCpnt->cfg.NCA9595_Cfg.Word & mask;
uint16_t data = pCpnt->NCA9595_out.Word;
SET_BITS_VAL(data, final_mask, out);
FctERR err = NCA9595_Write_Word(pCpnt->cfg.slave_inst, &data, NCA9595__OutputPorts);
if (!err) { pCpnt->NCA9595_out.Word = data; }
return err;
}
FctERR NONNULL__ NCA9595_Set_Config(NCA9595_t * const pCpnt, const uint16_t cfg)
{
const FctERR err = NCA9595_Write_Word(pCpnt->cfg.slave_inst, &cfg, NCA9595__ConfigPorts);
if (!err) { pCpnt->cfg.NCA9595_Cfg.Word = cfg; }
return err;
}
FctERR NONNULL__ NCA9595_Set_Config_Mask(NCA9595_t * const pCpnt, const uint16_t cfg, const uint16_t mask)
{
uint16_t data = pCpnt->cfg.NCA9595_Cfg.Word; // Instead of getting values from chip
SET_BITS_VAL(data, mask, cfg);
const FctERR err = NCA9595_Write_Word(pCpnt->cfg.slave_inst, &data, NCA9595__ConfigPorts);
if (!err) { pCpnt->cfg.NCA9595_Cfg.Word = data; }
return err;
}
FctERR NONNULL__ NCA9595_Set_Polarity(NCA9595_t * const pCpnt, const uint16_t pol)
{
return NCA9595_Write_Word(pCpnt->cfg.slave_inst, &pol, NCA9595__PolarityPorts);
}
FctERR NONNULL__ NCA9595_Set_Polarity_Mask(NCA9595_t * const pCpnt, const uint16_t pol, const uint16_t mask)
{
return NCA9595_Write_Reg_Mask(pCpnt, pol, mask, NCA9595__PolarityPorts);
}
FctERR NONNULL__ NCA9595_Set_PullUp(NCA9595_t * const pCpnt, const uint16_t pullup)
{
return NCA9595_Write_Word(pCpnt->cfg.slave_inst, &pullup, NCA9595__PullUpConfigPorts);
}
FctERR NONNULL__ NCA9595_Set_PullUp_Mask(NCA9595_t * const pCpnt, const uint16_t pullup, const uint16_t mask)
{
return NCA9595_Write_Reg_Mask(pCpnt, pullup, mask, NCA9595__PullUpConfigPorts);
}
/****************************************************************/
__WEAK FctERR NONNULL__ NCA9595_INT_GPIO_Init(NCA9595_t * const pCpnt, GPIO_TypeDef * const GPIOx, const uint16_t GPIO_Pin, const GPIO_PinState GPIO_Active) {
return I2C_peripheral_GPIO_init(&pCpnt->cfg.INT_GPIO, GPIOx, GPIO_Pin, GPIO_Active); }
__WEAK FctERR NONNULL__ NCA9595_INT_GPIO_Get(NCA9595_t * const pCpnt, bool * const pState) {
return I2C_peripheral_GPIO_get(&pCpnt->cfg.INT_GPIO, pState); }
/****************************************************************/
#endif
#endif
/****************************************************************/