Mercurial > public > ostc4
changeset 1037:2af07aa38531 GasConsumption
Merge with external development branches:
Some features have been prepared for integration: Profiles, DMA UART on Firmware part, Bluetooth discovery and messges logging for development phase. All these new function are deactivated by compile switch and may be activated using the configuration.h for testing purpose.
| author | Ideenmodellierer |
|---|---|
| date | Mon, 15 Sep 2025 21:12:44 +0200 |
| parents | e938901f6386 (current diff) 5865f0aeb438 (diff) |
| children | 677d293c669f |
| files | Common/Inc/configuration.h Discovery/Inc/tStructure.h Discovery/Src/base.c Discovery/Src/tMenu.c Discovery/Src/tMenuEdit.c Discovery/Src/tMenuEditSystem.c Discovery/Src/tMenuSystem.c FontPack/base_upperRegion.c |
| diffstat | 27 files changed, 1493 insertions(+), 61 deletions(-) [+] |
line wrap: on
line diff
--- a/Common/Inc/configuration.h Sun Sep 07 20:44:35 2025 +0200 +++ b/Common/Inc/configuration.h Mon Sep 15 21:12:44 2025 +0200 @@ -96,8 +96,20 @@ /* Enable to have a faster transfer speed between bluetooth module and CPU */ #define ENABLE_FAST_COMM +/* Enable to have support of Polar HC10 heartbeat sensor active */ +/* #define ENABLE_PULSE_SENSOR_BT */ + /* Enable RTE sleep mode debugging */ /* #define ENABLE_SLEEP_DEBUG */ +/* Enable to receive data from the radio connection usart */ +/* #define ENABLE_USART_RADIO */ + +/* Enable to show messages which are den during runtime in a popup window */ +/* #define ENABLE_LOGGER_WINDOW */ + +/* Enable to have the possibility to switch between four individual sets of settings */ +/* #define ENABLE_SETTING_PROFILES */ + #endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Discovery/Inc/cv_heartbeat.h Mon Sep 15 21:12:44 2025 +0200 @@ -0,0 +1,143 @@ +/////////////////////////////////////////////////////////////////////////////// +/// -*- coding: UTF-8 -*- +/// +/// \file Discovery/Inc/cv_heartbeat.h +/// \brief Function definitions for connecting to a Polar HC10 heartbeat sensor +/// \date 3 July 2025 + +/////////////////////////////////////////////////////////////////////////////// +/// \par Copyright (c) 2014-2015 Heinrichs Weikamp gmbh +/// +/// This program is free software: you can redistribute it and/or modify +/// it under the terms of the GNU General Public License as published by +/// the Free Software Foundation, either version 3 of the License, or +/// (at your option) any later version. +/// +/// This program is distributed in the hope that it will be useful, +/// but WITHOUT ANY WARRANTY; without even the implied warranty of +/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +/// GNU General Public License for more details. +/// +/// You should have received a copy of the GNU General Public License +/// along with this program. If not, see <http://www.gnu.org/licenses/>. +////////////////////////////////////////////////////////////////////////////// + +#ifndef INC_CV_HEARTBEAT_H_ +#define INC_CV_HEARTBEAT_H_ + +#include <stdint.h> + + +#define BLUEMOD_ADDR_SIZE (20u) /* length of address respond */ +#define BLUEMOD_RSSI_SIZE (5u) +#define BLUEMOD_NAME_SIZE (40u) + +void openEdit_Heartbeat(void); + +typedef enum +{ + NO_INDICATOR = 0, + DEVICE_INDICATOR, + CONNECTION_INDICATOR, + SERVICE_INDICATOR, + CHARACTERISTIC_INDICATOR, + DESCRIPTOR_INDICATOR, + PULSE_INDICATOR, + OK_INDICATOR, /* module control */ + ERROR_INDICATOR /* module control */ +} indicatior_t; + +typedef enum +{ + BT_READ_NOTHING = 0, + BT_READ_DEVICE_ADDR, + BT_READ_DEVICE_RSSI, + BT_READ_DEVICE_NAME, + BT_READ_CON_DETAILS, + BT_READ_SERV_HANDLE, + BT_READ_SERV_START, + BT_READ_SERV_END, + BT_READ_SERV_UUID, + BT_READ_CHAR_CONHANDLE, + BT_READ_CHAR_ATTRIBUTE, + BT_READ_CHAR_PROPERTY, + BT_READ_CHAR_VALUEHANDLE, + BT_READ_CHAR_UUID, + BT_READ_DESC_CONHANDLE, + BT_READ_DESC_CHARHANDLE, + BT_READ_DESC_DESCHANDLE, + BT_READ_DESC_UUID, + BT_READ_PULSE_CONHANDLE, + BT_READ_PULSE_VALUEHANDLE, + BT_READ_PULSE_DATA, +} readDataType_t; + +typedef enum + { + SENSOR_HB_OFFLINE = 0, /* Default Status no data available */ + SENSOR_HB_ENABLE_BLE, + SENSOR_HB_CHECK_CONFIG, + SENSOR_HB_DISCOVER, + SENSOR_HB_CONNECT, + SENSOR_HB_DISCONNECT, + SENSOR_HB_SERVICES, + SENSOR_HB_CHARACTERISTIC, + SENSOR_HB_DESCRIPTOR, + SENSOR_HB_SUBSCRIBE, + SENSOR_HB_RESTART, + SENSOR_HB_DETECTION_INDICATOR, /* searching for indicators to identify data items */ + SENSOR_HB_DETECTION_RSSI, + SENSOR_HB_DETECTION_NAME, + SENSOR_HB_DETECTION_MAN, + SENSOR_HB_DETECTION_UUID, + SENSOR_HB_FOUND, /* A device providing the requested service was found */ + SENSOR_HB_CONNECTED, /* Connection to heartbeat sensor established */ + SENSOR_HB_OFFLINEMODE, /* Oflline measurement started */ + } sensorHeartbeat_State_t; + +typedef struct +{ + uint8_t address[BLUEMOD_ADDR_SIZE]; + uint8_t rssi[BLUEMOD_RSSI_SIZE]; + uint8_t name[BLUEMOD_NAME_SIZE]; +} btDdeviceData_t; + + +typedef struct +{ + uint8_t handle; + uint8_t start[6]; + uint8_t end[6]; + uint8_t uuid[50]; +} btDeviceService_t; + +typedef struct +{ + uint8_t conHandle; + uint8_t attrHandle[10]; + uint8_t properties[10]; + uint8_t valueHandle[10]; + uint8_t uuid[50]; +} btDeviceCharacteristic_t; + +typedef struct +{ + uint8_t conHandle; + uint8_t charHandle[10]; + uint8_t descHandle[10]; + uint8_t uuid[50]; +} btDeviceDescriptor_t; + +typedef struct { + uint16_t heart_rate; + uint16_t energy_expended; + uint16_t rr_intervals[10]; + uint8_t rr_count; +} HRMeasurement_t; + +sensorHeartbeat_State_t cv_heartbeat_getState(); +void refresh_Heartbeat(void); +void cv_heartbeat_Control(void); +uint8_t cv_heartbeat_HandleData(); + +#endif /* INC_CV_HEARTBEAT_H_ */
--- a/Discovery/Inc/demo.h Sun Sep 07 20:44:35 2025 +0200 +++ b/Discovery/Inc/demo.h Mon Sep 15 21:12:44 2025 +0200 @@ -35,4 +35,6 @@ void demoConfigureSettings(void); void demoSendCommand(uint8_t action); +void demo_HandleData(void); + #endif // DEMO_H
--- a/Discovery/Inc/ostc.h Sun Sep 07 20:44:35 2025 +0200 +++ b/Discovery/Inc/ostc.h Mon Sep 15 21:12:44 2025 +0200 @@ -60,6 +60,10 @@ #define DISPLAY_VERSION_LCD (0u) #define DISPLAY_VERSION_NEW (1u) +#define CHUNK_SIZE (160u) /* the DMA will handle chunk size transfers */ +#define CHUNKS_PER_BUFFER (3u) + + /* Exported variables --------------------------------------------------------*/ extern SPI_HandleTypeDef hspiDisplay; @@ -82,6 +86,7 @@ void MX_SPI_Init(void); void MX_GPIO_Init(void); void MX_UART_Init(void); +void MX_UART_BT_Init_DMA(); uint8_t MX_UART_ButtonAdjust(uint8_t *array); void MX_SmallCPU_Reset_To_Boot(void); @@ -104,5 +109,15 @@ void SetDisplayVersion(uint8_t version); uint8_t isNewDisplay(void); +uint8_t UART_getChar(); + +#ifdef ENABLE_PULSE_SENSOR_BT +void UART_StartDMARx(); +#endif +#ifdef ENABLE_USART_RADIO +void MX_UART_RADIO_Init_DMA(); +void UART_StartDMARxRadio(); +#endif + #endif // OSTC_H
--- a/Discovery/Inc/ostc_hw2.h Sun Sep 07 20:44:35 2025 +0200 +++ b/Discovery/Inc/ostc_hw2.h Mon Sep 15 21:12:44 2025 +0200 @@ -167,6 +167,22 @@ #define USART_IR_HUD_IRQn USART2_IRQn // to it directly#define USART_IR_HUD_IRQHandler USART2_IRQHandler +#define USART_RADIO USART3 +#define USART_RADIO_CLK_ENABLE() __USART3_CLK_ENABLE(); +#define USART_RADIO_FORCE_RESET() __USART3_FORCE_RESET() +#define USART_RADIO_RELEASE_RESET() __USART3_RELEASE_RESET() +//#define USART_IR_HUD_TX_AF GPIO_AF7_USART3 +//#define USART_IR_HUD_TX_PIN GPIO_PIN_5 +//#define USART_IR_HUD_TX_GPIO_PORT GPIOD +//#define USART_IR_HUD_TX_GPIO_CLK_ENABLE() __GPIOD_CLK_ENABLE() + +#define USART_RADIO_RX_AF GPIO_AF7_USART3 +#define USART_RADIO_RX_PIN GPIO_PIN_11 +#define USART_RADIO_RX_GPIO_PORT GPIOB +#define USART_RADIO_RX_GPIO_CLK_ENABLE() __GPIOB_CLK_ENABLE() +#define USART_RADIO_IRQn USART3_IRQn + + #define TIMx TIM4 #define TIMx_CLK_ENABLE __TIM4_CLK_ENABLE #define TIMx_IRQn TIM4_IRQn
--- a/Discovery/Inc/tHome.h Sun Sep 07 20:44:35 2025 +0200 +++ b/Discovery/Inc/tHome.h Mon Sep 15 21:12:44 2025 +0200 @@ -81,7 +81,10 @@ CVIEW_CcrSummary, CVIEW_Timer, CVIEW_Position, - CVIEW_END /* The ID is used in shift operation => 31 is the max number of supported views */ +#ifdef ENABLE_LOGGER_WINDOW + CVIEW_Logger = 25, /* keep development views at the end of the list to avoid id problems in official releases */ +#endif + CVIEW_END = 32 /* The ID is used in shift operation => 31 is the max number of supported views */ }; enum CUSTOMVIEWS_BF
--- a/Discovery/Inc/tInfo.h Sun Sep 07 20:44:35 2025 +0200 +++ b/Discovery/Inc/tInfo.h Mon Sep 15 21:12:44 2025 +0200 @@ -69,5 +69,6 @@ void tInfo_set_on_off(uint32_t editID, uint8_t int1); void exitInfo(void); void exitInfoToBack(void); +void exitInfoSilent(void); #endif /* TINFO_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Discovery/Inc/tInfoLogger.h Mon Sep 15 21:12:44 2025 +0200 @@ -0,0 +1,47 @@ +/////////////////////////////////////////////////////////////////////////////// +/// -*- coding: UTF-8 -*- +/// +/// \file Discovery/Inc/tInfoSensor.h +/// \brief Infopage content for visualisation of UART protocol flow +/// \author heinrichs weikamp gmbh +/// \date 17-07-2025 +/// +/// $Id$ +/////////////////////////////////////////////////////////////////////////////// +/// \par Copyright (c) 2014-2025 Heinrichs Weikamp gmbh +/// +/// This program is free software: you can redistribute it and/or modify +/// it under the terms of the GNU General Public License as published by +/// the Free Software Foundation, either version 3 of the License, or +/// (at your option) any later version. +/// +/// This program is distributed in the hope that it will be useful, +/// but WITHOUT ANY WARRANTY; without even the implied warranty of +/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +/// GNU General Public License for more details. +/// +/// You should have received a copy of the GNU General Public License +/// along with this program. If not, see <http://www.gnu.org/licenses/>. +////////////////////////////////////////////////////////////////////////////// + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef TINFO_LOGGER_H +#define TINFO_LOGGER_H + +#define LINE_HEADER_BYTES (3u) +#define MAX_CHAR_PER_LINE (60u) +#define MAX_LOGGER_LINES (13u) + +#define LOG_TX_LINE (0u) +#define LOG_RX_LINE (1u) + +#include "gfx_engine.h" + +/* Exported functions --------------------------------------------------------*/ +void openInfo_Logger(); +void refreshInfo_Logger(GFX_DrawCfgScreen s); +void sendActionToInfoLogger(uint8_t sendAction); +void InfoLogger_writeLine(uint8_t* pLine,uint8_t lineLength,uint8_t direction); +uint8_t InfoLogger_isUpdated(); + +#endif /* TINFO_LOGGER_H */
--- a/Discovery/Inc/tStructure.h Sun Sep 07 20:44:35 2025 +0200 +++ b/Discovery/Inc/tStructure.h Mon Sep 15 21:12:44 2025 +0200 @@ -66,6 +66,7 @@ #define InfoPageCompass 6 #define InfoPageSensor 8 #define InfoPagePreDive 9 +#define InfoPageLogger 10 #define StI _MB(0,1,0,0,0) #define StILOGLIST _MB(0,2,0,0,0) @@ -76,6 +77,7 @@ #define StIDEBUG _MB(0,7,0,0,0) #define StISENINFO _MB(0,8,0,0,0) #define StIPREDIVE _MB(0,9,0,0,0) +#define StILOGGER _MB(0,10,0,0,0) #define StI_GoToLogbook _MB(0,1,1,0,0) #define StI_GoToPlanner _MB(0,1,2,0,0) @@ -313,6 +315,7 @@ #define StMSYS1_GNSSDT _MB(2,8,1,5,0) #define StMSYS1_ZONE _MB(2,8,1,6,0) +#ifdef ENABLE_SETTING_PROFILES #define StMSYS_Profile _MB(2,8,2,0,0) #define StMSYS_ProfileA _MB(2,8,2,1,0) #define StMSYS_ProfileB _MB(2,8,2,2,0) @@ -331,7 +334,7 @@ #define StMSYS3_Debug _MB(2,8,4,3,0) #endif - #define StMSYS4_Info _MB(2,8,5,1,0) +#define StMSYS4_Info _MB(2,8,5,1,0) #define StMSYS5_Exit _MB(2,8,6,1,0) #define StMSYS5_LogbookOffset _MB(2,8,6,7,0) @@ -350,6 +353,39 @@ #define StMSYS5_AdjustSurfPres _MB(2,8,6,14,0) #define StMSYS5_FlashBoot _MB(2,8,6,15,0) +#else + +#define StMSYS2_English _MB(2,8,2,1,0) +#define StMSYS2_German _MB(2,8,2,2,0) +#define StMSYS2_French _MB(2,8,2,3,0) +#define StMSYS2_Italian _MB(2,8,2,4,0) +#define StMSYS2_Espanol _MB(2,8,2,5,0) + +#define StMSYS3_Units _MB(2,8,3,1,0) +#define StMSYS3_Colors _MB(2,8,3,2,0) +#ifdef HAVE_DEBUG_VIEW +#define StMSYS3_Debug _MB(2,8,3,3,0) +#endif + +#define StMSYS4_Info _MB(2,8,4,1,0) + +#define StMSYS5_Exit _MB(2,8,5,1,0) +#define StMSYS5_LogbookOffset _MB(2,8,5,7,0) +#define StMSYS5_ResetAll _MB(2,8,5,2,0) +#define StMSYS5_ResetDeco _MB(2,8,5,3,0) +#define StMSYS5_Reboot _MB(2,8,5,4,0) +#define StMSYS5_Maintenance _MB(2,8,5,5,0) +#define StMSYS5_ResetLogbook _MB(2,8,5,6,0) +#define StMSYS5_SetBattCharge _MB(2,8,5,7,0) +#define StMSYS5_RebootRTE _MB(2,8,5,8,0) +#define StMSYS5_RebootMainCPU _MB(2,8,5,9,0) +#define StMSYS5_ScreenTest _MB(2,8,5,10,0) +#define StMSYS5_SetFactoryBC _MB(2,8,5,11,0) +#define StMSYS5_ResetBluetooth _MB(2,8,5,12,0) +#define StMSYS5_SetSampleIndx _MB(2,8,5,13,0) +#define StMSYS5_AdjustSurfPres _MB(2,8,5,14,0) +#define StMSYS5_FlashBoot _MB(2,8,5,15,0) +#endif #define StMSYS_Custom0 _MB(2,8,1,0,0) @@ -406,6 +442,8 @@ #define StMOption_Timer _MB(2,10,2,0,0) #define StMOption_Timer_Value _MB(2,10,2,1,0) +#define StMOption_Heartbeat _MB(2,10,3,0,0) + /* PAGE 11 */ #define StMPLAN _MB(2,11,0,0,0)
--- a/Discovery/Inc/text_multilanguage.h Sun Sep 07 20:44:35 2025 +0200 +++ b/Discovery/Inc/text_multilanguage.h Mon Sep 15 21:12:44 2025 +0200 @@ -395,6 +395,8 @@ TXT2BYTE_TIMEZONE, TXT2BYTE_BUZZER, + TXT2BYTE_Pulse, + TXT2BYTE_Logger, TXT2BYTE_END, };
--- a/Discovery/Src/base.c Sun Sep 07 20:44:35 2025 +0200 +++ b/Discovery/Src/base.c Mon Sep 15 21:12:44 2025 +0200 @@ -237,12 +237,17 @@ #include "t7.h" #include "t3.h" #include "tMenuEditSetpoint.h" +#include "cv_heartbeat.h" +#include "tInfoLogger.h" #ifdef DEMOMODE #include "demo.h" static void TIM_DEMO_init(void); #endif +#ifdef ENABLE_USART_RADIO +#include "demo.h" +#endif //#include "lodepng.h" //#include <stdlib.h> // for malloc and free @@ -501,6 +506,7 @@ resetToFirmwareUpdate(); tCCR_control(); + if( tComm_control() )// will stop while loop if tComm Mode started until exit from UART { createDiveSettings(); @@ -526,12 +532,22 @@ { TriggerButtonAction(); } +#ifdef ENABLE_PULSE_SENSOR_BT + cv_heartbeat_HandleData(); +#endif + +#ifdef ENABLE_USART_RADIO + demo_HandleData(); +#endif if(DoHousekeeping) { DoHousekeeping = housekeepingFrame(); } if(DoDisplayRefresh) /* set every 100ms by timer interrupt */ { +#ifdef ENABLE_PULSE_SENSOR_BT + cv_heartbeat_Control(); +#endif DoDisplayRefresh = 0; updateSetpointStateUsed(); @@ -727,6 +743,15 @@ { SStateList status; get_globalStateList(&status); + +#ifdef ENABLE_LOGGER_WINDOW + if((status.base != 0) && (get_globalState() != StILOGGER) && (InfoLogger_isUpdated())) + { + openInfo_Logger(); + get_globalStateList(&status); + } +#endif + switch(status.base) { case BaseHome: @@ -919,6 +944,8 @@ break; case InfoPagePreDive: sendActionToInfoPreDive(action); break; + case InfoPageLogger: exitInfo(); + break; default: sendActionToInfo(action); break; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Discovery/Src/cv_heartbeat.c Mon Sep 15 21:12:44 2025 +0200 @@ -0,0 +1,668 @@ +/////////////////////////////////////////////////////////////////////////////// +/// -*- coding: UTF-8 -*- +/// +/// \file Discovery/Src/cv_heartbeat.c +/// \brief providing functionality to connect OSTC to a Polar HC10 heartbeat sensor +/// \author heinrichs weikamp gmbh +/// \date 03-July-2025 +/// +/// $Id$ +/////////////////////////////////////////////////////////////////////////////// +/// \par Copyright (c) 2014-2025 Heinrichs Weikamp gmbh +/// +/// This program is free software: you can redistribute it and/or modify +/// it under the terms of the GNU General Public License as published by +/// the Free Software Foundation, either version 3 of the License, or +/// (at your option) any later version. +/// +/// This program is distributed in the hope that it will be useful, +/// but WITHOUT ANY WARRANTY; without even the implied warranty of +/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +/// GNU General Public License for more details. +/// +/// You should have received a copy of the GNU General Public License +/// along with this program. If not, see <http://www.gnu.org/licenses/>. +////////////////////////////////////////////////////////////////////////////// + +#include "configuration.h" + +#ifdef ENABLE_PULSE_SENSOR_BT +#include "cv_heartbeat.h" +#include "tMenuEdit.h" + +#include "gfx_fonts.h" +#include "tHome.h" +#include "ostc.h" +#include "tComm.h" +#include "tInfoLogger.h" +#include "stdlib.h" + +static sensorHeartbeat_State_t heartbeatState = SENSOR_HB_OFFLINE; + +static uint8_t OnAction_Heartbeat(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); +static uint32_t startDetection_ms; + +#define MAX_BT_DEVICE 10 /* max number of device which may be handled */ +static btDdeviceData_t btDeviceList[MAX_BT_DEVICE]; +static btDeviceService_t curDeviceService[10]; +static btDeviceCharacteristic_t curDevCharacteristic[10]; +static btDeviceDescriptor_t curDevDescriptor; + + +static uint8_t curCharacteristicIndex = 0; +static uint8_t curServiceIndex = 0; +static uint8_t curBtIndex = 0; +static uint8_t connHandle = ' '; +static uint8_t evaluateDevIndex = 0xFF; +static uint8_t evaluateSrvIndex = 0xFF; +static uint8_t evaluateCharIndex = 0xFF; + +static void parsePulseMeasurement(uint8_t* pData, uint8_t length) +{ + uint8_t rawData[10]; + + char* enptr; + uint8_t flags = 0; + uint16_t rr = 0; + uint8_t index = 0; + uint8_t* pRaw = (uint8_t*)&rawData; + char tmpStr[3]; + + tmpStr[2] = 0; + + HRMeasurement_t pulseData; + + for(index = 0; index < length; index +=2) + { + memcpy(tmpStr,&pData[index],2); + rawData[index / 2] = strtol(tmpStr, &enptr,16); + } + flags = pRaw[0]; + index = 1; + /* 0: Heart Rate Format bit (0 = UINT8, 1 = UINT16) */ + if (flags & 0x01) + { + pulseData.heart_rate = pRaw[index] | (pRaw[index + 1] << 8); + index += 2; + } else + { + pulseData.heart_rate = pRaw[index]; + index += 1; + } + + /* 3: Energy Expended Status */ + if (flags & 0x08) + { + pulseData.energy_expended = pRaw[index] | (pRaw[index + 1] << 8); + index += 2; + } else + { + pulseData.energy_expended = 0; + } + /* 4: RR-Interval bit */ + pulseData.rr_count = 0; + if (flags & 0x10) + { + while (index + 1 < 4 && pulseData.rr_count < 10) + { + rr = pRaw[index] | (pRaw[index + 1] << 8); + pulseData.rr_intervals[pulseData.rr_count++] = rr; + index += 2; + } + } +// snprintf(text,40,"Pulse: %d",pulseData.heart_rate); +// InfoLogger_writeLine((uint8_t*)text,strlen(text),0); +} + +static indicatior_t checkIndicators(uint8_t* pdata) +{ + indicatior_t ret = NO_INDICATOR; + + if(strcmp((char*)pdata,"+UBTD:") == 0) + { + ret = DEVICE_INDICATOR; + } + else if(strcmp((char*)pdata,"+UUBTACLC:") == 0) + { + ret = CONNECTION_INDICATOR; + } + else if(strcmp((char*)pdata,"+UBTGDP:") == 0) + { + ret = SERVICE_INDICATOR; + } + else if(strcmp((char*)pdata,"+UBTGDCS:") == 0) + { + ret = CHARACTERISTIC_INDICATOR; + } + else if(strcmp((char*)pdata,"+UBTGDCD:") == 0) + { + ret = DESCRIPTOR_INDICATOR; + } + else if(strcmp((char*)pdata,"+UUBTGN:") == 0) + { + ret = PULSE_INDICATOR; + } + return ret; +} + +static void handleOK() +{ + uint8_t index = 0; + + switch(heartbeatState) + { + case SENSOR_HB_ENABLE_BLE: heartbeatState = SENSOR_HB_CHECK_CONFIG; + break; + case SENSOR_HB_CHECK_CONFIG: heartbeatState = SENSOR_HB_DISCOVER; + break; + case SENSOR_HB_RESTART: heartbeatState = SENSOR_HB_OFFLINE; + break; + case SENSOR_HB_DISCOVER: if(curBtIndex > 0) + { + heartbeatState = SENSOR_HB_CONNECT; + evaluateDevIndex = 0; + } + else + { + heartbeatState = SENSOR_HB_OFFLINE; + } + + break; + case SENSOR_HB_SERVICES: evaluateSrvIndex = 0xFF; + if(curServiceIndex != 0) + { + for(index = 0; index <= curServiceIndex; index++) + { + if(strcmp((char*)curDeviceService[index].uuid,"180D") == 0) + { + heartbeatState = SENSOR_HB_CHARACTERISTIC; + evaluateSrvIndex = index; + curCharacteristicIndex = 0; + break; + } + } + } + if(evaluateSrvIndex == 0xFF) /* device does not provide heartbeat data => disconnect */ + { + heartbeatState = SENSOR_HB_DISCONNECT; + } + break; + case SENSOR_HB_CHARACTERISTIC: evaluateCharIndex = 0xFF; + if(curCharacteristicIndex != 0) + { + for(index = 0; index < curCharacteristicIndex; index++) + { + if(strcmp((char*)curDevCharacteristic[index].uuid,"2A37") == 0) + { + heartbeatState = SENSOR_HB_DESCRIPTOR; + evaluateCharIndex = index; + break; + } + } + } + if(evaluateCharIndex == 0xFF) /* device does not provide heartbeat data => disconnect */ + { + heartbeatState = SENSOR_HB_DISCONNECT; + } + break; + case SENSOR_HB_DESCRIPTOR: if(strcmp((char*)curDevDescriptor.uuid,"2902") == 0) + { + heartbeatState = SENSOR_HB_SUBSCRIBE; + } + else + { + heartbeatState = SENSOR_HB_DISCONNECT; + } + break; + + case SENSOR_HB_SUBSCRIBE: heartbeatState = SENSOR_HB_CONNECTED; + break; + case SENSOR_HB_DISCONNECT: evaluateDevIndex++; + connHandle= ' '; + if(evaluateDevIndex < curBtIndex) /* more devices to be evaluated? */ + { + heartbeatState = SENSOR_HB_CONNECT; + } + else + { + heartbeatState = SENSOR_HB_OFFLINE; + } + break; + case SENSOR_HB_CONNECT: /* handled in data rx section */ + default: + break; + } +} + +static void handleERROR() +{ + switch(heartbeatState) + { + case SENSOR_HB_DISCONNECT: evaluateDevIndex++; + connHandle= ' '; + if(evaluateDevIndex < curBtIndex) /* more devices to be evaluated? */ + { + heartbeatState = SENSOR_HB_CONNECT; + } + else + { + heartbeatState = SENSOR_HB_OFFLINE; + } + break; + default: + break; + } +} + +uint8_t cv_heartbeat_HandleData() +{ + static uint8_t firstDevice = 1; + static uint8_t curLine[MAX_CHAR_PER_LINE]; /* holds complete line and is used for logging */ + static uint8_t curLineIndex = 0; + static uint8_t parameter[40]; /* content of the parameter in read state */ + static uint8_t writeIndex = 0; + static uint8_t complete = 0; + + static readDataType_t readType = BT_READ_NOTHING; + + uint8_t data = 0; + data = UART_getChar(); + + while((data != 0) && (complete == 0)) + { + if(curLineIndex == MAX_CHAR_PER_LINE - 1) /* avoid overflow */ + { + InfoLogger_writeLine(curLine,curLineIndex,0); + memset(curLine,0,sizeof(curLine)); + curLineIndex = 0; + } + if((data == '\r') || (data == '\n')) + { + if(curLineIndex > 0) + { + InfoLogger_writeLine(curLine,curLineIndex,0); + if(strcmp((char*)curLine,"OK") == 0) + { + handleOK(); + } + else + { + if(strcmp((char*)curLine,"ERROR") == 0) + { + handleERROR(); + } + } + } + switch(readType) + { + case BT_READ_DEVICE_NAME: if(writeIndex < BLUEMOD_NAME_SIZE) + { + memcpy (btDeviceList[curBtIndex].name, parameter, writeIndex); + } + break; + case BT_READ_SERV_UUID: if((writeIndex < 50) && (curServiceIndex < 10)) + { + memcpy(curDeviceService[curServiceIndex].uuid, parameter, writeIndex); + } + curServiceIndex++; + break; + case BT_READ_CHAR_UUID: if(writeIndex < 50) + { + memcpy(curDevCharacteristic[curCharacteristicIndex].uuid, parameter, writeIndex); + curCharacteristicIndex++; + } + break; + case BT_READ_DESC_UUID: if(writeIndex < 50) + { + memcpy(curDevDescriptor.uuid, parameter, writeIndex); + } + break; + case BT_READ_PULSE_DATA: if(writeIndex < 50) + { + parsePulseMeasurement(parameter, writeIndex); + } + break; + default: + break; + } + curLineIndex = 0; + writeIndex = 0; + memset(curLine,0,sizeof(curLine)); + readType = BT_READ_NOTHING; + } + else + { + if(curLineIndex < MAX_CHAR_PER_LINE) curLine[curLineIndex++] = data; + + if(data == ':') + { + switch(checkIndicators(curLine)) + { + case DEVICE_INDICATOR: readType = BT_READ_DEVICE_ADDR; + break; + case CONNECTION_INDICATOR: readType = BT_READ_CON_DETAILS; + break; + case SERVICE_INDICATOR: readType = BT_READ_SERV_HANDLE; + break; + case CHARACTERISTIC_INDICATOR: readType = BT_READ_CHAR_CONHANDLE; + break; + case DESCRIPTOR_INDICATOR: readType = BT_READ_DESC_CONHANDLE; + break; + case PULSE_INDICATOR: readType = BT_READ_PULSE_CONHANDLE; + break; + default: + break; + } + writeIndex = 0; + memset(parameter,0,sizeof(parameter)); + } + else + { + if(data == ',') /* parameter end */ + { + switch(readType) + { + case BT_READ_DEVICE_ADDR: if(writeIndex < BLUEMOD_ADDR_SIZE-1) + { + if(firstDevice) + { + firstDevice = 0; + } + else + { + curBtIndex++; + } + parameter[writeIndex-1] = 0; /*remove 'p' from address */ + strcpy((char*)btDeviceList[curBtIndex].address, (char*)parameter); + } + readType = BT_READ_DEVICE_RSSI; + break; + case BT_READ_DEVICE_RSSI: if(writeIndex < BLUEMOD_RSSI_SIZE-1) + { + strcpy((char*)btDeviceList[curBtIndex].rssi, (char*)parameter); + } + readType = BT_READ_DEVICE_NAME; + break; + case BT_READ_DEVICE_NAME: if(writeIndex < BLUEMOD_NAME_SIZE-1) + { + memcpy(btDeviceList[curBtIndex].name, parameter, writeIndex); + } + readType = BT_READ_NOTHING; + break; + case BT_READ_CON_DETAILS: connHandle = parameter[0]; + heartbeatState = SENSOR_HB_SERVICES; + readType = BT_READ_NOTHING; + curServiceIndex = 0; + break; + case BT_READ_SERV_HANDLE: curDeviceService[curServiceIndex].handle = parameter[0]; + readType = BT_READ_SERV_START; + break; + case BT_READ_SERV_START: if(writeIndex < 6) + { + memcpy(curDeviceService[curServiceIndex].start, parameter, writeIndex); + } + readType = BT_READ_SERV_END; + break; + case BT_READ_SERV_END: if(writeIndex < 6) + { + memcpy(curDeviceService[curServiceIndex].end, parameter, writeIndex); + } + readType = BT_READ_SERV_UUID; + break; + case BT_READ_CHAR_CONHANDLE: curDevCharacteristic[curCharacteristicIndex].conHandle = parameter[0]; + readType = BT_READ_CHAR_ATTRIBUTE; + break; + case BT_READ_CHAR_ATTRIBUTE: if(writeIndex < 10) + { + memcpy(curDevCharacteristic[curCharacteristicIndex].attrHandle, parameter, writeIndex); + } + readType = BT_READ_CHAR_PROPERTY; + break; + case BT_READ_CHAR_PROPERTY: if(writeIndex < 10) + { + memcpy(curDevCharacteristic[curCharacteristicIndex].properties, parameter, writeIndex); + } + readType = BT_READ_CHAR_VALUEHANDLE; + break; + case BT_READ_CHAR_VALUEHANDLE: if(writeIndex < 10) + { + memcpy(curDevCharacteristic[curCharacteristicIndex].valueHandle, parameter, writeIndex); + } + readType = BT_READ_CHAR_UUID; + break; + case BT_READ_DESC_CONHANDLE: curDevDescriptor.conHandle = parameter[0]; + readType = BT_READ_DESC_CHARHANDLE; + break; + case BT_READ_DESC_CHARHANDLE: if(writeIndex < 10) + { + memcpy(curDevDescriptor.charHandle, parameter, writeIndex); + } + readType = BT_READ_DESC_DESCHANDLE; + break; + case BT_READ_DESC_DESCHANDLE: if(writeIndex < 10) + { + memcpy(curDevDescriptor.descHandle, parameter, writeIndex); + } + readType = BT_READ_DESC_UUID; + break; + case BT_READ_PULSE_CONHANDLE: curDevDescriptor.conHandle = parameter[0]; + readType = BT_READ_PULSE_VALUEHANDLE; + break; + case BT_READ_PULSE_VALUEHANDLE: if(writeIndex < 10) + { + // if(strcmp((char*)curDevCharacteristic[evaluateCharIndex].valueHandle,(char*) parameter) == 0) + { + readType = BT_READ_PULSE_DATA; + } +#if 0 + else + { + readType = BT_READ_NOTHING; + } +#endif + } + break; + default: readType = BT_READ_NOTHING; + break; + } + writeIndex = 0; + memset(parameter,0 , sizeof(parameter)); + } + else + { + if(readType != BT_READ_NOTHING) + { + parameter[writeIndex++] = data; + } + } + } + } + data = UART_getChar(); + } + return complete; +} + +sensorHeartbeat_State_t cv_heartbeat_getState() +{ + return heartbeatState; +} + +void openEdit_Heartbeat(void) +{ + char text[32]; + snprintf(text, 32, "\001%c%c", TXT_2BYTE, TXT2BYTE_Pulse); + write_topline(text); + + set_globalState(StMOption_Heartbeat); + resetMenuEdit(CLUT_MenuPageCvOption); + + snprintf(text, 32, "%c%c", TXT_2BYTE, TXT2BYTE_SensorDetect); + write_field_button(StMOption_Heartbeat, 30, 299, ME_Y_LINE1, &FontT48, text); + + write_buttonTextline(TXT2BYTE_ButtonMinus, TXT2BYTE_ButtonEnter, TXT2BYTE_ButtonPlus); + + setEvent(StMOption_Heartbeat, (uint32_t)OnAction_Heartbeat); +} + +static uint8_t OnAction_Heartbeat(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action) +{ + switch(heartbeatState) + { + case SENSOR_HB_OFFLINE: + HAL_UART_AbortReceive_IT(&UartHandle); + MX_UART_BT_Init_DMA(); + UART_StartDMARx(); + heartbeatState = SENSOR_HB_ENABLE_BLE; + startDetection_ms = HAL_GetTick(); + curBtIndex = 0; + memset(btDeviceList, 0, sizeof(btDeviceList)); + break; + + default: + break; + } + return UNSPECIFIC_RETURN; +} + +void cv_heartbeat_Control(void) +{ + static uint8_t action = 0; + static uint8_t retry = 0; + static uint8_t lastState = 0; + char cmd[50]; + + cmd[0] = 0; + + if(action == 3) + { + action = 0; + switch(heartbeatState) + { + case SENSOR_HB_ENABLE_BLE: HAL_Delay(1000); + snprintf(cmd, sizeof(cmd), "+++" ); //"AT+UBTD=2,1,5000\r\n" + InfoLogger_writeLine((uint8_t*)cmd,3,1); + HAL_UART_Transmit(&UartHandle, (uint8_t*)cmd, 3, 5000); + HAL_Delay(1000); + cmd[0] = 0; + break; + case SENSOR_HB_CHECK_CONFIG: snprintf(cmd, sizeof(cmd), "AT+UBTCFG=2\r\n" ); // AT+UBTLE? + +#if 0 + if(settingsGetPointer()->dive_mode == DIVEMODE_OC) + { + snprintf(cmd, sizeof(cmd), "AT+UBTLE=2\r\n" ); //+UBTLE=1 //"AT+UBTD=2,1,5000\r\n" + } + else + { + snprintf(cmd, sizeof(cmd), "AT+UBTLE=3\r\n" ); //+UBTLE=1 //"AT+UBTD=2,1,5000\r\n" + } +#endif + break; + case SENSOR_HB_DISCOVER: if(lastState != SENSOR_HB_DISCOVER) + { + snprintf(cmd, sizeof(cmd), "AT+UBTD=2,1\r\n" ); //+UBTLE=1 //"AT+UBTD=2,1,5000\r\n" + curBtIndex = 0; + } + + //snprintf(cmd, sizeof(cmd), "AT&W\r\n" ); // AT+UBTD=2,1\r\n "AT+UBTD=2,1,5000\r\n" + break; +#if 0 + case SENSOR_HB_RESTART: snprintf(cmd, sizeof(cmd), "AT+UBTD=2,1\r\n" ); //+UBTLE=1 //"AT+UBTD=2,1,5000\r\n" + + // snprintf(cmd, sizeof(cmd), "AT+CPWROFF\r\n" ); // AT+UBTD=2,1\r\n "AT+UBTD=2,1,5000\r\n" + break; +#endif + case SENSOR_HB_CONNECT: if(evaluateDevIndex < curBtIndex) + { + snprintf(cmd, sizeof(cmd), "AT+UBTACLC=%s\r\n",btDeviceList[evaluateDevIndex].address); + } + break; + case SENSOR_HB_DISCONNECT: snprintf(cmd, sizeof(cmd), "AT+UBTACLD=%c\r\n",connHandle); + break; + case SENSOR_HB_SERVICES: if((connHandle >= '0') && (connHandle <= '9') && (lastState != SENSOR_HB_SERVICES)) + { + snprintf(cmd, sizeof(cmd), "AT+UBTGDP=%c\r\n",connHandle); + memset(curDeviceService, 0, sizeof(curDeviceService)); + } + break; + case SENSOR_HB_CHARACTERISTIC: snprintf(cmd, sizeof(cmd), "AT+UBTGDCS=%c,%s,%s\r\n",connHandle,curDeviceService[evaluateSrvIndex].start + ,curDeviceService[evaluateSrvIndex].end); + memset(curDevCharacteristic, 0, sizeof(curDevCharacteristic)); + break; + case SENSOR_HB_DESCRIPTOR: snprintf(cmd, sizeof(cmd), "AT+UBTGDCD=%c,%s,%s\r\n",connHandle,curDevCharacteristic[evaluateCharIndex].valueHandle + ,curDeviceService[evaluateSrvIndex].end); + break; + case SENSOR_HB_SUBSCRIBE: snprintf(cmd, sizeof(cmd), "AT+UBTGWC=%c,%s,1\r\n",connHandle,curDevDescriptor.descHandle); + break; + default: + break; + } + if(cmd[0] != 0) + { + { + InfoLogger_writeLine((uint8_t*)cmd,strlen(cmd),1); + HAL_UART_Transmit(&UartHandle, (uint8_t*)cmd, strlen(cmd), 5000); + retry++; + if(retry == 3) + { + heartbeatState = SENSOR_HB_OFFLINE; + } + } + } + if(lastState != heartbeatState) + { + lastState = heartbeatState; + retry = 0; + } + } + else + { + action++; + } +} +void refresh_Heartbeat(void) +{ + char text[32]; + uint8_t index = 0; + + snprintf(text, 32, "\001%c%c", TXT_2BYTE, TXT2BYTE_Pulse); + write_topline(text); + + switch(heartbeatState) + { + case SENSOR_HB_OFFLINE: + default: snprintf(text, 32, "%c%c", TXT_2BYTE, TXT2BYTE_SensorDetect); + write_label_var(30, 299, ME_Y_LINE1, &FontT48, text); + + if(curBtIndex > 0) + { + while((index < curBtIndex) && (index < 3)) + { + snprintf(text, 40, "%s", btDeviceList[index].address); + write_label_var( 30, 300, ME_Y_LINE3 + (index * ME_Y_LINE_STEP), &FontT48, text); + index++; + } + } + break; + case SENSOR_HB_ENABLE_BLE: snprintf(text, 32, "Activate BLE"); + write_label_var( 30, 300, ME_Y_LINE1, &FontT48, text); + break; + case SENSOR_HB_DISCOVER: + snprintf(text, 32, "Searching"); + write_label_var( 30, 300, ME_Y_LINE1, &FontT48, text); + + if(curBtIndex > 0) + { + while((index < curBtIndex) && (index < 4)) + { + snprintf(text, 40, "%s", btDeviceList[index].address); + write_label_var( 30, 300, ME_Y_LINE2 + (index * ME_Y_LINE_STEP), &FontT48, text); + index++; + } + } + break; + } + + write_buttonTextline(TXT2BYTE_ButtonMinus, TXT2BYTE_ButtonEnter, TXT2BYTE_ButtonPlus); +} +#endif
--- a/Discovery/Src/demo.c Sun Sep 07 20:44:35 2025 +0200 +++ b/Discovery/Src/demo.c Mon Sep 15 21:12:44 2025 +0200 @@ -28,6 +28,8 @@ #include "data_exchange_main.h" // for time_elapsed_ms() #include "settings.h" #include "ostc.h" +#include "tInfoLogger.h" +#include <string.h> #ifndef DEMOMODE @@ -425,5 +427,62 @@ #endif // DEMO +#ifdef ENABLE_USART_RADIO /* debug function to check receiption of radio data */ +void demo_HandleData(void) +{ + static uint8_t comStarted = 0; + static uint8_t text[50]; + static uint8_t index = 0; + static uint32_t startTick = 0; + static uint8_t firstData = 1; + uint8_t data = 0; + + switch(comStarted) + { + case 0: startTick = HAL_GetTick(); + comStarted++; + break; + case 1: if(time_elapsed_ms(startTick, HAL_GetTick()) > 5000) + { + MX_UART_RADIO_Init_DMA(); + UART_StartDMARxRadio(); + comStarted++; + sprintf((char*)text,"RadioStarted"); + InfoLogger_writeLine(text,strlen((char*)text),1); + } + break; + case 2: data = UART_getChar(); + if(data != 0) + { + if(firstData) + { + firstData = 0; + sprintf((char*)text,"FirstData"); + InfoLogger_writeLine(text,strlen((char*)text),1); + } + if((index == 50) || (data =='r') || (data =='n')) + { + if(index > 0) + { + InfoLogger_writeLine(text,index,0); + index = 0; + } + } + else + { + text[index++] = data; + } + } + break; + default: + break; + } + + + { + } +} +#endif + /************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/
--- a/Discovery/Src/ostc.c Sun Sep 07 20:44:35 2025 +0200 +++ b/Discovery/Src/ostc.c Mon Sep 15 21:12:44 2025 +0200 @@ -27,8 +27,10 @@ ////////////////////////////////////////////////////////////////////////////// /* Includes ------------------------------------------------------------------*/ +#include "configuration.h" #include "ostc.h" #include "stm32f4xx_hal.h" +#include "cv_heartbeat.h" #ifndef BOOTLOADER_STANDALONE #include "tCCR.h" @@ -45,6 +47,10 @@ #endif UART_HandleTypeDef UartIR_HUD_Handle; +#ifdef ENABLE_USART_RADIO +UART_HandleTypeDef UartRadio_Handle; +#endif + __IO ITStatus UartReady = RESET; __IO ITStatus UartReadyHUD = RESET; @@ -54,6 +60,19 @@ /* Private variables with external access via get_xxx() function -------------*/ static uint8_t hardwareDisplay = 0; //< either OSTC4 LCD (=0) or new Screen (=1) + +#ifdef ENABLE_PULSE_SENSOR_BT +static DMA_HandleTypeDef hdma_uart_BT_rx; +#endif + +#ifdef ENABLE_USART_RADIO +static DMA_HandleTypeDef hdma_uart_radio_rx; +#endif + +static uint16_t rxBufRead = 0; +static uint16_t rxBufWrite = 0; +static uint8_t rxBufferUart[CHUNK_SIZE * CHUNKS_PER_BUFFER]; /* The complete buffer has a X * chunk size to allow variations in buffer read time */ + /* Private function prototypes -----------------------------------------------*/ /* Exported functions --------------------------------------------------------*/ @@ -378,8 +397,122 @@ HAL_UART_Init(&UartIR_HUD_Handle); #endif + +#ifdef ENABLE_USART_RADIO + UartRadio_Handle.Instance = USART_RADIO; + UartRadio_Handle.Init.BaudRate = 9600; + UartRadio_Handle.Init.WordLength = UART_WORDLENGTH_8B; + UartRadio_Handle.Init.StopBits = UART_STOPBITS_1; + UartRadio_Handle.Init.Parity = UART_PARITY_NONE; + UartRadio_Handle.Init.HwFlowCtl = UART_HWCONTROL_NONE; + UartRadio_Handle.Init.Mode = UART_MODE_RX; + + HAL_UART_Init(&UartRadio_Handle); +#endif + } +#ifdef ENABLE_PULSE_SENSOR_BT +void MX_UART_BT_Init_DMA() +{ + + __DMA2_CLK_ENABLE(); + __HAL_RCC_DMA2_CLK_ENABLE(); + + hdma_uart_BT_rx.Instance = DMA2_Stream2; + hdma_uart_BT_rx.Init.Channel = DMA_CHANNEL_4; + hdma_uart_BT_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; + hdma_uart_BT_rx.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_uart_BT_rx.Init.MemInc = DMA_MINC_ENABLE; + hdma_uart_BT_rx.Init.PeriphDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_uart_BT_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_uart_BT_rx.Init.Mode = DMA_NORMAL; + hdma_uart_BT_rx.Init.Priority = DMA_PRIORITY_LOW; + hdma_uart_BT_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + HAL_DMA_Init(&hdma_uart_BT_rx); + + __HAL_LINKDMA(&UartHandle, hdmarx, hdma_uart_BT_rx); + + HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn); +} +#endif + +#ifdef ENABLE_USART_RADIO +void MX_UART_RADIO_Init_DMA() +{ + + __DMA2_CLK_ENABLE(); + __HAL_RCC_DMA2_CLK_ENABLE(); + + hdma_uart_radio_rx.Instance = DMA2_Stream1; + hdma_uart_radio_rx.Init.Channel = DMA_CHANNEL_4; + hdma_uart_radio_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; + hdma_uart_radio_rx.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_uart_radio_rx.Init.MemInc = DMA_MINC_ENABLE; + hdma_uart_radio_rx.Init.PeriphDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_uart_radio_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_uart_radio_rx.Init.Mode = DMA_NORMAL; + hdma_uart_radio_rx.Init.Priority = DMA_PRIORITY_LOW; + hdma_uart_radio_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + HAL_DMA_Init(&hdma_uart_radio_rx); + + __HAL_LINKDMA(&UartRadio_Handle, hdmarx, hdma_uart_radio_rx); + + HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn); +} +#endif + + +uint8_t UART_getChar() +{ + uint8_t retChar = 0; + + if((rxBufRead != rxBufWrite) && (rxBufferUart[rxBufRead] != 0)) + { + retChar = rxBufferUart[rxBufRead]; + rxBufferUart[rxBufRead++] = 0; + if(rxBufRead == CHUNK_SIZE * CHUNKS_PER_BUFFER) + { + rxBufRead = 0; + } + } + return retChar; +} +#ifdef ENABLE_PULSE_SENSOR_BT +void UART_StartDMARx() +{ + HAL_UART_Receive_DMA (&UartHandle, &rxBufferUart[rxBufWrite], CHUNK_SIZE); + rxBufWrite += CHUNK_SIZE; + if(rxBufWrite >= CHUNK_SIZE * CHUNKS_PER_BUFFER) + { + rxBufWrite = 0; + } +} +void DMA2_Stream2_IRQHandler(void) +{ + HAL_DMA_IRQHandler(&hdma_uart_BT_rx); +} +#endif + +#ifdef ENABLE_USART_RADIO +void UART_StartDMARxRadio() +{ + HAL_UART_Receive_DMA (&UartRadio_Handle, &rxBufferUart[rxBufWrite], CHUNK_SIZE); + rxBufWrite += CHUNK_SIZE; + if(rxBufWrite >= CHUNK_SIZE * CHUNKS_PER_BUFFER) + { + rxBufWrite = 0; + } +} + +void DMA2_Stream2_IRQHandler(void) +{ + HAL_DMA_IRQHandler(&hdma_uart_radio_rx); +} +#endif + void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) { if(huart == &UartHandle) @@ -390,7 +523,20 @@ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(huart == &UartHandle) - UartReady = SET; + { +#ifdef ENABLE_PULSE_SENSOR_BT + if(cv_heartbeat_getState() != SENSOR_HB_OFFLINE) + { + UART_StartDMARx(); + } + else + { + UartReady = SET; + } +#else + UartReady = SET; +#endif + } else if(huart == &UartIR_HUD_Handle) {
--- a/Discovery/Src/stm32f4xx_hal_msp_hw2.c Sun Sep 07 20:44:35 2025 +0200 +++ b/Discovery/Src/stm32f4xx_hal_msp_hw2.c Mon Sep 15 21:12:44 2025 +0200 @@ -630,18 +630,20 @@ /* USER CODE END USART3_MspInit 0 */ /* Peripheral clock enable */ - __USART3_CLK_ENABLE(); + USART_RADIO_RX_GPIO_CLK_ENABLE(); /**USART3 GPIO Configuration - PC10 ------> USART3_TX - PC11 ------> USART3_RX + PB11 ------> USART3_RX */ - GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11; + GPIO_InitStruct.Pin = USART_RADIO_RX_PIN; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_LOW; - GPIO_InitStruct.Alternate = GPIO_AF7_USART3; - HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + GPIO_InitStruct.Alternate = USART_RADIO_RX_AF; + HAL_GPIO_Init(USART_RADIO_RX_GPIO_PORT, &GPIO_InitStruct); + + HAL_NVIC_SetPriority(USART_RADIO_IRQn, 0, 1); + HAL_NVIC_EnableIRQ(USART_RADIO_IRQn); /* USER CODE BEGIN USART3_MspInit 1 */ @@ -706,7 +708,7 @@ PC10 ------> USART3_TX PC11 ------> USART3_RX */ - HAL_GPIO_DeInit(GPIOC, GPIO_PIN_10|GPIO_PIN_11); + HAL_GPIO_DeInit(USART_RADIO_RX_GPIO_PORT, USART_RADIO_RX_PIN); /* USER CODE BEGIN USART3_MspDeInit 1 */
--- a/Discovery/Src/tDebug.c Sun Sep 07 20:44:35 2025 +0200 +++ b/Discovery/Src/tDebug.c Mon Sep 15 21:12:44 2025 +0200 @@ -58,9 +58,12 @@ void exitDebugMode(void) { - MX_Bluetooth_PowerOff(); - settingsGetPointer()->debugModeOnStart = 0; - tD_debugModeActive = 0; + if(tD_debugModeActive) + { + MX_Bluetooth_PowerOff(); + settingsGetPointer()->debugModeOnStart = 0; + tD_debugModeActive = 0; + } }
--- a/Discovery/Src/tHome.c Sun Sep 07 20:44:35 2025 +0200 +++ b/Discovery/Src/tHome.c Mon Sep 15 21:12:44 2025 +0200 @@ -59,7 +59,13 @@ static uint16_t tHome_tick_count_field; static uint16_t tHome_tick_count_o2sens; -const uint8_t cv_changelist[] = {CVIEW_Compass, CVIEW_SummaryOfLeftCorner, CVIEW_Tissues, CVIEW_Profile, CVIEW_EADTime, CVIEW_Gaslist, CVIEW_noneOrDebug, CVIEW_Decolist, CVIEW_sensors,CVIEW_sensors_mV, CVIEW_Timer, CVIEW_END}; +const uint8_t cv_changelist[] = {CVIEW_Compass, CVIEW_SummaryOfLeftCorner, CVIEW_Tissues, + CVIEW_Profile, CVIEW_EADTime, CVIEW_Gaslist, CVIEW_noneOrDebug, + CVIEW_Decolist, CVIEW_sensors,CVIEW_sensors_mV, CVIEW_Timer, +#ifdef ENABLE_LOGGER_WINDOW + CVIEW_Logger, +#endif + CVIEW_END}; const uint8_t cv_changelist_BS[] = {CVIEW_T3_Decostop, CVIEW_sensors, CVIEW_Compass, CVIEW_T3_MaxDepth,CVIEW_T3_StopWatch, CVIEW_T3_TTS, CVIEW_T3_GasList, CVIEW_T3_ppO2andGas, CVIEW_noneOrDebug, CVIEW_T3_Navigation, CVIEW_T3_DepthData, CVIEW_T3_DecoTTS, #ifdef ENABLE_T3_PROFILE_VIEW
--- a/Discovery/Src/tInfo.c Sun Sep 07 20:44:35 2025 +0200 +++ b/Discovery/Src/tInfo.c Mon Sep 15 21:12:44 2025 +0200 @@ -38,6 +38,7 @@ #include "tInfoCompass.h" #include "tInfoSensor.h" #include "tInfoPreDive.h" +#include "tInfoLogger.h" #include "tMenu.h" #include "tMenuEdit.h" @@ -227,6 +228,12 @@ infoColor = CLUT_MenuPageGasCC; refreshInfo_PreDive(tIscreen); break; +#ifdef ENABLE_LOGGER_WINDOW + case StILOGGER: tIscreen.FBStartAdress = getFrame(14); + infoColor = CLUT_MenuPageCvOption; + refreshInfo_Logger(tIscreen); + break; +#endif default: break; @@ -256,6 +263,11 @@ exitMenuEdit_to_BackMenu(); } +void exitInfoSilent(void) /* no changes were done on info screen => just free buffer */ +{ + releaseFrame(14,tIscreen.FBStartAdress); + updateMenu(); +} void sendActionToInfo(uint8_t sendAction) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Discovery/Src/tInfoLogger.c Mon Sep 15 21:12:44 2025 +0200 @@ -0,0 +1,170 @@ +/////////////////////////////////////////////////////////////////////////////// +/// -*- coding: UTF-8 -*- +/// +/// \file Discovery/Src/tInfoLogger.c +/// \brief Show data which is received / send through UART interface +/// \author heinrichs weikamp gmbh +/// \date 23-Feb-2015 +/// +/// \details +/// +/// $Id$ +/////////////////////////////////////////////////////////////////////////////// +/// \par Copyright (c) 2014-2018 Heinrichs Weikamp gmbh +/// +/// This program is free software: you can redistribute it and/or modify +/// it under the terms of the GNU General Public License as published by +/// the Free Software Foundation, either version 3 of the License, or +/// (at your option) any later version. +/// +/// This program is distributed in the hope that it will be useful, +/// but WITHOUT ANY WARRANTY; without even the implied warranty of +/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +/// GNU General Public License for more details. +/// +/// You should have received a copy of the GNU General Public License +/// along with this program. If not, see <http://www.gnu.org/licenses/>. +////////////////////////////////////////////////////////////////////////////// + +/* Includes ------------------------------------------------------------------*/ + +#include "gfx_engine.h" +#include "gfx_fonts.h" +#include "tHome.h" +#include "tInfo.h" +#include "tInfoLogger.h" +#include "tMenuEdit.h" +#include "data_exchange_main.h" +#include "t7.h" + +#include <string.h> +#include <inttypes.h> + + +/* Private variables ---------------------------------------------------------*/ +static uint8_t lines[MAX_LOGGER_LINES][MAX_CHAR_PER_LINE + LINE_HEADER_BYTES]; +static uint8_t lineWriteIndex = 0; +static uint8_t lineReadIndex = 0; +static uint32_t receivedLinesCount = 0; + +static uint32_t loggerUpdateTime = 0; +static uint32_t previousGlobalState = 0; + +/* Exported functions --------------------------------------------------------*/ + + +void InfoLogger_writeLine(uint8_t* pLine,uint8_t lineLength,uint8_t direction) +{ +#ifdef ENABLE_LOGGER_WINDOW + uint8_t LogIndex = 0; + + if(!t7_customview_disabled(CVIEW_Logger)) + { + if(lineLength <= MAX_CHAR_PER_LINE) + { + memset(&lines[lineWriteIndex][0],0, (MAX_CHAR_PER_LINE + LINE_HEADER_BYTES)); + if(direction == LOG_TX_LINE) + { + lines[lineWriteIndex][LogIndex] = '\002'; /* align right */ + LogIndex++; + } + memcpy(&lines[lineWriteIndex][LogIndex],pLine,lineLength); + lineWriteIndex++; + if(lineWriteIndex == MAX_LOGGER_LINES) + { + lineWriteIndex = 0; + } + receivedLinesCount++; + } + } +#endif +} + +uint8_t InfoLogger_isUpdated() +{ + uint8_t ret = 0; + if(lineReadIndex != lineWriteIndex) + { + ret = 1; + } + return ret; +} + +void openInfo_Logger() +{ + previousGlobalState = get_globalState(); + set_globalState(StILOGGER); + + loggerUpdateTime = HAL_GetTick(); +} + +void refreshInfo_Logger(GFX_DrawCfgScreen s) +{ + uint8_t index = 0; + char text[31]; + uint8_t displayLine = 0; + uint8_t color = CLUT_Font020; + + sprintf(text,"\001%c%c", TXT_2BYTE, TXT2BYTE_Logger); + + tInfo_write_content_simple( 30, 770, ME_Y_LINE_BASE, &FontT48, text, CLUT_InfoSurface); + + + if(InfoLogger_isUpdated()) + { + loggerUpdateTime = HAL_GetTick(); + } + if(receivedLinesCount > MAX_LOGGER_LINES) + { + displayLine = MAX_LOGGER_LINES-1; + } + else + { + displayLine = lineWriteIndex; + } + + if(lineReadIndex != lineWriteIndex) /* needed for isUpdated function */ + { + lineReadIndex++; + if(lineReadIndex == MAX_LOGGER_LINES) + { + lineReadIndex = 0; + } + } + while (index < displayLine) + { + color = CLUT_Font020; + if(lines[index][0] == '\002') + { + color = CLUT_NiceGreen; + } + if(lineReadIndex == index) + { + color = CLUT_NiceBlue; + } + tInfo_write_content_simple( 30, 770, 60 + (index * 30), &FontT24, (char*)lines[index], color); + + if(lineReadIndex != lineWriteIndex) /* needed for isUpdated function */ + { + lineReadIndex++; + if(lineReadIndex == MAX_LOGGER_LINES) + { + lineReadIndex = 0; + } + } + index++; + } + if((time_elapsed_ms(loggerUpdateTime, HAL_GetTick()) > 10000)) + { + set_globalState(previousGlobalState); /* restore state which was active before log data was received */ + exitInfo(); + } +} + +void sendActionToInfoLogger(uint8_t sendAction) +{ +/* TODO: at the moment a generic return to home is used because the logger window could be opened from everywhere => implement context based return from view */ + set_globalState(previousGlobalState); /* restore state which was active before log data was received */ + exitInfoSilent(); +} +
--- a/Discovery/Src/tMenu.c Sun Sep 07 20:44:35 2025 +0200 +++ b/Discovery/Src/tMenu.c Mon Sep 15 21:12:44 2025 +0200 @@ -826,7 +826,12 @@ update_content_actual_page(text, tabPosition, subtext); break; case StMSYS: - if((line == get_lineOfID(StMSYS1_DateTime)) || (line == get_lineOfID(StMSYS2_English)) || (line == get_lineOfID(StMSYS_Profile))) + if((line == get_lineOfID(StMSYS1_DateTime)) || (line == get_lineOfID(StMSYS2_English)) +#ifdef ENABLE_SETTING_PROFILES + || (line == get_lineOfID(StMSYS_Profile))) +#else + ) +#endif { tM_rebuild_pages(); menu.lineMemoryForNavigationForPage[page] = line; // fix 160623
--- a/Discovery/Src/tMenuCvOption.c Sun Sep 07 20:44:35 2025 +0200 +++ b/Discovery/Src/tMenuCvOption.c Mon Sep 15 21:12:44 2025 +0200 @@ -76,6 +76,15 @@ } nextline(text,&textPointer); +#ifdef ENABLE_PULSE_SENSOR_BT + if (line == 0 || line == 3) + { + textPointer += snprintf(&text[textPointer], 21, "%c%c", TXT_2BYTE, TXT2BYTE_Pulse); + } + nextline(text,&textPointer); + +#endif + return StMOption; } void tMCvOption_checkLineStatus(void)
--- a/Discovery/Src/tMenuEdit.c Sun Sep 07 20:44:35 2025 +0200 +++ b/Discovery/Src/tMenuEdit.c Mon Sep 15 21:12:44 2025 +0200 @@ -42,6 +42,7 @@ #include "tMenuEditSystem.h" #include "tMenuEditXtra.h" #include "tMenuEditCustom.h" +#include "cv_heartbeat.h" /* Private types -------------------------------------------------------------*/ #define TEXTSIZE 16 @@ -260,6 +261,11 @@ case StMCustom3_CViewSelection5: case StMCustom3_CViewSelection6: refreshFct = CustomviewDivemode_refresh; break; +#ifdef ENABLE_PULSE_SENSOR_BT + case (StMOption_Heartbeat): refreshFct = refresh_Heartbeat; + break; +#endif + #ifdef ENABLE_MOTION_CONTROL case (StMCustom5_CViewPortCalib & MaskFieldDigit): case StMCustom5_CViewPortLayout:
--- a/Discovery/Src/tMenuEditCustom.c Sun Sep 07 20:44:35 2025 +0200 +++ b/Discovery/Src/tMenuEditCustom.c Mon Sep 15 21:12:44 2025 +0200 @@ -528,6 +528,10 @@ case CVIEW_noneOrDebug: text = TXT2BYTE_DispNoneDbg; break; +#ifdef ENABLE_LOGGER_WINDOW + case CVIEW_Logger: text = TXT2BYTE_Logger; + break; +#endif default: break; }
--- a/Discovery/Src/tMenuEditCvOption.c Sun Sep 07 20:44:35 2025 +0200 +++ b/Discovery/Src/tMenuEditCvOption.c Mon Sep 15 21:12:44 2025 +0200 @@ -35,6 +35,8 @@ #include "tMenuEdit.h" #include "tHome.h" +#include "cv_heartbeat.h" + /* Private function prototypes -----------------------------------------------*/ static void openEdit_Timer(void); void openEdit_Compass(void); @@ -56,13 +58,15 @@ switch(line) { case 1: - default: - resetMenuEdit(CLUT_MenuPageHardware); - openEdit_Compass(); - break; - case 2: - openEdit_Timer(); - break; + default: resetMenuEdit(CLUT_MenuPageHardware); + openEdit_Compass(); + break; + case 2: openEdit_Timer(); + break; +#ifdef ENABLE_PULSE_SENSOR_BT + case 3: openEdit_Heartbeat(); +#endif + break; } }
--- a/Discovery/Src/tMenuEditSystem.c Sun Sep 07 20:44:35 2025 +0200 +++ b/Discovery/Src/tMenuEditSystem.c Mon Sep 15 21:12:44 2025 +0200 @@ -46,16 +46,19 @@ /*#define HAVE_DEBUG_VIEW */ static uint8_t infoPage = 0; +#ifdef ENABLE_SETTING_PROFILES static uint32_t profileStartCrc[NUMBER_OF_PROFILES]; static uint8_t profileActiveStart = 0; - +#endif /* Private function prototypes -----------------------------------------------*/ void openEdit_DateTime(void); void openEdit_DateFormat(void); void openEdit_Language(void); void openEdit_Design(void); +#ifdef ENABLE_SETTING_PROFILES void openEdit_Profile(void); +#endif void openEdit_Information(void); void openEdit_Reset(void); void openEdit_Maintenance(void); @@ -98,9 +101,10 @@ uint8_t OnAction_Units (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); uint8_t OnAction_Colorscheme (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); uint8_t OnAction_DebugInfo (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); +#ifdef ENABLE_SETTING_PROFILES uint8_t OnAction_Profile(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); uint8_t OnAction_SetProfile(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); - +#endif uint8_t OnAction_Exit (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); uint8_t OnAction_Confirm (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); uint8_t OnAction_Maintenance (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action); @@ -137,29 +141,33 @@ if(actual_menu_content == MENU_SURFACE) { - switch(line) - { - case 1: - default: - openEdit_DateTime(); - break; - case 2: - openEdit_Profile(); - break; - case 3: - openEdit_Language(); - break; - case 4: - openEdit_Design(); - break; - case 5: - openEdit_Information(); - break; - case 6: - openEdit_Reset(); - break; - } + if(line == get_lineOfID(StMSYS1_DateTime)) + { + openEdit_DateTime(); + } + else if(line == get_lineOfID(StMSYS2_English)) + { + openEdit_Language(); + } + else if(line == get_lineOfID(StMSYS3_Units)) + { + openEdit_Design(); + } + else if(line == get_lineOfID(StMSYS4_Info)) + { + openEdit_Information(); + } + else if(line == get_lineOfID(StMSYS5_ResetAll)) + { + openEdit_Reset(); + } +#ifdef ENABLE_SETTING_PROFILES + else if(line == get_lineOfID(StMSYS_Profile)) + { + openEdit_Profile(); + } +#endif } else { @@ -919,6 +927,7 @@ #endif } +#ifdef ENABLE_SETTING_PROFILES void changeActiveProfil(uint8_t newProfile) { SSettings *pSettings = settingsGetPointer(); @@ -992,7 +1001,8 @@ } exitMenuEdit(1); } - +#endif +#ifdef ENABLE_SETTING_PROFILES void openEdit_Profile(void) { char text[50]; @@ -1035,7 +1045,7 @@ write_buttonTextline(TXT2BYTE_ButtonBack,TXT2BYTE_ButtonEnter,TXT2BYTE_ButtonNext); } - +#endif void refresh_Design(void) @@ -1076,16 +1086,6 @@ text[1] = 0; write_label_var( 400, 700, ME_Y_LINE2, &FontT48, text); -#if 0 - /* profile */ - sprintf(text,"Profile:"); - write_label_var( 30, 300, ME_Y_LINE3, &FontT48, text); - - memset(text,0, sizeof(text)); - sprintf(text,"%s",pSettings->profileName[pSettings->activeProfile]); - tMenuEdit_newInputText(StMSYS_Profile,(uint8_t*)text); - // write_label_var( 400, 700, ME_Y_LINE3, &FontT48, text); -#endif #ifdef HAVE_DEBUG_VIEW // specials text[0] = TXT_2BYTE; @@ -1143,6 +1143,7 @@ return UPDATE_DIVESETTINGS; } +#ifdef ENABLE_SETTING_PROFILES uint8_t OnAction_SetProfile(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action) { SSettings *pSettings = settingsGetPointer(); @@ -1159,6 +1160,7 @@ tMenuEdit_newButtonText(editId,(char*)pSettings->profileName[pSettings->activeProfile]); return UNSPECIFIC_RETURN; } + uint8_t OnAction_Profile(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action) { SSettings *pSettings = settingsGetPointer(); @@ -1237,7 +1239,7 @@ } return returnValue; } - +#endif /* uint8_t OnAction_Design_t7ft (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action)
--- a/Discovery/Src/tMenuSystem.c Sun Sep 07 20:44:35 2025 +0200 +++ b/Discovery/Src/tMenuSystem.c Mon Sep 15 21:12:44 2025 +0200 @@ -145,7 +145,7 @@ strcpy(&text[textPointer],"\n\r"); textPointer += 2; } - +#ifdef ENABLE_SETTING_PROFILES if((line == 0) || (line == 2)) { textPointer += snprintf(&text[textPointer], 40,"%c%c:\t%s\n\r",TXT_2BYTE,TXT2BYTE_Profile,data->profileName[data->activeProfile]); @@ -155,7 +155,12 @@ strcpy(&text[textPointer],"\n\r"); textPointer += 2; } +#endif +#ifdef ENABLE_SETTING_PROFILES if((line == 0) || (line == 3)) +#else + if((line == 0) || (line == 2)) +#endif { text[textPointer++] = TXT_Language; text[textPointer++] = '\t'; @@ -169,8 +174,11 @@ strcpy(&text[textPointer],"\n\r"); textPointer += 2; } - +#ifdef ENABLE_SETTING_PROFILES if((line == 0) || (line == 4)) +#else + if((line == 0) || (line == 3)) +#endif { text[textPointer++] = TXT_2BYTE; text[textPointer++] = TXT2BYTE_Layout; @@ -243,7 +251,11 @@ textPointer += 2; } +#ifdef ENABLE_SETTING_PROFILES if((line == 0) || (line == 5)) +#else + if((line == 0) || (line == 4)) +#endif { text[textPointer++] = TXT_Information; text[textPointer++] = '\t'; @@ -258,7 +270,11 @@ strcpy(&text[textPointer],"\n\r"); textPointer += 2; +#ifdef ENABLE_SETTING_PROFILES if((line == 0) || (line == 6)) +#else + if((line == 0) || (line == 5)) +#endif { text[textPointer++] = TXT_2BYTE; text[textPointer++] = TXT2BYTE_ResetMenu;
--- a/Discovery/Src/text_multilanguage.c Sun Sep 07 20:44:35 2025 +0200 +++ b/Discovery/Src/text_multilanguage.c Mon Sep 15 21:12:44 2025 +0200 @@ -2005,6 +2005,18 @@ static uint8_t text_IT_Reverse[] = "Invertire"; static uint8_t text_ES_Reverse[] = "Invertir"; +static uint8_t text_EN_Pulse[] = "Heartbeat sensor (BT)"; +static uint8_t text_DE_Pulse[] = "Pulssensor (BT)"; +static uint8_t text_FR_Pulse[] = ""; +static uint8_t text_IT_Pulse[] = ""; +static uint8_t text_ES_Pulse[] = ""; + +static uint8_t text_EN_Logger[] = "Debug Messages"; +static uint8_t text_DE_Logger[] = "Logger"; +static uint8_t text_FR_Logger[] = ""; +static uint8_t text_IT_Logger[] = ""; +static uint8_t text_ES_Logger[] = ""; + /* Lookup Table -------------------------------------------------------------*/ const tText text_array[] = @@ -2319,6 +2331,8 @@ {(uint8_t)TXT2BYTE_Log, {text_EN_Log, text_DE_Log, text_FR_Log, text_IT_Log, text_ES_Log}}, {(uint8_t)TXT2BYTE_Reverse, {text_EN_Reverse, text_DE_Reverse, text_FR_Reverse, text_IT_Reverse, text_ES_Reverse}}, + {(uint8_t)TXT2BYTE_Pulse, {text_EN_Pulse, text_DE_Pulse, text_FR_Pulse, text_IT_Pulse, text_ES_Pulse}}, + {(uint8_t)TXT2BYTE_Logger, {text_EN_Logger, text_DE_Logger, text_FR_Logger, text_IT_Logger, text_ES_Logger}}, };
