-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPoKeysLibPoNETAsyncEnhanced.c
More file actions
200 lines (159 loc) · 6.45 KB
/
PoKeysLibPoNETAsyncEnhanced.c
File metadata and controls
200 lines (159 loc) · 6.45 KB
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
#include "PoKeysLibHal.h"
#include "PoKeysLibAsync.h"
#include <string.h>
/*
* Enhanced PoNET Async Functions for kbd48CNC and advanced PoNET operations.
* These complement the existing basic PoNET async functions with:
* - Enhanced kbd48CNC operations for LinuxCNC integration
* - Combined operations for efficiency
* - Advanced device management
* - RT-safe error handling
*
* Designed specifically for production LinuxCNC applications with
* kbd48CNC devices and other PoNET modules.
*/
// Enhanced kbd48CNC complete update cycle - combines all operations
int PK_PoNETKbd48CNCUpdateCycleAsync(sPoKeysDevice* device)
{
if (!device) return PK_ERR_NOT_CONNECTED;
// This function combines:
// 1. Module settings check
// 2. Light sensor reading
// 3. Button status reading (statusIn)
// 4. LED status update (statusOut)
// 5. PWM brightness update
int result;
// Step 1: Get module settings to verify kbd48CNC is available
result = PK_PoNETGetModuleSettingsAsync(device);
if (result != PK_OK) return result;
// Step 2: Request light sensor reading for brightness control
result = PK_PoNETGetModuleLightRequestAsync(device);
if (result != PK_OK) return result;
// Step 3: Get light sensor value
result = PK_PoNETGetModuleLightAsync(device);
if (result != PK_OK) return result;
// Step 4: Request button status
result = PK_PoNETGetModuleStatusRequestAsync(device);
if (result != PK_OK) return result;
// Step 5: Get button status (statusIn for button presses)
result = PK_PoNETGetModuleStatusAsync(device);
if (result != PK_OK) return result;
// Step 6: Set LED status (statusOut for LED control)
result = PK_PoNETSetModuleStatusAsync(device);
if (result != PK_OK) return result;
// Step 7: Update PWM brightness if needed
result = PK_PoNETSetModulePWMAsync(device);
if (result != PK_OK) return result;
return PK_OK;
}
// Set LED pattern for kbd48CNC - optimized for common patterns
int PK_PoNETKbd48CNCLEDSetPatternAsync(sPoKeysDevice* device, uint8_t pattern[6])
{
if (!device || !pattern) return PK_ERR_GENERIC;
// Copy pattern to device statusOut (48 buttons = 6 bytes)
memcpy(device->PoNETmodule.statusOut, pattern, 6);
// Send the LED pattern update
return PK_PoNETSetModuleStatusAsync(device);
}
// Set kbd48CNC brightness with automatic PWM calculation
int PK_PoNETKbd48CNCBrightnessSetAsync(sPoKeysDevice* device, uint8_t brightness)
{
if (!device) return PK_ERR_NOT_CONNECTED;
// Convert brightness (0-255) to PWM duty cycle
// kbd48CNC uses inverted brightness (255 = bright, 0 = dim)
device->PoNETmodule.PWMduty = 255 - brightness;
return PK_PoNETSetModulePWMAsync(device);
}
// Enhanced device discovery for PoNET modules
int PK_PoNETDeviceDiscoveryAsync(sPoKeysDevice* device)
{
if (!device) return PK_ERR_NOT_CONNECTED;
uint8_t params[1] = { PONET_OP_DEVICE_DISCOVERY };
int req = CreateRequestAsync(device, PK_CMD_POI2C_COMMUNICATION,
params, 1, NULL, 0, NULL);
if (req < 0) return req;
return SendRequestAsync(device, req);
}
// Reinitialize specific PoNET module (useful for error recovery)
int PK_PoNETModuleReinitializeAsync(sPoKeysDevice* device, uint8_t moduleID)
{
if (!device) return PK_ERR_NOT_CONNECTED;
uint8_t params[2] = { PONET_OP_REINITIALIZE, moduleID };
int req = CreateRequestAsync(device, PK_CMD_POI2C_COMMUNICATION,
params, 2, NULL, 0, NULL);
if (req < 0) return req;
return SendRequestAsync(device, req);
}
// Advanced kbd48CNC button mapping function
static void PK_PoNETKbd48CNCMapButtonID(int logicalButton, int* physicalID)
{
/*
* kbd48CNC uses a 4-group mapping scheme for buttons:
* This matches the mapping used in PoKeysCompPoNet.c
*
* Physical layout is remapped to logical button indices 0-47
* for easier LinuxCNC integration.
*/
int offset[] = { 15, 8, 7, 0 };
int top = (logicalButton & 0xF0) + offset[(logicalButton / 4) % 4];
int y = logicalButton % 4;
int ID = top + y;
// Handle even/odd row inversion
if (((logicalButton / 4) % 2) == 0) {
ID = top - y;
}
*physicalID = ID;
}
// Get specific kbd48CNC button state (helper function)
int PK_PoNETKbd48CNCGetButtonStateAsync(sPoKeysDevice* device, uint8_t buttonIndex, bool* pressed)
{
if (!device || !pressed || buttonIndex >= 48) return PK_ERR_GENERIC;
// Map logical button to physical ID
int physicalID;
PK_PoNETKbd48CNCMapButtonID(buttonIndex, &physicalID);
// First ensure we have current status
int result = PK_PoNETGetModuleStatusAsync(device);
if (result != PK_OK) return result;
// Extract button state from statusIn
uint8_t byteIndex = physicalID / 8;
uint8_t bitIndex = physicalID % 8;
*pressed = (device->PoNETmodule.statusIn[byteIndex] & (1 << bitIndex)) != 0;
return PK_OK;
}
// Set specific kbd48CNC LED state (helper function)
int PK_PoNETKbd48CNCSetLEDStateAsync(sPoKeysDevice* device, uint8_t ledIndex, bool on)
{
if (!device || ledIndex >= 48) return PK_ERR_GENERIC;
// Map logical LED to physical ID
int physicalID;
PK_PoNETKbd48CNCMapButtonID(ledIndex, &physicalID);
// Update statusOut
uint8_t byteIndex = physicalID / 8;
uint8_t bitIndex = physicalID % 8;
if (on) {
device->PoNETmodule.statusOut[byteIndex] |= (1 << bitIndex);
} else {
device->PoNETmodule.statusOut[byteIndex] &= ~(1 << bitIndex);
}
// Send the update
return PK_PoNETSetModuleStatusAsync(device);
}
// Batch update multiple kbd48CNC LEDs efficiently
int PK_PoNETKbd48CNCSetMultipleLEDsAsync(sPoKeysDevice* device, const uint8_t* ledStates)
{
if (!device || !ledStates) return PK_ERR_GENERIC;
// Clear all statusOut first
memset(device->PoNETmodule.statusOut, 0, 16);
// Set LEDs according to ledStates array (48 bits = 6 bytes)
for (int i = 0; i < 48; i++) {
if (ledStates[i / 8] & (1 << (i % 8))) {
int physicalID;
PK_PoNETKbd48CNCMapButtonID(i, &physicalID);
uint8_t byteIndex = physicalID / 8;
uint8_t bitIndex = physicalID % 8;
device->PoNETmodule.statusOut[byteIndex] |= (1 << bitIndex);
}
}
// Send the batch update
return PK_PoNETSetModuleStatusAsync(device);
}