wip sleep fix
This commit is contained in:
@@ -49,7 +49,6 @@ extern "C" {
|
|||||||
#include "sysclk/config.h"
|
#include "sysclk/config.h"
|
||||||
#include "sysclk/errors.h"
|
#include "sysclk/errors.h"
|
||||||
#include "sysclk/psm_ext.h"
|
#include "sysclk/psm_ext.h"
|
||||||
#include "sysclk/soctherm.hpp"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,6 +87,9 @@ typedef enum
|
|||||||
SysClkThermalSensor_Skin,
|
SysClkThermalSensor_Skin,
|
||||||
HorizonOCThermalSensor_Battery,
|
HorizonOCThermalSensor_Battery,
|
||||||
HorizonOCThermalSensor_PMIC,
|
HorizonOCThermalSensor_PMIC,
|
||||||
|
HorizonOCThermalSensor_CPU,
|
||||||
|
HorizonOCThermalSensor_GPU,
|
||||||
|
HorizonOCThermalSensor_MEM,
|
||||||
SysClkThermalSensor_EnumMax
|
SysClkThermalSensor_EnumMax
|
||||||
} SysClkThermalSensor;
|
} SysClkThermalSensor;
|
||||||
|
|
||||||
@@ -209,7 +212,12 @@ static inline const char* sysclkFormatThermalSensor(SysClkThermalSensor thermSen
|
|||||||
return pretty ? "BAT" : "battery";
|
return pretty ? "BAT" : "battery";
|
||||||
case HorizonOCThermalSensor_PMIC:
|
case HorizonOCThermalSensor_PMIC:
|
||||||
return pretty ? "PMIC" : "pmic";
|
return pretty ? "PMIC" : "pmic";
|
||||||
|
case HorizonOCThermalSensor_CPU:
|
||||||
|
return pretty ? "CPU" : "cpu";
|
||||||
|
case HorizonOCThermalSensor_GPU:
|
||||||
|
return pretty ? "GPU" : "gpu";
|
||||||
|
case HorizonOCThermalSensor_MEM:
|
||||||
|
return pretty ? "MEM" : "mem";
|
||||||
default:
|
default:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2014 - 2019, NVIDIA CORPORATION. All rights reserved.
|
|
||||||
*
|
|
||||||
* Author:
|
|
||||||
* Mikko Perttunen <mperttunen@nvidia.com>
|
|
||||||
*
|
|
||||||
* Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope 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/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------
|
|
||||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
|
||||||
* <p-sam@d3vs.net>, <natinusala@gmail.com>, <m4x@m4xw.net>
|
|
||||||
* wrote this file. As long as you retain this notice you can do whatever you
|
|
||||||
* want with this stuff. If you meet any of us some day, and you think this
|
|
||||||
* stuff is worth it, you can buy us a beer in return. - The sys-clk authors
|
|
||||||
* --------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <switch.h>
|
|
||||||
#include <sysclk.h>
|
|
||||||
|
|
||||||
namespace soctherm {
|
|
||||||
|
|
||||||
struct TSensorTemps {
|
|
||||||
s32 cpu;
|
|
||||||
s32 gpu;
|
|
||||||
s32 mem;
|
|
||||||
s32 pllx;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
"title_id": "0x00FF0000636C6BFF",
|
"title_id": "0x00FF0000636C6BFF",
|
||||||
"title_id_range_min": "0x00FF0000636C6BFF",
|
"title_id_range_min": "0x00FF0000636C6BFF",
|
||||||
"title_id_range_max": "0x00FF0000636C6BFF",
|
"title_id_range_max": "0x00FF0000636C6BFF",
|
||||||
"main_thread_stack_size": "0x0000D000",
|
"main_thread_stack_size": "0x0000C000",
|
||||||
"main_thread_priority": 16,
|
"main_thread_priority": 16,
|
||||||
"default_cpu_id": 3,
|
"default_cpu_id": 3,
|
||||||
"process_category": 1,
|
"process_category": 1,
|
||||||
|
|||||||
@@ -40,7 +40,8 @@
|
|||||||
#include "board_volt.hpp"
|
#include "board_volt.hpp"
|
||||||
#include "board_misc.hpp"
|
#include "board_misc.hpp"
|
||||||
#include "../soctherm.hpp"
|
#include "../soctherm.hpp"
|
||||||
|
#include "../integrations.hpp"
|
||||||
|
#include "../file_utils.hpp"
|
||||||
namespace board {
|
namespace board {
|
||||||
|
|
||||||
SysClkSocType gSocType;
|
SysClkSocType gSocType;
|
||||||
@@ -52,6 +53,46 @@ namespace board {
|
|||||||
|
|
||||||
u32 fd = 0, fd2 = 0;
|
u32 fd = 0, fd2 = 0;
|
||||||
|
|
||||||
|
constexpr u32 pscDependencies[] = {PscPmModuleId_Display}; // Our dependencies
|
||||||
|
constexpr PscPmModuleId pscModuleId = (PscPmModuleId)692; // Our ID
|
||||||
|
static PscPmModule pscModule; // Module to listen for events with
|
||||||
|
|
||||||
|
Thread SleepWakeListener;
|
||||||
|
|
||||||
|
void SleepWakeEventListener(void *ptr) {
|
||||||
|
while (true) {
|
||||||
|
Result rc = eventWait(&pscModule.event, 10'000'000);
|
||||||
|
if (R_VALUE(rc) == KERNELRESULT(TimedOut))
|
||||||
|
continue;
|
||||||
|
if (R_VALUE(rc) == KERNELRESULT(Cancelled))
|
||||||
|
break;
|
||||||
|
|
||||||
|
PscPmState eventState;
|
||||||
|
u32 flags;
|
||||||
|
if (R_FAILED(pscPmModuleGetRequest(&pscModule, &eventState, &flags)))
|
||||||
|
break;
|
||||||
|
|
||||||
|
switch (eventState) {
|
||||||
|
case PscPmState_ReadySleep:
|
||||||
|
fileUtils::LogLine("Sleep");
|
||||||
|
soctherm::StopSensors();
|
||||||
|
break;
|
||||||
|
case PscPmState_ReadyAwaken:
|
||||||
|
fileUtils::LogLine("Wake");
|
||||||
|
soctherm::StartSensors();
|
||||||
|
break;
|
||||||
|
case PscPmState_ReadyShutdown:
|
||||||
|
fileUtils::LogLine("Shutdown");
|
||||||
|
soctherm::StopSensors();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pscPmModuleAcknowledge(&pscModule, eventState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void FetchHardwareInfos() {
|
void FetchHardwareInfos() {
|
||||||
ReadFuses(fuseData);
|
ReadFuses(fuseData);
|
||||||
SetGpuBracket(fuseData.gpuSpeedo, speedoBracket);
|
SetGpuBracket(fuseData.gpuSpeedo, speedoBracket);
|
||||||
@@ -115,13 +156,13 @@ namespace board {
|
|||||||
Result nvCheck = 1;
|
Result nvCheck = 1;
|
||||||
if (R_SUCCEEDED(nvInitialize())) {
|
if (R_SUCCEEDED(nvInitialize())) {
|
||||||
nvCheck = nvOpen(&fd, "/dev/nvhost-ctrl-gpu");
|
nvCheck = nvOpen(&fd, "/dev/nvhost-ctrl-gpu");
|
||||||
Result nvCheck_sched = nvOpen(&fd2, "/dev/nvsched-ctrl");
|
// Result nvCheck_sched = nvOpen(&fd2, "/dev/nvsched-ctrl");
|
||||||
/* This can be improved. */
|
// /* This can be improved. */
|
||||||
NvSchedSucceed(nvCheck_sched);
|
// NvSchedSucceed(nvCheck_sched);
|
||||||
|
|
||||||
if (R_SUCCEEDED(nvCheck_sched)) {
|
// if (R_SUCCEEDED(nvCheck_sched)) {
|
||||||
SchedSetFD2(fd2);
|
// SchedSetFD2(fd2);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = rgltrInitialize();
|
rc = rgltrInitialize();
|
||||||
@@ -130,6 +171,16 @@ namespace board {
|
|||||||
rc = pmdmntInitialize();
|
rc = pmdmntInitialize();
|
||||||
ASSERT_RESULT_OK(rc, "pmdmntInitialize");
|
ASSERT_RESULT_OK(rc, "pmdmntInitialize");
|
||||||
|
|
||||||
|
rc = pscmInitialize();
|
||||||
|
ASSERT_RESULT_OK(rc, "pscmInitialize");
|
||||||
|
|
||||||
|
rc = pscmGetPmModule(&pscModule, pscModuleId, pscDependencies, sizeof(pscDependencies)/sizeof(u32), true);
|
||||||
|
ASSERT_RESULT_OK(rc, "pscmGetPmModule");
|
||||||
|
|
||||||
|
threadCreate(&SleepWakeListener, SleepWakeEventListener, NULL, NULL, 0x1000, 0x0, 3);
|
||||||
|
|
||||||
|
threadStart(&SleepWakeListener);
|
||||||
|
|
||||||
StartLoad(nvCheck, fd);
|
StartLoad(nvCheck, fd);
|
||||||
|
|
||||||
batteryInfoInitialize();
|
batteryInfoInitialize();
|
||||||
@@ -152,13 +203,16 @@ namespace board {
|
|||||||
rc = svcQueryMemoryMapping(&dsiVirtAddr, &outsize, 0x54300000, 0x40000);
|
rc = svcQueryMemoryMapping(&dsiVirtAddr, &outsize, 0x54300000, 0x40000);
|
||||||
ASSERT_RESULT_OK(rc, "svcQueryMemoryMapping (dsi)");
|
ASSERT_RESULT_OK(rc, "svcQueryMemoryMapping (dsi)");
|
||||||
|
|
||||||
display::DisplayRefreshConfig cfg = {.clkVirtAddr = clkVirtAddr, .dsiVirtAddr = dsiVirtAddr};
|
display::DisplayRefreshConfig cfg = {.clkVirtAddr = clkVirtAddr, .dsiVirtAddr = dsiVirtAddr, .isLite = (GetConsoleType() == HorizonOCConsoleType_Hoag), .isRetroSUPER = integrations::GetRETROSuperStatus()};
|
||||||
display::Initialize(&cfg);
|
display::Initialize(&cfg);
|
||||||
|
|
||||||
CacheDfllData();
|
CacheDfllData();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Exit() {
|
void Exit() {
|
||||||
|
|
||||||
|
soctherm::StopSensors();
|
||||||
|
|
||||||
if (HOSSVC_HAS_CLKRST) {
|
if (HOSSVC_HAS_CLKRST) {
|
||||||
clkrstExit();
|
clkrstExit();
|
||||||
} else {
|
} else {
|
||||||
@@ -184,9 +238,12 @@ namespace board {
|
|||||||
rgltrExit();
|
rgltrExit();
|
||||||
batteryInfoExit();
|
batteryInfoExit();
|
||||||
pmdmntExit();
|
pmdmntExit();
|
||||||
nvExit();
|
|
||||||
|
|
||||||
display::Shutdown();
|
display::Shutdown();
|
||||||
|
nvExit();
|
||||||
|
threadClose(&SleepWakeListener);
|
||||||
|
pscPmModuleFinalize(&pscModule);
|
||||||
|
pscPmModuleClose(&pscModule);
|
||||||
|
pscmExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
SysClkSocType GetSocType() {
|
SysClkSocType GetSocType() {
|
||||||
@@ -233,5 +290,4 @@ namespace board {
|
|||||||
bool IsUsingRetroSuperDisplay() {
|
bool IsUsingRetroSuperDisplay() {
|
||||||
return false; /* stub for now. */
|
return false; /* stub for now. */
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#include <battery.h>
|
#include <battery.h>
|
||||||
#include <pwm.h>
|
#include <pwm.h>
|
||||||
#include "board.hpp"
|
#include "board.hpp"
|
||||||
|
#include "../soctherm.hpp"
|
||||||
|
|
||||||
namespace board {
|
namespace board {
|
||||||
|
|
||||||
@@ -38,23 +39,50 @@ namespace board {
|
|||||||
s32 millis = 0;
|
s32 millis = 0;
|
||||||
BatteryChargeInfo info;
|
BatteryChargeInfo info;
|
||||||
|
|
||||||
if (sensor == SysClkThermalSensor_SOC) {
|
soctherm::TSensorTemps temps;
|
||||||
millis = tmp451TempSoc();
|
soctherm::ReadSensors(temps);
|
||||||
} else if (sensor == SysClkThermalSensor_PCB) {
|
|
||||||
millis = tmp451TempPcb();
|
switch(sensor) {
|
||||||
} else if (sensor == SysClkThermalSensor_Skin) {
|
case SysClkThermalSensor_SOC: {
|
||||||
if (HOSSVC_HAS_TC) {
|
millis = tmp451TempSoc();
|
||||||
Result rc;
|
break;
|
||||||
rc = tcGetSkinTemperatureMilliC(&millis);
|
}
|
||||||
ASSERT_RESULT_OK(rc, "tcGetSkinTemperatureMilliC");
|
case SysClkThermalSensor_PCB: {
|
||||||
|
millis = tmp451TempPcb();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SysClkThermalSensor_Skin: {
|
||||||
|
if (HOSSVC_HAS_TC) {
|
||||||
|
Result rc;
|
||||||
|
rc = tcGetSkinTemperatureMilliC(&millis);
|
||||||
|
ASSERT_RESULT_OK(rc, "tcGetSkinTemperatureMilliC");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case HorizonOCThermalSensor_Battery: {
|
||||||
|
batteryInfoGetChargeInfo(&info);
|
||||||
|
millis = batteryInfoGetTemperatureMiliCelsius(&info);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case HorizonOCThermalSensor_PMIC: {
|
||||||
|
millis = 50000;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case HorizonOCThermalSensor_CPU: {
|
||||||
|
millis = temps.cpu;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case HorizonOCThermalSensor_GPU: {
|
||||||
|
millis = temps.gpu;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case HorizonOCThermalSensor_MEM: {
|
||||||
|
millis = board::GetSocType() == SysClkSocType_Mariko ? temps.pllx : temps.mem;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
ASSERT_ENUM_VALID(SysClkThermalSensor, sensor);
|
||||||
}
|
}
|
||||||
} else if (sensor == HorizonOCThermalSensor_Battery) {
|
|
||||||
batteryInfoGetChargeInfo(&info);
|
|
||||||
millis = batteryInfoGetTemperatureMiliCelsius(&info);
|
|
||||||
/* } else if (sensor == HorizonOCThermalSensor_PMIC) {
|
|
||||||
millis = 50000; */
|
|
||||||
} else {
|
|
||||||
ASSERT_ENUM_VALID(SysClkThermalSensor, sensor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::max(0, millis);
|
return std::max(0, millis);
|
||||||
|
|||||||
@@ -580,7 +580,7 @@ namespace clockManager {
|
|||||||
integrations::LoadSaltyNX();
|
integrations::LoadSaltyNX();
|
||||||
}
|
}
|
||||||
|
|
||||||
gContext.isUsingRetroSuper = board::IsUsingRetroSuperDisplay();
|
gContext.isUsingRetroSuper = integrations::GetRETROSuperStatus();
|
||||||
governor::startThreads();
|
governor::startThreads();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -616,6 +616,7 @@ namespace clockManager {
|
|||||||
|
|
||||||
void Tick()
|
void Tick()
|
||||||
{
|
{
|
||||||
|
fileUtils::LogLine("CPU Temp: %d", board::GetTemperatureMilli(HorizonOCThermalSensor_CPU));
|
||||||
std::scoped_lock lock{gContextMutex};
|
std::scoped_lock lock{gContextMutex};
|
||||||
std::uint32_t mode = 0;
|
std::uint32_t mode = 0;
|
||||||
Result rc = apmExtGetCurrentPerformanceConfiguration(&mode);
|
Result rc = apmExtGetCurrentPerformanceConfiguration(&mode);
|
||||||
@@ -633,7 +634,7 @@ namespace clockManager {
|
|||||||
|
|
||||||
void WaitForNextTick()
|
void WaitForNextTick()
|
||||||
{
|
{
|
||||||
if (!(board::GetHz(SysClkModule_MEM) < 665000000))
|
if (board::GetHz(SysClkModule_MEM) > 665000000)
|
||||||
svcSleepThread(config::GetConfigValue(SysClkConfigValue_PollingIntervalMs) * 1000000ULL);
|
svcSleepThread(config::GetConfigValue(SysClkConfigValue_PollingIntervalMs) * 1000000ULL);
|
||||||
else
|
else
|
||||||
svcSleepThread(5000 * 1000000ULL); // 5 seconds in sleep mode
|
svcSleepThread(5000 * 1000000ULL); // 5 seconds in sleep mode
|
||||||
|
|||||||
@@ -95,6 +95,11 @@ namespace integrations {
|
|||||||
return stat("sdmc:/atmosphere/contents/0000000000534C56/flags/boot2.flag", &st) == 0;
|
return stat("sdmc:/atmosphere/contents/0000000000534C56/flags/boot2.flag", &st) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GetRETROSuperStatus() {
|
||||||
|
struct stat st = {0};
|
||||||
|
return stat("sdmc:/config/horizon-oc/retro.flag", &st) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
void LoadSaltyNX() {
|
void LoadSaltyNX() {
|
||||||
if (!CheckSaltyNXPort())
|
if (!CheckSaltyNXPort())
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ namespace integrations {
|
|||||||
|
|
||||||
bool GetSysDockState();
|
bool GetSysDockState();
|
||||||
bool GetSaltyNXState();
|
bool GetSaltyNXState();
|
||||||
|
bool GetRETROSuperStatus();
|
||||||
void LoadSaltyNX();
|
void LoadSaltyNX();
|
||||||
u8 GetSaltyNXFPS();
|
u8 GetSaltyNXFPS();
|
||||||
u16 GetSaltyNXResolutionHeight();
|
u16 GetSaltyNXResolutionHeight();
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
#include "clock_manager.hpp"
|
#include "clock_manager.hpp"
|
||||||
#include "ipc_service.hpp"
|
#include "ipc_service.hpp"
|
||||||
#include "config.hpp"
|
#include "config.hpp"
|
||||||
#define INNER_HEAP_SIZE 0x40000
|
#define INNER_HEAP_SIZE 0x45000
|
||||||
|
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
|
|||||||
@@ -418,7 +418,7 @@ namespace soctherm {
|
|||||||
};
|
};
|
||||||
|
|
||||||
u32 calib[SocthermTSensor_EnumMax] = {};
|
u32 calib[SocthermTSensor_EnumMax] = {};
|
||||||
u64 socthermVa;
|
u64 socthermVa, carVa, fuseVa;
|
||||||
bool isMariko;
|
bool isMariko;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -509,6 +509,22 @@ namespace soctherm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StopSensors() {
|
||||||
|
const TSensor *sensors = isMariko ? marikoTSensors : eristaTSensors;
|
||||||
|
u32 count = isMariko ? std::size(marikoTSensors) : std::size(eristaTSensors);
|
||||||
|
|
||||||
|
for (u32 i = 0; i < count; ++i) {
|
||||||
|
SetBits(socthermVa, sensors[i].base + SENSOR_CONFIG0, SENSOR_CONFIG0_STOP);
|
||||||
|
ClearBits(socthermVa, sensors[i].base + SENSOR_CONFIG1, SENSOR_CONFIG1_TEMP_ENABLE);
|
||||||
|
WriteReg(socthermVa, sensors[i].base + SENSOR_CONFIG2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteReg(socthermVa, TSENSOR_TSENSOR_CLKEN, 0);
|
||||||
|
WriteReg(carVa, CAR_CLK_SOURCE_TSENSOR, 0);
|
||||||
|
SetBits(carVa, CAR_CLK_OUT_ENB_V, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void StartSensors() {
|
void StartSensors() {
|
||||||
if (!ReadReg(socthermVa, TSENSOR_TSENSOR_CLKEN)) {
|
if (!ReadReg(socthermVa, TSENSOR_TSENSOR_CLKEN)) {
|
||||||
u32 pdiv, hotspot;
|
u32 pdiv, hotspot;
|
||||||
@@ -597,7 +613,6 @@ namespace soctherm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Initialize() {
|
void Initialize() {
|
||||||
u64 carVa, fuseVa;
|
|
||||||
isMariko = board::GetSocType() == SysClkSocType_Mariko;
|
isMariko = board::GetSocType() == SysClkSocType_Mariko;
|
||||||
|
|
||||||
constexpr u64 SocthermPa = 0x700E2000, FusePa = 0x7000F000, CarPa = 0x60006000;
|
constexpr u64 SocthermPa = 0x700E2000, FusePa = 0x7000F000, CarPa = 0x60006000;
|
||||||
|
|||||||
@@ -122,7 +122,16 @@ namespace soctherm {
|
|||||||
SocthermTSensor_EnumMax = 8,
|
SocthermTSensor_EnumMax = 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TSensorTemps {
|
||||||
|
s32 cpu;
|
||||||
|
s32 gpu;
|
||||||
|
s32 mem;
|
||||||
|
s32 pllx;
|
||||||
|
};
|
||||||
|
|
||||||
void Initialize();
|
void Initialize();
|
||||||
|
void StartSensors();
|
||||||
|
void StopSensors();
|
||||||
void ReadSensors(TSensorTemps &temps);
|
void ReadSensors(TSensorTemps &temps);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user