@@ -12,6 +12,15 @@ namespace GridCharger::Huawei {
12
12
13
13
TWAI::~TWAI ()
14
14
{
15
+ if (_pollingTaskHandle != nullptr ) {
16
+ _pollingTaskDone = false ;
17
+ _stopPolling = true ;
18
+
19
+ while (!_pollingTaskDone) { delay (10 ); }
20
+
21
+ _pollingTaskHandle = nullptr ;
22
+ }
23
+
15
24
stopLoop ();
16
25
17
26
if (twai_stop () != ESP_OK) {
@@ -41,7 +50,6 @@ bool TWAI::init()
41
50
auto tx = static_cast <gpio_num_t >(pin.huawei_tx );
42
51
auto rx = static_cast <gpio_num_t >(pin.huawei_rx );
43
52
twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT (tx, rx, TWAI_MODE_NORMAL);
44
- g_config.rx_queue_len = 16 ;
45
53
46
54
// interrupts at level 1 are in high demand, at least on ESP32-S3 boards,
47
55
// but only a limited amount can be allocated. failing to allocate an
@@ -65,30 +73,55 @@ bool TWAI::init()
65
73
return false ;
66
74
}
67
75
76
+ if (!startLoop ()) {
77
+ MessageOutput.printf (" [Huawei::TWAI] failed to start loop task\r\n " );
78
+ return false ;
79
+ }
80
+
81
+ // enable alert on message received
82
+ uint32_t alertsToEnable = TWAI_ALERT_RX_DATA;
83
+ if (twai_reconfigure_alerts (alertsToEnable, NULL ) != ESP_OK) {
84
+ MessageOutput.print (" [Huawei::TWAI] Failed to configure alerts\r\n " );
85
+ return false ;
86
+ }
87
+
88
+ uint32_t constexpr stackSize = 1536 ;
89
+ return pdPASS == xTaskCreate (TWAI::pollAlerts,
90
+ " HuaweiTwai" , stackSize, this , 20 /* prio*/ , &_pollingTaskHandle);
91
+
68
92
MessageOutput.print (" [Huawei::TWAI] driver ready\r\n " );
69
93
70
- return startLoop () ;
94
+ return true ;
71
95
}
72
96
73
- bool TWAI::getMessage (HardwareInterface:: can_message_t & msg )
97
+ void TWAI::pollAlerts ( void * context )
74
98
{
75
- twai_status_info_t status;
99
+ auto & instance = *static_cast <TWAI*>(context);
100
+ uint32_t alerts;
76
101
77
- while (true ) {
78
- if (twai_get_status_info (&status) != ESP_OK) {
79
- MessageOutput.print (" [Huawei::TWAI] Failed to get status info\r\n " );
80
- return false ;
102
+ while (!instance._stopPolling ) {
103
+ if (twai_read_alerts (&alerts, pdMS_TO_TICKS (500 )) != ESP_OK) { continue ; }
104
+
105
+ if (alerts & TWAI_ALERT_RX_DATA) {
106
+ // wake up hardware interface task to actually receive the message
107
+ xTaskNotifyGive (instance.getTaskHandle ());
81
108
}
109
+ }
110
+
111
+ instance._pollingTaskDone = true ;
82
112
83
- if (status.msgs_to_rx == 0 ) { return false ; }
113
+ vTaskDelete (nullptr );
114
+ }
84
115
116
+ bool TWAI::getMessage (HardwareInterface::can_message_t & msg)
117
+ {
118
+ while (true ) {
85
119
twai_message_t rxMessage;
86
120
87
- // wait for message to be received, function is blocking (for 100ms)
88
- if (twai_receive (&rxMessage, pdMS_TO_TICKS (100 )) != ESP_OK) {
89
- MessageOutput.print (" [Huawei::TWAI] Failed to receive message\r\n " );
90
- return false ;
91
- }
121
+ // it's okay if we cannot receive a message now, as the hardware
122
+ // interface task wakes up for reasons other than a message being
123
+ // received, but always checks if a message is available.
124
+ if (twai_receive (&rxMessage, pdMS_TO_TICKS (1 )) != ESP_OK) { return false ; }
92
125
93
126
if (rxMessage.extd != 1 ) { continue ; } // we only process extended format messages
94
127
0 commit comments