You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Increased stability in measurement modes, the messages are now sent less frequently
Added a watchdog task, reset by radio messages
Extended time before automatic AC macro kicks in after entering the AC menu
voidavrc_metadata_callback(uint8_t md_type, constuint8_t *data2) { // fills the song title buffer with data, updates text_lenght with the amount of chars
10
+
xSemaphoreTake(CAN_MsgSemaphore, portMAX_DELAY); // take the semaphore as a way to prevent the buffers being accessed elsewhere
DIS_forceUpdate=1; // lets the main loop() know that there's a new song title in the buffer
30
32
md_title_recvd=0;
@@ -69,36 +71,40 @@ void a2dp_init(){
69
71
a2dp_sink.start("EHU32"); // setting up bluetooth audio sink
70
72
a2dp_started=1;
71
73
DEBUG_PRINTLN("A2DP: Started!");
72
-
disp_mode=0; // set display mode to audio metadata on boot
73
-
writeTextToDisplay(1, "EHU32 v0.9.1 started!", "Bluetooth on", "Waiting for connection...");
74
+
disp_mode=-1; // set display mode to audio metadata on boot
75
+
writeTextToDisplay(1, "EHU32 v0.9.2 started!", "Bluetooth on", "Waiting for connection...");
74
76
}
75
77
76
78
// handles events such as connecion/disconnection and audio play/pause
77
79
voidA2DP_EventHandler(){
78
80
if(ehu_started && !a2dp_started){ // this enables bluetooth A2DP service only after the radio is started
79
81
a2dp_init();
80
82
}
81
-
82
-
if(audio_state_changed && bt_connected){ // mute external DAC when not playing; bt_connected ensures no "Connected, paused" is displayed, seems that the audio_state_changed callback comes late
83
-
if(bt_audio_playing){
84
-
digitalWrite(PCM_MUTE_CTL, HIGH);
85
-
DIS_forceUpdate=1; // force reprinting of audio metadata when the music is playing
if(audio_state_changed && bt_connected){ // mute external DAC when not playing; bt_connected ensures no "Connected, paused" is displayed, seems that the audio_state_changed callback comes late
97
+
if(bt_audio_playing){
98
+
digitalWrite(PCM_MUTE_CTL, HIGH);
99
+
DIS_forceUpdate=1; // force reprinting of audio metadata when the music is playing
if(disp_mode!=-1){ // don't bother checking the data if there's no need to update the display
54
54
if(Recvd_CAN_MSG.data[0]==0x10 && (Recvd_CAN_MSG.data[1]<0x40 || (Recvd_CAN_MSG.data[1]<0x4F && Recvd_CAN_MSG.data[2]==0x50))){ // we check if the total payload of radio's message is small, if yes assume it's an Aux message
55
55
DEBUG_PRINTLN("CAN: Received display update, trying to block");
56
-
twai_transmit(&Msg_PreventDisplayUpdate, pdMS_TO_TICKS(10)); // radio blocking msg has to be transmitted ASAP, which is why we skip the queue
56
+
twai_transmit(&Msg_PreventDisplayUpdate, pdMS_TO_TICKS(30)); // radio blocking msg has to be transmitted ASAP, which is why we skip the queue
if(disp_mode==0) vTaskResume(canDisplayTaskHandle); // only retransmit the msg for audio metadata mode
65
+
if(disp_mode==0 || disp_mode==2) vTaskResume(canDisplayTaskHandle); // only retransmit the msg for audio metadata mode and single line coolant, since these don't update frequently
switch(RxMsg.data[0]){ // measurement block ID -> update data which the message is referencing, I may implement more cases in the future which is why switch is there
154
156
case0x0B: { // 0x0B references coolant temps
157
+
DEBUG_PRINT("coolant\n");
155
158
int CAN_data_coolant=RxMsg.data[5]-40;
156
159
snprintf(voltage_buffer, sizeof(voltage_buffer), "No additional data available");
if(disp_mode==1 || disp_mode==2) xSemaphoreGive(CAN_MsgSemaphore); // let the message processing continue
169
176
break;
170
177
}
171
178
case0x548: { // AC measurement blocks
179
+
if(disp_mode==1 || disp_mode==2) xSemaphoreTake(CAN_MsgSemaphore, portMAX_DELAY); // if we're in body data mode, take the semaphore to prevent the buffer being modified while the display message is being compiled
180
+
DEBUG_PRINT("CAN: Got measurements from ECC: ");
172
181
switch(RxMsg.data[0]){ // measurement block ID -> update data which the message is referencing
173
182
case0x07: { // 0x10 references battery voltage
174
183
CAN_data_voltage=RxMsg.data[2];
175
184
CAN_data_voltage/=10;
176
185
snprintf(voltage_buffer, sizeof(voltage_buffer), "Voltage: %.1f V ", CAN_data_voltage);
// this task waits for a flow control packet from the display
366
+
// this task implements ISO 15765-2 (multi-packet transmission over CAN frames) in a crude, but hopefully robust way in order to send frames to the display
349
367
voidcanDisplayTask(void *pvParameters){
350
368
while(1){
351
-
if(xSemaphoreTake(CAN_MsgSemaphore, pdMS_TO_TICKS(100))==pdTRUE){ // if the buffer is being accessed, block indefinitely
369
+
if(xSemaphoreTake(CAN_MsgSemaphore, portMAX_DELAY)==pdTRUE){ // if the buffer is being accessed, block indefinitely
352
370
if(CAN_flowCtlFail){ // failed transmitting flow control before the display resulting in an error frame, wait for a bit before sending it again, skip queue
353
371
vTaskDelay(pdMS_TO_TICKS(1));
354
-
twai_transmit(&Msg_PreventDisplayUpdate, pdMS_TO_TICKS(10)); // hope for the best and send flow control again
372
+
twai_transmit(&Msg_PreventDisplayUpdate, pdMS_TO_TICKS(10)); // hope for the best and send flow control again, skip queue
//xEventGroupWaitBits(CAN_Events, CAN_MessageReady, pdFALSE, pdFALSE, portMAX_DELAY); // this waits until CAN_MessageReady is set by the transmit function (only in case of a successful TX)
365
-
if(CAN_MessageReady && !CAN_prevTxFail){ // possibly not needed anymore?
383
+
if(CAN_MessageReady && !CAN_prevTxFail){ // possibly not needed anymore? nope, still needed until I'm competent enough to implement EventGroups
366
384
DEBUG_PRINTLN("CAN: Now waiting for 2C1...");
367
-
xTaskNotifyWait(0, 0, NULL, portMAX_DELAY); // waiting for a notification from the canProcessTask once a flow control frame is received
385
+
xTaskNotifyWait(0, 0, NULL, pdMS_TO_TICKS(100));
368
386
sendMultiPacketData();
369
387
xTaskNotifyStateClear(NULL);
370
388
} else {
371
389
vTaskDelay(10);
372
390
}
373
391
xSemaphoreGive(CAN_MsgSemaphore); // release the semaphore
374
392
}
375
-
vTaskSuspend(NULL);
393
+
vTaskSuspend(NULL);// have the display task stop itself
376
394
}
377
395
}
378
396
379
397
// this task provides asynchronous simulation of button presses on the AC panel, quickly toggling AC
380
398
voidcanAirConMacroTask(void *pvParameters){
381
399
while(1){
382
-
vTaskDelay(100);
400
+
vTaskDelay(500); // initial delay has to be extended, in some cases 100ms was not enough to have the AC menu appear on the screen, resulting in the inputs being dropped and often entering the vent config instead
0 commit comments