From c7c9ecfab8b0cf673acfbc6ee9db1cfe84cbfc40 Mon Sep 17 00:00:00 2001 From: Mati Date: Mon, 5 Aug 2019 18:57:55 +0200 Subject: [PATCH] Fine-tuning init procedure --- .../board/linux/cellular/linux_cellular.cpp | 4 ++ .../board/linux/cellular/linux_cellular.hpp | 2 + .../board/rt1051/cellular/rt1051_cellular.cpp | 12 ++++ .../board/rt1051/cellular/rt1051_cellular.hpp | 2 + module-bsp/bsp/cellular/bsp_cellular.hpp | 2 + module-cellular/Modem/ATParser.cpp | 1 + module-cellular/Modem/MuxDaemon.cpp | 34 ++++++++--- module-cellular/Modem/MuxDaemon.hpp | 1 + .../service-cellular/ServiceCellular.cpp | 60 +++++++++++++------ .../service-cellular/ServiceCellular.hpp | 1 + source/MessageType.hpp | 1 + 11 files changed, 93 insertions(+), 27 deletions(-) diff --git a/module-bsp/board/linux/cellular/linux_cellular.cpp b/module-bsp/board/linux/cellular/linux_cellular.cpp index 5da7b360a..00aab4456 100644 --- a/module-bsp/board/linux/cellular/linux_cellular.cpp +++ b/module-bsp/board/linux/cellular/linux_cellular.cpp @@ -93,6 +93,10 @@ namespace bsp { } + void LinuxCellular::Restart() { + + } + ssize_t LinuxCellular::Read(void *buf, size_t nbytes) { retry: diff --git a/module-bsp/board/linux/cellular/linux_cellular.hpp b/module-bsp/board/linux/cellular/linux_cellular.hpp index 88559e3d7..42746cfe1 100644 --- a/module-bsp/board/linux/cellular/linux_cellular.hpp +++ b/module-bsp/board/linux/cellular/linux_cellular.hpp @@ -34,6 +34,8 @@ namespace bsp { void PowerDown() override final; + void Restart() override final; + uint32_t Wait(uint32_t timeout) override final; ssize_t Read(void *buf, size_t nbytes) override final; diff --git a/module-bsp/board/rt1051/cellular/rt1051_cellular.cpp b/module-bsp/board/rt1051/cellular/rt1051_cellular.cpp index 9c33c099b..48927b4cf 100644 --- a/module-bsp/board/rt1051/cellular/rt1051_cellular.cpp +++ b/module-bsp/board/rt1051/cellular/rt1051_cellular.cpp @@ -195,6 +195,18 @@ namespace bsp { DisableRx(); } + void RT1051Cellular::Restart() { + const uint16_t RESET_DELAY_MS = 460; + + InformModemHostWakeup(); + WakeupModem(); + + GPIO_PinWrite(BSP_CELLULAR_RESET_PORT, BSP_CELLULAR_RESET_PIN, 1); + vTaskDelay(pdMS_TO_TICKS(RESET_DELAY_MS)); + GPIO_PinWrite(BSP_CELLULAR_RESET_PORT, BSP_CELLULAR_RESET_PIN, 0); + + } + ssize_t RT1051Cellular::Write(void *buf, size_t nbytes) { lpuart_transfer_t sendXfer; sendXfer.data = static_cast(buf); diff --git a/module-bsp/board/rt1051/cellular/rt1051_cellular.hpp b/module-bsp/board/rt1051/cellular/rt1051_cellular.hpp index cdcfd9d6e..cf009cb7c 100644 --- a/module-bsp/board/rt1051/cellular/rt1051_cellular.hpp +++ b/module-bsp/board/rt1051/cellular/rt1051_cellular.hpp @@ -35,6 +35,8 @@ namespace bsp { void PowerDown() override final; + void Restart() override final; + uint32_t Wait(uint32_t timeout) override final; ssize_t Read(void *buf, size_t nbytes) override final; diff --git a/module-bsp/bsp/cellular/bsp_cellular.hpp b/module-bsp/bsp/cellular/bsp_cellular.hpp index 82acbfd02..91a7da4c1 100644 --- a/module-bsp/bsp/cellular/bsp_cellular.hpp +++ b/module-bsp/bsp/cellular/bsp_cellular.hpp @@ -32,6 +32,8 @@ namespace bsp { virtual void PowerDown() = 0; + virtual void Restart() = 0; + virtual uint32_t Wait(uint32_t timeout) = 0; virtual ssize_t Read(void *buf, size_t nbytes) = 0; diff --git a/module-cellular/Modem/ATParser.cpp b/module-cellular/Modem/ATParser.cpp index 57a63ab42..1d8842c69 100644 --- a/module-cellular/Modem/ATParser.cpp +++ b/module-cellular/Modem/ATParser.cpp @@ -111,6 +111,7 @@ int ATParser::ProcessNewData() { if (urcs.size() == 5) { mux->callback(NotificationType ::PowerUpProcedureComplete,""); responseBuffer.erase(); + urcs.clear(); } } diff --git a/module-cellular/Modem/MuxDaemon.cpp b/module-cellular/Modem/MuxDaemon.cpp index 30e1260f7..f8022377c 100644 --- a/module-cellular/Modem/MuxDaemon.cpp +++ b/module-cellular/Modem/MuxDaemon.cpp @@ -132,7 +132,7 @@ bool MuxDaemon::PowerUpProcedure() { // At first send AT command to check if modem is turned on auto ret = inOutSerialDataWorker->SendATCommand("AT\r", 2); if ((ret.size() == 1 && ret[0] == "OK") || (ret.size() == 2 && ret[0] == "AT\r" && ret[1] == "OK")) { - return StartMultiplexer(); + return ConfProcedure(); } else { LOG_INFO("Modem does not respond to AT commands, trying close mux mode"); @@ -146,7 +146,7 @@ bool MuxDaemon::PowerUpProcedure() { ret = inOutSerialDataWorker->SendATCommand("AT\r", 2); if (ret.size() == 1 || ret.size() == 2) { // Modem can send echo response or not, in either case it means that modem is operating in AT mode - return StartMultiplexer(); + return ConfProcedure(); } else { LOG_INFO("Starting power up procedure..."); // If no response, power up modem and try again @@ -156,8 +156,10 @@ bool MuxDaemon::PowerUpProcedure() { } } +//TODO:M.P Fetch configuration from JSON/XML file +bool MuxDaemon::ConfProcedure() { -bool MuxDaemon::StartMultiplexer() { + LOG_DEBUG("Configuring modem..."); // Factory reset inOutSerialDataWorker->SendATCommand("AT&F\r", 2); @@ -193,18 +195,34 @@ bool MuxDaemon::StartMultiplexer() { // Turn on caller's number presentation CheckATCommandResponse(inOutSerialDataWorker->SendATCommand("AT+CLIP=1\r", 1)); + /* // Set Message format to Text + SendAT("AT+CMGF=1\r", 500); + // Set SMS received report format + SendAT("AT+CNMI=1,2,0,1,0\r", 500);*/ + // Audio configuraton, custom PCM, 16bit linear samples, primary mode, 16kHz, master, /* * M.P: Quectel confirmed that during init phase of modem sends 'ready notification" way before audio subsystem is initialized * hence in order to properly configure audio we have literally ping modem with conf command until it responds with success ret code... */ - CheckATCommandResponse(inOutSerialDataWorker->SendATCommand("AT+QDAI=1,0,0,5,0,1\r", 1)); -/* // Set Message format to Text - SendAT("AT+CMGF=1\r", 500); - // Set SMS received report format - SendAT("AT+CNMI=1,2,0,1,0\r", 500);*/ + auto audioConfRet = inOutSerialDataWorker->SendATCommand("AT+QDAI?\r",2); + if(audioConfRet.size() == 2 && !audioConfRet[0].compare("AT+QDAI=1,0,0,5,0,1")){ + // GSM modem is configured properly, skip audio configuration + StartMultiplexer(); + return true; + } + else{ + CheckATCommandResponse(inOutSerialDataWorker->SendATCommand("AT+QDAI=1,0,0,5,0,1\r", 1)); + cellular->Restart(); + LOG_DEBUG("GSM module first run, performing reset..."); + return false; + } +} +bool MuxDaemon::StartMultiplexer() { + + LOG_DEBUG("Configuring multiplexer..."); // This driver supports only Basic mode (max frame length = 127bytes and no frame errors correction) char gsm_command[128] = {}; diff --git a/module-cellular/Modem/MuxDaemon.hpp b/module-cellular/Modem/MuxDaemon.hpp index a3fead519..9734ff1f2 100644 --- a/module-cellular/Modem/MuxDaemon.hpp +++ b/module-cellular/Modem/MuxDaemon.hpp @@ -67,6 +67,7 @@ public: void RemoveMuxChannel(MuxChannel::MuxChannelType chan); bool PowerUpProcedure(); + bool ConfProcedure(); bool StartMultiplexer(); int uihPfBitReceived = 0; diff --git a/module-services/service-cellular/ServiceCellular.cpp b/module-services/service-cellular/ServiceCellular.cpp index 026b1b217..5f1f5005a 100644 --- a/module-services/service-cellular/ServiceCellular.cpp +++ b/module-services/service-cellular/ServiceCellular.cpp @@ -41,9 +41,9 @@ ServiceCellular::ServiceCellular() switch (type) { - case NotificationType::PowerUpProcedureComplete: - { - sys::Bus::SendUnicast(std::make_shared(MessageType::CellularStartMultiplexer),GetName(),this); + case NotificationType::PowerUpProcedureComplete: { + sys::Bus::SendUnicast(std::make_shared(MessageType::CellularStartConfProcedure), + GetName(), this); return; } case NotificationType::ServiceReady: @@ -98,9 +98,19 @@ sys::ReturnCodes ServiceCellular::InitHandler() { muxdaemon = MuxDaemon::Create(notificationCallback); if (muxdaemon) { - // Start power up procedure - sys::Bus::SendUnicast(std::make_shared(MessageType::CellularStartPowerUpProcedure),GetName(),this); - state = State ::PowerUpInProgress; + // Start procedure is as follow: + /* + * 1) Power-up + * 2) Init configuration of GSM modem + * 3) Optional modem reset and jump to 1) (only if it's first run of modem) + * 4) Start multiplexer + * 5) Modem fully-operational + */ + + // Start power-up procedure + sys::Bus::SendUnicast(std::make_shared(MessageType::CellularStartPowerUpProcedure), + GetName(), this); + state = State::PowerUpInProgress; return sys::ReturnCodes::Success; } else { @@ -134,41 +144,53 @@ sys::Message_t ServiceCellular::DataReceivedHandler(sys::DataMessage *msgl) { if ((msg->type == CellularNotificationMessage::Type::CallAborted) || (msg->type == CellularNotificationMessage::Type::CallBusy)) { stopTimer(callStateTimer); - }else { + } else { //ignore rest of notifications } } break; - case MessageType ::CellularStartPowerUpProcedure: - { - - if(!muxdaemon->PowerUpProcedure()){ + case MessageType::CellularStartPowerUpProcedure: { + if (!muxdaemon->PowerUpProcedure()) { LOG_FATAL("[ServiceCellular] PowerUp procedure failed"); - state = State ::Failed; + state = State::Failed; + }else{ + state = State::PowerUpInProgress; } - state = State ::MultiplexerStartInProgress; } break; - case MessageType ::CellularStartMultiplexer: - { - if (muxdaemon->StartMultiplexer()) { + case MessageType::CellularStartConfProcedure: { + // Start configuration procedure, if it's first run modem will need to be restarted + if (!muxdaemon->ConfProcedure()) { - state = State ::Ready; + } else { + state = State::MultiplexerStartInProgress; + sys::Bus::SendUnicast( + std::make_shared(MessageType::CellularStartMultiplexer), GetName(), + this); + } + + } + break; + + case MessageType::CellularStartMultiplexer: { + if (muxdaemon->StartMultiplexer()) { + LOG_DEBUG("[ServiceCellular] Modem is fully operational"); + + state = State::Ready; // Propagate "ServiceReady" notification into system sys::Bus::SendMulticast(std::make_shared( static_cast(NotificationType::ServiceReady)), sys::BusChannels::ServiceCellularNotifications, this); } else { LOG_FATAL("[ServiceCellular] Initialization failed, not ready"); - state = State ::Failed; + state = State::Failed; } } break; - case MessageType::CellularListCurrentCalls: { auto ret = muxdaemon->SendCommandResponse(MuxChannel::MuxChannelType::Communication, "AT+CLCC\r", 3); if ((ret.size() == 3) && (ret[2] == "OK")) { diff --git a/module-services/service-cellular/ServiceCellular.hpp b/module-services/service-cellular/ServiceCellular.hpp index e3770e16b..0b2958747 100644 --- a/module-services/service-cellular/ServiceCellular.hpp +++ b/module-services/service-cellular/ServiceCellular.hpp @@ -24,6 +24,7 @@ public: enum class State{ Idle, PowerUpInProgress, + ModemConfigurationInProgress, MultiplexerStartInProgress, Ready, Failed diff --git a/source/MessageType.hpp b/source/MessageType.hpp index 3b5086ec7..0c70c5855 100644 --- a/source/MessageType.hpp +++ b/source/MessageType.hpp @@ -53,6 +53,7 @@ enum class MessageType { CellularListCurrentCalls, CellularStartPowerUpProcedure, + CellularStartConfProcedure, CellularStartMultiplexer, //Audio service messages