// // Created by xemon on 02.09.22. // //#include #include #include "SerialPort.h" #include "SystemDelayInterface.h" #include "AsciiStringAssmeblingUtils.h" #include "NmeaACPParser.h" #include "GsmWithGnss.h" #include "AtGsmTelitLe910.h" #include "AtCmdCommonProtected.h" #include "AtGsmSms_DeleteAll.h" #include "Nmea0183Parser.h" #include "Rtc.h" #define LOGGER env->logger #define LOG_SIGN "GSM&GNSSOPS" time_t gnssTime; bool fl_rtcIsUsed = false; #define GWG_IER(FUNC) {A} AtCommandResult GsmWithGnssInitGnss(tGsmWithGnss *env) { AT_INOKR(AtGsmTelitLe910_GnssSwitchOnRestoreParam(&env->gsmAt)) SystemDelayMs(200); AT_INOKR(AtGsmTelitLe910_Gnss_ClearNvramGnssBuf(&env->gsmAt)); SystemDelayMs(200); AT_INOKR(AtGsmTelitLe910_Gnss_ClearStaticBufFix(&env->gsmAt)); SystemDelayMs(200); // AT_INOKR(AtGsmTelitLe910_Gnss_AGPSup(&env->gsmAt,2)); // SystemDelayMs(1000); AT_INOKR(AtGsmTelitLe910_Gnss_ReStartReceiver(&env->gsmAt, 1)); SystemDelayMs(200); AT_INOKR(AtGsmTelitLe910_SIMCardDetect(&env->gsmAt)); SystemDelayMs(200); return AT_OK; } void AtGsm_Gsnss_NavData_Incorrect(tGsmWithGnss *env) { env->gnss.currentRmc.status = 'V'; } void AtGsm_Gsnss_NavData_Processing(tGsmWithGnss *env) { // Поиск строки RMC // char Data[] = "$GPRMC,122118.00,A,5500.000013,N,03700.002305,E,0.0,0.0,180119,8.5,E,A,V*49"; // bNmea0183ParseRMC(Data + 7, sizeof(Data)- 7, &env->gnss.currentRmc); // env->gnss.success = true; if (bNmea0183IsRmcString(env->gsmAt.rxBuffer.data, env->gsmAt.rxBuffer.len)) { if (bNmea0183IsValidString(env->gsmAt.rxBuffer.data, env->gsmAt.rxBuffer.len)) { bNmea0183ParseRMC(env->gsmAt.rxBuffer.data + 7, env->gsmAt.rxBuffer.len - 7, &env->gnss.currentRmc); env->gnss.success = true; } } } #ifdef UVEOS_ADD_TELEMATICA void Gnss_GetFullNavData(tGsmWithGnss *env, tNmeaRmc *nmeaRmc) { if (osMutexAcquire(env->gnssRmcGga.rmcAccess, 2000) == osOK) { memcpy(nmeaRmc, &env->gnssRmcGga.currentRmc, sizeof(tNmeaRmc)); osMutexRelease(env->gnssRmcGga.rmcAccess); } else { LoggerInfoStatic(LOGGER, LOG_SIGN, "Ошибка захвата доступа Gnss_GetFullNavData") } } #endif void GsmWithGnss_GetNevData(tGsmWithGnss *env, uint32_t timeout) { GsmWithGnss_StartRMCThread(&env->gsmAt); uint32_t endTimeout = SystemGetMs() + timeout; env->gnss.currentRmc.time.second = 0; while (endTimeout > SystemGetMs()) { AtCmdProcessUnresolvedLines(&env->gsmAt); if (env->gnss.currentRmc.time.second != 0) { GsmWithGnss_StopRMCThread(&env->gsmAt); osMutexRelease(env->gsmAt.access); return; } SystemDelayMs(2); } GsmWithGnss_StopRMCThread(&env->gsmAt); } void AtGsm_Gsnss_GetNMEA_Pack(tGsmWithGnss *env, uint32_t timeout) { env->gnss.currentAcp.status = 0; char acpString[256]; size_t aspStringLen; xAtGsmTelitLe910_Gnss_GetAcquiredPositionNMEA(&env->gsmAt, acpString, &aspStringLen, timeout); if (bNmeaACPString(acpString, aspStringLen, &env->gnss.currentAcp)) { if (bNmeaACPParse(acpString, aspStringLen, &env->gnss.currentAcp) && aspStringLen > 24) { #ifdef UVEOS_ADD_TELEMATICA if (osMutexAcquire(env->gnssRmcGga.rmcAccess, 2000) == osOK) { memcpy(&env->gnssRmcGga.currentRmc, &env->gnss.currentAcp, sizeof(env->gnss.currentAcp)); osMutexRelease(env->gnssRmcGga.rmcAccess); } if (env->gnssRmcGga.currentRmc.time.second != 0) { if (env->isRtcACP == false) { time_t timestamp; timestamp = iNmea0183TimestampFromRmc(&env->gnssRmcGga.currentRmc); if (timestamp > 1733817613) { env->isRtcACP = true; RtcSet(env->Rtc, ×tamp); } } } #endif env->gnss.success = true; } } } char convertDecToMilliArcSec(double dec, int32_t *mArcs, double *gradus) { int deg = 0, min = 0; double sec = 0.0; double _dec = dec; deg = (int) (_dec / 100); min = (int) (_dec) - (deg * 100); sec = (double) (_dec - min - 100 * deg) * 60.0; if (gradus != NULL) *gradus = deg + min / 60.0 + sec / 3600.0; if (mArcs != NULL) *mArcs = (int) (deg * 3600 + min * 60) * 1000 + (int) (sec * 1000); return 0; } void NmeaRMCLocationToLocationACP(tNmeaLocationAcp *nmea, EraGlonassUveosNavData *gnss) { convertDecToMilliArcSec(nmea->latitude, &gnss->latitude, NULL); convertDecToMilliArcSec(nmea->longitude, &gnss->longitude, NULL); } void NmeaRMCLocationToLocationRMC(tNmeaLocationRmc *nmea, EraGlonassUveosNavData *gnss) { convertDecToMilliArcSec(nmea->latitude, &gnss->latitude, NULL); convertDecToMilliArcSec(nmea->longitude, &gnss->longitude, NULL); } void GnssTaskGetTime(tGsmWithGnss *env, uint32_t *timestamp) { *timestamp = iNmea0183TimestampFromRmc(&env->gnss.currentRmc); } void GnssSetRTC(tGsmWithGnss *env) { if (env->gnss.currentRmc.time.second != 0) { if (!fl_rtcIsUsed) { GnssTaskGetTime(env, (uint32_t *) &gnssTime); RtcSet(env->Rtc, &gnssTime); fl_rtcIsUsed = true; } } } void AtGsm_Gsnss_GetLastActualNavData(tGsmWithGnss *env, EraGlonassUveosNavData *location, bool locSourse) { if (locSourse == 1) { if (env->gnss.currentRmc.status == 'A') { env->gnss.prevRmc = env->gnss.currentRmc; location->valid = 2; } else { if (env->gnss.prevRmc.status == 'A') { env->gnss.currentRmc = env->gnss.prevRmc; env->gnss.currentRmc.status = 'V'; location->valid = 1; } else if (env->gnss.prevRmc.location.latitude < 1) { env->gnss.currentRmc.status = 'V'; location->valid = 0; } } } else { if (env->gnss.currentAcp.status == 'A') { location->valid = 1; } else { location->valid = 0; } } } void GnssGetNavData(tGsmWithGnss *env, EraGlonassUveosNavData *location, bool locSourse) { GnssSetRTC(env); AtGsm_Gsnss_GetLastActualNavData(env, location, locSourse); if (locSourse == 1) { NmeaRMCLocationToLocationRMC(&env->gnss.currentRmc.location, location); location->direction = (uint16_t) env->gnss.currentRmc.headingAngle; } else { NmeaRMCLocationToLocationACP(&env->gnss.currentAcp.location, location); location->direction = (uint16_t) env->gnss.currentAcp.course; } }