@@ -56,12 +56,14 @@ const char kTwaiSpeeds[] PROGMEM = "25K|50K|100K|125K|250K|500K|800K|1M";
56
56
const char kTwaiModes [] PROGMEM = " Normal|No Ack|Listen Only" ;
57
57
58
58
struct TWAIs {
59
- twai_handle_t bus[MAX_TWAI];
60
- twai_mode_t mode[MAX_TWAI];
61
- uint8_t speed[MAX_TWAI];
62
- bool installed[MAX_TWAI];
63
- bool supported;
64
- } Twai;
59
+ twai_handle_t bus;
60
+ twai_mode_t mode;
61
+ uint8_t rx_queue_len;
62
+ uint8_t speed;
63
+ bool installed;
64
+ } Twai[MAX_TWAI];
65
+
66
+ bool Twai_supported;
65
67
66
68
#ifdef USE_BERRY
67
69
/* ********************************************************************************************\
@@ -72,18 +74,28 @@ struct TWAIs {
72
74
file twai_minimal.be contents:
73
75
74
76
class twai_cls
75
- var twai_speed, twai_mode # (int, int)
77
+ var twai_speed, twai_mode, twai_rx_queue_len # (int, int, int)
76
78
77
79
def init()
78
- self.twai_speed = 4 # 0 = 25K, 1 = 50K, 2 = 100K, 3 = 125K, 4 = 250K, 5 = 500K, 6 = 800K, 7 = 1Mbits
79
- self.twai_mode = 2 # 0 = TWAI_MODE_NORMAL, 1 = TWAI_MODE_NO_ACK, 2 = TWAI_MODE_LISTEN_ONLY
80
+ self.twai_speed = 4 # 0 = 25K, 1 = 50K, 2 = 100K, 3 = 125K, 4 = 250K, 5 = 500K, 6 = 800K, 7 = 1Mbits
81
+ self.twai_mode = 2 # 0 = TWAI_MODE_NORMAL, 1 = TWAI_MODE_NO_ACK, 2 = TWAI_MODE_LISTEN_ONLY
82
+ self.twai_rx_queue_len = 8 # 1 .. 64
83
+
84
+ if global.twai_driver
85
+ global.twai_driver.stop() # Let previous instance bail out cleanly
86
+ end
87
+ tasmota.add_driver(global.twai_driver := self)
88
+ end
89
+
90
+ def stop()
91
+ tasmota.remove_driver(self)
80
92
end
81
93
82
94
#----------------------------------------------------------------------------------------------
83
95
Allow TWAI driver configuration on restart (if this file is installed by preinit.be)
84
96
----------------------------------------------------------------------------------------------#
85
97
def config(bus) # This function name (config) is called by the TWAI driver!
86
- return self.twai_mode << 3 | self.twai_speed # Initial configure TWAI driver
98
+ return ( self.twai_rx_queue_len -1) << 5 | self.twai_mode << 3 | self.twai_speed # Initial configure TWAI driver
87
99
end
88
100
89
101
#----------------------------------------------------------------------------------------------
@@ -99,7 +111,6 @@ class twai_cls
99
111
end
100
112
101
113
twai = twai_cls() # This class name (twai) is used by the TWAI driver!
102
- tasmota.add_driver(twai)
103
114
104
115
// *******************************************************************************************
105
116
@@ -158,10 +169,19 @@ bool TWAIBerryConfig(uint32_t bus) {
158
169
be_pop (vm, 2 );
159
170
if (be_isint (vm, -1 )) {
160
171
uint32_t config = be_toint (vm, -1 );
161
- Twai.speed [bus] = config & 0x7 ; // User input check 0..7
172
+ // 3322222222221111111111
173
+ // 10987654321098765432109876543210
174
+ // xxxxxxxxxxxxxxxxxxxxxxxxxxxxx111 = speed 0..7
175
+ // xxxxxxxxxxxxxxxxxxxxxxxxxxx11xxx = mode 0..2
176
+ // xxxxxxxxxxxxxxxxxxxxx111111xxxxx = rx_queue_len 0..63
177
+ Twai[bus].speed = config & 0x7 ; // User input check 0..7
162
178
uint32_t mode = config >> 3 & 0x3 ;
163
179
if (mode > 2 ) { mode = 2 ; } // User input check 0..2
164
- Twai.mode [bus] = (twai_mode_t )mode;
180
+ Twai[bus].mode = (twai_mode_t )mode;
181
+ uint32_t rx_queue_len = config >> 5 & 0x3f ;
182
+ rx_queue_len++; // Rx queue len 1..64
183
+ if (rx_queue_len < 8 ) { rx_queue_len = 8 ; } // User input check 8..64
184
+ Twai[bus].rx_queue_len = rx_queue_len;
165
185
handled = true ;
166
186
}
167
187
}
@@ -178,12 +198,12 @@ bool TWAIBerryConfig(uint32_t bus) {
178
198
179
199
bool TWAIStart (int tx, int rx, uint32_t bus = 0 );
180
200
bool TWAIStart (int tx, int rx, uint32_t bus) {
181
- twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT ((gpio_num_t )tx, (gpio_num_t )rx, Twai. mode [bus]);
201
+ twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT ((gpio_num_t )tx, (gpio_num_t )rx, Twai[bus]. mode );
182
202
g_config.controller_id = bus;
183
- g_config.rx_queue_len = 32 ;
203
+ g_config.rx_queue_len = Twai[bus]. rx_queue_len ;
184
204
185
205
twai_timing_config_t t_config;
186
- switch (Twai. speed [bus]) {
206
+ switch (Twai[bus]. speed ) {
187
207
case 0 :
188
208
t_config = TWAI_TIMING_CONFIG_25KBITS ();
189
209
break ;
@@ -215,39 +235,39 @@ bool TWAIStart(int tx, int rx, uint32_t bus) {
215
235
216
236
twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL ();
217
237
218
- if (twai_driver_install_v2 (&g_config, &t_config, &f_config, &Twai. bus [bus]) != ESP_OK) {
238
+ if (twai_driver_install_v2 (&g_config, &t_config, &f_config, &Twai[bus]. bus ) != ESP_OK) {
219
239
AddLog (LOG_LEVEL_DEBUG, PSTR (" TWA: Bus%d Not installed" ), bus +1 );
220
240
return false ;
221
241
}
222
- if (twai_start_v2 (Twai. bus [bus]) != ESP_OK) {
242
+ if (twai_start_v2 (Twai[bus]. bus ) != ESP_OK) {
223
243
AddLog (LOG_LEVEL_DEBUG, PSTR (" TWA: Bus%d Not started" ), bus +1 );
224
244
return false ;
225
245
}
226
246
// Reconfigure alerts to detect frame receive, Bus-Off error and RX queue full states
227
247
uint32_t alerts_to_enable = TWAI_ALERT_RX_DATA | TWAI_ALERT_RX_QUEUE_FULL | TWAI_ALERT_TX_IDLE | TWAI_ALERT_TX_SUCCESS | TWAI_ALERT_TX_FAILED | TWAI_ALERT_ERR_PASS | TWAI_ALERT_BUS_ERROR;
228
- if (twai_reconfigure_alerts_v2 (Twai. bus [bus], alerts_to_enable, NULL ) != ESP_OK) {
248
+ if (twai_reconfigure_alerts_v2 (Twai[bus]. bus , alerts_to_enable, NULL ) != ESP_OK) {
229
249
AddLog (LOG_LEVEL_DEBUG, PSTR (" TWA: Bus%d Failed to reconfigure CAN alerts" ), bus +1 );
230
250
return false ;
231
251
}
232
252
233
253
char smode[16 ];
234
- GetTextIndexed (smode, sizeof (smode), Twai. mode [bus], kTwaiModes );
254
+ GetTextIndexed (smode, sizeof (smode), Twai[bus]. mode , kTwaiModes );
235
255
char sspeed[16 ];
236
- GetTextIndexed (sspeed, sizeof (sspeed), Twai. speed [bus], kTwaiSpeeds );
256
+ GetTextIndexed (sspeed, sizeof (sspeed), Twai[bus]. speed , kTwaiSpeeds );
237
257
AddLog (LOG_LEVEL_DEBUG, PSTR (" TWA: Bus%d using GPIO%02d(Tx) and GPIO%02d(Rx) started in %s Mode and %sbit/s" ),
238
258
bus +1 , tx, rx, smode, sspeed);
239
259
240
- Twai. installed [bus] = true ;
260
+ Twai[bus]. installed = true ;
241
261
return true ;
242
262
}
243
263
244
264
/* ********************************************************************************************/
245
265
246
266
void TWAIStop (uint32_t bus) {
247
- if (Twai. installed [bus]) {
248
- twai_stop_v2 (Twai. bus [bus]);
249
- twai_driver_uninstall_v2 (Twai. bus [bus]);
250
- Twai. installed [bus] = false ;
267
+ if (Twai[bus]. installed ) {
268
+ twai_stop_v2 (Twai[bus]. bus );
269
+ twai_driver_uninstall_v2 (Twai[bus]. bus );
270
+ Twai[bus]. installed = false ;
251
271
AddLog (LOG_LEVEL_DEBUG, PSTR (" TWA: Bus%d stopped" ), bus +1 );
252
272
}
253
273
}
@@ -256,9 +276,9 @@ void TWAIStop(uint32_t bus) {
256
276
257
277
uint32_t TWAICheckAlerts (uint32_t bus) {
258
278
uint32_t alerts_triggered;
259
- twai_read_alerts_v2 (Twai. bus [bus], &alerts_triggered, pdMS_TO_TICKS (TWAI_POLLING_RATE_MS));
279
+ twai_read_alerts_v2 (Twai[bus]. bus , &alerts_triggered, pdMS_TO_TICKS (TWAI_POLLING_RATE_MS));
260
280
twai_status_info_t twaistatus;
261
- twai_get_status_info_v2 (Twai. bus [bus], &twaistatus);
281
+ twai_get_status_info_v2 (Twai[bus]. bus , &twaistatus);
262
282
263
283
// Handle alerts
264
284
if (alerts_triggered & TWAI_ALERT_ERR_PASS) {
@@ -290,7 +310,7 @@ void TWAIRead(uint32_t bus) {
290
310
if (alerts_triggered & TWAI_ALERT_RX_DATA) {
291
311
// One or more messages received. Handle all.
292
312
twai_message_t message;
293
- while (twai_receive_v2 (Twai. bus [bus], &message, 0 ) == ESP_OK) {
313
+ while (twai_receive_v2 (Twai[bus]. bus , &message, 0 ) == ESP_OK) {
294
314
uint32_t identifier = message.identifier | message.extd << 31 ; // Add extended 29-bit flag
295
315
#ifdef USE_BERRY
296
316
if (TWAIBerryDecode (bus, identifier, message.data_length_code , message.data )) { continue ; }
@@ -307,16 +327,17 @@ void TWAIRead(uint32_t bus) {
307
327
\*********************************************************************************************/
308
328
309
329
void TWAIInit (void ) {
310
- Twai. supported = false ;
330
+ Twai_supported = false ;
311
331
for (uint32_t bus = 0 ; bus < MAX_TWAI; bus++) {
312
332
if (PinUsed (GPIO_TWAI_TX, bus) && PinUsed (GPIO_TWAI_RX, bus)) {
313
- Twai.speed [bus] = TWAI_SPEED_100KBITS;
314
- Twai.mode [bus] = TWAI_MODE_NORMAL; // 0 = TWAI_MODE_NORMAL, 1 = TWAI_MODE_NO_ACK, 2 = TWAI_MODE_LISTEN_ONLY
333
+ Twai[bus].speed = TWAI_SPEED_100KBITS;
334
+ Twai[bus].mode = TWAI_MODE_NORMAL; // 0 = TWAI_MODE_NORMAL, 1 = TWAI_MODE_NO_ACK, 2 = TWAI_MODE_LISTEN_ONLY
335
+ Twai[bus].rx_queue_len = 8 ;
315
336
#ifdef USE_BERRY
316
337
TWAIBerryConfig (bus);
317
338
#endif // USE_BERRY
318
339
if (TWAIStart (Pin (GPIO_TWAI_TX, bus), Pin (GPIO_TWAI_RX, bus), bus)) {
319
- Twai. supported = true ;
340
+ Twai_supported = true ;
320
341
}
321
342
}
322
343
}
@@ -341,7 +362,7 @@ void CmndTWAISend(void) {
341
362
// TwaiSend2 {"ID":0x80000481,"DATA":[0x03,0x1E,0xFF,0xFF,0xFF,0x01,0x21]}
342
363
if ((XdrvMailbox.index > 0 ) && (XdrvMailbox.index <= MAX_TWAI) && (XdrvMailbox.data_len > 0 )) {
343
364
uint32_t bus = XdrvMailbox.index -1 ;
344
- if (!Twai. installed [bus]) { return ; }
365
+ if (!Twai[bus]. installed ) { return ; }
345
366
346
367
uint32_t data[9 ] = { 0 }; // Accomodate identifier and 8 data bytes
347
368
uint32_t data_count = 0 ;
@@ -381,9 +402,9 @@ void CmndTWAISend(void) {
381
402
message.data [i] = data[i +1 ]; // Payload
382
403
}
383
404
384
- twai_clear_receive_queue_v2 (Twai. bus [bus]);
405
+ twai_clear_receive_queue_v2 (Twai[bus]. bus );
385
406
// Queue message for transmission
386
- if (twai_transmit_v2 (Twai. bus [bus], &message, pdMS_TO_TICKS (TWAI_POLLING_RATE_MS)) == ESP_OK) {
407
+ if (twai_transmit_v2 (Twai[bus]. bus , &message, pdMS_TO_TICKS (TWAI_POLLING_RATE_MS)) == ESP_OK) {
387
408
AddLog (LOG_LEVEL_DEBUG_MORE, PSTR (" TWA: Bus%d Message queued for transmission" ), bus +1 );
388
409
} else {
389
410
AddLog (LOG_LEVEL_DEBUG, PSTR (" TWA: Bus%d Alert - Failed to queue message for transmission" ), bus +1 );
@@ -402,11 +423,11 @@ bool Xdrv91(uint32_t function) {
402
423
if (FUNC_INIT == function) {
403
424
TWAIInit ();
404
425
}
405
- else if (Twai. supported ) {
426
+ else if (Twai_supported ) {
406
427
switch (function) {
407
428
case FUNC_LOOP:
408
429
for (uint32_t bus = 0 ; bus < MAX_TWAI; bus++) {
409
- if (Twai. installed [bus]) {
430
+ if (Twai[bus]. installed ) {
410
431
TWAIRead (bus);
411
432
}
412
433
}
0 commit comments