-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathAT42QT1244_ex.c
144 lines (99 loc) · 4.84 KB
/
AT42QT1244_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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*!\file AT42QT1244_ex.c
** \author SMFSW
** \copyright MIT (c) 2017-2024, SMFSW
** \brief AT42QT1244 Driver extensions
** \details AT42QT1244: 24-key QMatrix FMEA IEC/EN/UL60730 Touch Sensor
**/
/****************************************************************/
#include "AT42QT1244.h"
#if defined(HAL_I2C_MODULE_ENABLED)
#if defined(I2C_AT42QT1244)
/****************************************************************/
FctERR NONNULL__ AT42QT1244_Send_Command(AT42QT1244_t * const pCpnt, const AT42QT_cmd cmd)
{
if ((cmd > AT42QT__RESET_DEVICE) && (cmd < AT42QT__LOW_LEVEL_CALIBRATION) && (cmd != AT42QT__WRITE_SETUPS)) { return ERROR_VALUE; }
return AT42QT1244_Write(pCpnt->cfg.slave_inst, (uint8_t *) &cmd, AT42QT__CONTROL_COMMAND, 1);
}
FctERR NONNULL__ AT42QT1244_Send_Setup(AT42QT1244_t * const pCpnt, uint16_t * const hcrc, const uint8_t * setup, const uint8_t addr, const uint8_t Nb)
{
uint8_t SETUP[111];
FctERR err;
*hcrc = 0;
if ((addr < AT42QT__SETUP_KEYS_THRESHOLD_0) || (addr > AT42QT__SETUP_NOISE)) { return ERROR_VALUE; }
if (Nb > AT42QT__SETUP_NOISE - AT42QT__SETUP_KEYS_THRESHOLD_0 + 1) { return ERROR_RANGE; }
#if defined(HAL_IWDG_MODULE_ENABLED)
HAL_IWDG_Refresh(&hiwdg); // Refresh watchdog (as the whole procedure may take up some time)
#endif
err = AT42QT1244_Read(pCpnt->cfg.slave_inst, &SETUP[1], AT42QT__SETUP_KEYS_THRESHOLD_0, sizeof(SETUP) - 3); // No need to read COMMAND & CRC registers
if (!err)
{
SETUP[0] = AT42QT__WRITE_SETUPS;
memcpy(&SETUP[addr - AT42QT__SETUP_KEYS_THRESHOLD_0] + 1, setup, Nb);
// Compute CRC excluding COMMAND & CRC registers
for (uintCPU_t i = 1 ; i < sizeof(SETUP) - 2 ; i++) { *hcrc = AT42QT1244_crc16(*hcrc, SETUP[i]); }
SETUP[sizeof(SETUP) - 2] = LOBYTE(*hcrc);
SETUP[sizeof(SETUP) - 1] = HIBYTE(*hcrc);
err |= AT42QT1244_Write(pCpnt->cfg.slave_inst, SETUP, AT42QT__CONTROL_COMMAND, sizeof(SETUP));
}
return err;
}
FctERR NONNULL__ AT42QT1244_Setup_Keys(AT42QT1244_t * const pCpnt, uint16_t * const hcrc, const uint32_t mask_keys, const bool use)
{
const uint8_t NDIL_Val = 4; // 4 is the default NDIL value
uAT42QT_REG__SETUP_165_188 TMP[AT42QT1244_MAX_KEYS];
FctERR err;
err = AT42QT1244_Read(pCpnt->cfg.slave_inst, &TMP[0].Byte, AT42QT__SETUP_KEYS_MODE_0, sizeof(TMP)); // 165 is the NDIL register of the 1st key
if (err) { return err; }
for (uintCPU_t i = 0, j = 1 ; i < AT42QT1244_MAX_KEYS ; i++, j <<= 1)
{
if (!(mask_keys & j)) { continue; } // Skip key if not in the mask
TMP[i].Bits.NDIL = use ? NDIL_Val : 0;
}
return AT42QT1244_Send_Setup(pCpnt, hcrc, &TMP[0].Byte, AT42QT__SETUP_KEYS_MODE_0, sizeof(TMP));
}
FctERR NONNULL__ AT42QT1244_Setup_FHM(AT42QT1244_t * const pCpnt, uint16_t * const hcrc, const AT42QT_FHM FHM)
{
uAT42QT_REG__SETUP_244 TMP;
FctERR err;
if (FHM > AT42QT__FHM_FREQUENCY_SWEEP) { return ERROR_VALUE; }
err = AT42QT1244_Read(pCpnt->cfg.slave_inst, &TMP.Byte, AT42QT__SETUP_FREQ_HOPING_DWELL, 1);
if (err) { return err; }
TMP.Bits.FHM = FHM;
return AT42QT1244_Send_Setup(pCpnt, hcrc, &TMP.Byte, AT42QT__SETUP_FREQ_HOPING_DWELL, 1);
}
FctERR NONNULL__ AT42QT1244_Reset(AT42QT1244_t * const pCpnt)
{
FctERR err;
AT42QT1244_Set_Reset_Time(pCpnt);
err = AT42QT1244_Send_Command(pCpnt, AT42QT__RESET_DEVICE);
if (!err) { AT42QT1244_Delay_PowerOn(pCpnt); }
return err;
}
FctERR NONNULL__ AT42QT1244_Get_Keys(AT42QT1244_t * const pCpnt, uint32_t * Keys)
{
uint8_t TMP[3];
FctERR err = AT42QT1244_Read(pCpnt->cfg.slave_inst, TMP, AT42QT__DETECT_STATUS_1, sizeof(TMP));
if (err) { return err; }
*Keys = (LSHIFT(TMP[2], 16) + LSHIFT(TMP[1], 8) + TMP[0]) & 0x00FFFFFFUL;
return ERROR_OK;
}
intCPU_t NONNULL__ AT42QT1244_is_Calib_Pending(AT42QT1244_t * const pCpnt)
{
uAT42QT_REG__DEVICE_STATUS ST;
FctERR err = AT42QT1244_Get_Status(pCpnt, &ST);
if (err) { return -1; }
return ST.Bits.Key_In_Calib;
}
/****************************************************************/
__WEAK FctERR NONNULL__ AT42QT1244_CHANGE_GPIO_Init(AT42QT1244_t * const pCpnt, GPIO_TypeDef * const GPIOx, const uint16_t GPIO_Pin, const GPIO_PinState GPIO_Active) {
return I2C_peripheral_GPIO_init(&pCpnt->cfg.CHANGE_GPIO, GPIOx, GPIO_Pin, GPIO_Active); }
__WEAK FctERR NONNULL__ AT42QT1244_CHANGE_GPIO_Get(AT42QT1244_t * const pCpnt, bool * const pState) {
return I2C_peripheral_GPIO_get(&pCpnt->cfg.CHANGE_GPIO, pState); }
__WEAK FctERR NONNULL__ AT42QT1244_RST_GPIO_Init(AT42QT1244_t * const pCpnt, GPIO_TypeDef * const GPIOx, const uint16_t GPIO_Pin, const GPIO_PinState GPIO_Active) {
return I2C_peripheral_GPIO_init(&pCpnt->cfg.RST_GPIO, GPIOx, GPIO_Pin, GPIO_Active); }
__WEAK FctERR NONNULL__ AT42QT1244_RST_GPIO_Set(AT42QT1244_t * const pCpnt, const bool state) {
return I2C_peripheral_GPIO_set(&pCpnt->cfg.RST_GPIO, state); }
/****************************************************************/
#endif
#endif
/****************************************************************/