~aleteoryx/muditaos

1336f48251c3d56d3d4f5746ea7eae9e0bff4509 — Mateusz Grzywacz 5 years ago c8e7e70
[EGD-5229] Cellular modem, change receiving to DMA

Changes implementation for receiving data from
cellular modem from IRQ byte-by-byte to DMA transactions.
Drop in replacement, works with current CMUX (TS07.10)
M module-bsp/board/rt1051/bluetooth/BluetoothCommon.cpp => module-bsp/board/rt1051/bluetooth/BluetoothCommon.cpp +2 -2
@@ 323,10 323,10 @@ extern "C"
        bsp::BlueKitchen *bt = bsp::BlueKitchen::getInstance();

        if (isrReg & kLPUART_RxDataRegFullFlag) {
            LOG_WARN("LPUART IRQ RX full");
            LOG_WARN("Bluetooth IRQ RX full");
        }
        if (isrReg & kLPUART_RxOverrunFlag) {
            LOG_WARN("LPUART IRQ RX overrun");
            LOG_WARN("Bluetooth IRQ RX overrun");
            val = bluetooth::Message::EvtUartError;
            xQueueSendFromISR(bt->qHandle, &val, &taskwoken);
        }

M module-bsp/board/rt1051/bsp/cellular/rt1051_cellular.cpp => module-bsp/board/rt1051/bsp/cellular/rt1051_cellular.cpp +211 -77
@@ 1,4 1,4 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "rt1051_cellular.hpp"


@@ 6,20 6,25 @@
#include "task.h"
#include "stream_buffer.h"

#include "../pit/pit.hpp"
#include "dma_config.h"
#include "fsl_cache.h"
#include "../../common/chip.hpp"
#include <common_data/EventStore.hpp>
#include <map>

#include <algorithm>

#if _RT1051_UART_DEBUG == 1
#define logUARTdebug(...) LOG_DEBUG(__VA_ARGS__)
#else
#define logUARTdebug(...)
#endif

namespace bsp::cellular
{
    void readline()
    void notifyReceivedNew()
    {
        BaseType_t hp = pdFALSE;
        if (bsp::RT1051Cellular::blockedTaskHandle) {
            vTaskNotifyGiveFromISR(bsp::RT1051Cellular::blockedTaskHandle, &hp);
        if (bsp::RT1051Cellular::untilReceivedNewHandle != nullptr) {
            vTaskNotifyGiveFromISR(bsp::RT1051Cellular::untilReceivedNewHandle, &hp);
        }
        portEND_SWITCHING_ISR(hp);
    }


@@ 29,50 34,63 @@ extern "C"
{
    void LPUART1_IRQHandler(void)
    {
        BaseType_t xHigherPriorityTaskWoken = pdFALSE;

        uint32_t isrReg               = LPUART_GetStatusFlags(CELLULAR_UART_BASE);
        static char characterReceived = 0;
        uint32_t isrReg = LPUART_GetStatusFlags(CELLULAR_UART_BASE);

        if (bsp::RT1051Cellular::uartRxStreamBuffer != NULL) {
            if (isrReg & kLPUART_RxDataRegFullFlag) {
                characterReceived = LPUART_ReadByte(CELLULAR_UART_BASE);

                if (characterReceived != 0) {
                    if (xStreamBufferSpacesAvailable(bsp::RT1051Cellular::uartRxStreamBuffer) < 8) {
                        LOG_FATAL("...");
            auto RxDmaStatus = LPUART_TransferGetReceiveCountEDMA(
                CELLULAR_UART_BASE,
                &bsp::RT1051Cellular::uartDmaHandle,
                reinterpret_cast<uint32_t *>(&bsp::RT1051Cellular::RXdmaReceivedCount));

            if (isrReg & bsp::RT1051Cellular::startIRQMask) {
                if (RxDmaStatus == kStatus_NoTransferInProgress) {
                    LPUART_DisableInterrupts(CELLULAR_UART_BASE, bsp::RT1051Cellular::startIRQMaskEnable);
                    bsp::RT1051Cellular::RXdmaReceivedCount = -1;
                    if (not bsp::RT1051Cellular::StartReceive(bsp::RT1051Cellular::GetFreeStreamBufferSize())) {
                        bsp::RT1051Cellular::RestartReceivingManually = true;
                        bsp::RT1051Cellular::FinishReceive();
                    }
                    xStreamBufferSendFromISR(bsp::RT1051Cellular::uartRxStreamBuffer,
                                             (void *)&characterReceived,
                                             1,
                                             &xHigherPriorityTaskWoken);
                    logUARTdebug("[RX] on Incoming data");
                }
            }

            if (isrReg & kLPUART_IdleLineFlag) {
                bsp::cellular::readline();
            if (isrReg & bsp::RT1051Cellular::finishIRQMask) {
                if (RxDmaStatus != kStatus_NoTransferInProgress) {
                    LPUART_TransferAbortReceiveEDMA(CELLULAR_UART_BASE, &bsp::RT1051Cellular::uartDmaHandle);
                    logUARTdebug("[RX idle] stopped engine");
                }
                logUARTdebug("[RX idle], received %d bytes", bsp::RT1051Cellular::RXdmaReceivedCount);
                // the main exit path on transmission done
                if (bsp::RT1051Cellular::RXdmaReceivedCount >= 0) {
                    if (bsp::RT1051Cellular::RXdmaReceivedCount > 0) {
                        bsp::RT1051Cellular::MoveRxDMAtoStreamBuf(bsp::RT1051Cellular::RXdmaReceivedCount);
                        bsp::RT1051Cellular::RXdmaReceivedCount = -1;
                    }
                    if (not bsp::RT1051Cellular::RestartReceivingManually) {
                        bsp::RT1051Cellular::FinishReceive();
                    }
                }
            }

            LPUART_ClearStatusFlags(CELLULAR_UART_BASE, isrReg);

            portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
        }
    }
};

namespace bsp
{
    uint8_t RT1051Cellular::RXdmaBuffer[RXdmaBufferSize] = {0};
    ssize_t RT1051Cellular::RXdmaReceivedCount           = -1;
    size_t RT1051Cellular::RXdmaMaxReceivedCount         = -1;
    bool RT1051Cellular::RestartReceivingManually        = false;

    using namespace drivers;

    lpuart_edma_handle_t RT1051Cellular::uartDmaHandle      = {};
    TaskHandle_t RT1051Cellular::blockedTaskHandle          = nullptr;
    TaskHandle_t RT1051Cellular::untilReceivedNewHandle     = nullptr;
    StreamBufferHandle_t RT1051Cellular::uartRxStreamBuffer = nullptr;

    RT1051Cellular::RT1051Cellular()
    {
        bsp::pit::init(nullptr);

        MSPInit();
        /// to set Store::GSM sim state and to log debug
        Store::GSM::get()->tray =


@@ 97,11 115,16 @@ namespace bsp
        s_cellularConfig.parityMode    = kLPUART_ParityDisabled;
        s_cellularConfig.isMsb         = false;
        s_cellularConfig.rxIdleType    = kLPUART_IdleTypeStartBit;
        s_cellularConfig.rxIdleConfig  = kLPUART_IdleCharacter1;
        s_cellularConfig.enableTx      = false;
        s_cellularConfig.enableRx      = false;
        s_cellularConfig.enableTxCTS   = true;
        s_cellularConfig.enableRxRTS   = true;
#if _RT1051_UART_DEBUG
        s_cellularConfig.rxIdleConfig = kLPUART_IdleCharacter4; // Logs take time
#else
        s_cellularConfig.rxIdleConfig = kLPUART_IdleCharacter1;
#endif
        s_cellularConfig.enableTx    = false;
        s_cellularConfig.enableRx    = false;
        s_cellularConfig.enableTxCTS = true;
        s_cellularConfig.txCtsConfig = kLPUART_CtsSampleAtStart; // be nice, allow to stop mid txfer
        s_cellularConfig.enableRxRTS = true;

        if (LPUART_Init(CELLULAR_UART_BASE, &s_cellularConfig, GetPerphSourceClock(PerphClock_LPUART)) !=
            kStatus_Success) {


@@ 109,16 132,17 @@ namespace bsp
            return;
        }

        LPUART_EnableInterrupts(CELLULAR_UART_BASE, kLPUART_IdleLineInterruptEnable | kLPUART_RxDataRegFullFlag);
        static_assert(rxStreamBufferLength >= 6, "Minimum buffer size (i.e. sufficient to enable flow control)");
        static_assert(rxStreamBufferLength >= 1024, "To be able to fit entire response");

        // CANNOT disable FIFO, dma *needs* it :o
        // CELLULAR_UART_BASE->FIFO &= ~LPUART_FIFO_RXFE_MASK;

        LPUART_ClearStatusFlags(CELLULAR_UART_BASE, 0xFFFFFFFF);
        NVIC_ClearPendingIRQ(LPUART1_IRQn);
        NVIC_ClearPendingIRQ(GPIO1_Combined_0_15_IRQn);
        NVIC_SetPriority(GPIO1_Combined_0_15_IRQn, configLIBRARY_LOWEST_INTERRUPT_PRIORITY);
        NVIC_SetPriority(LPUART1_IRQn, configLIBRARY_LOWEST_INTERRUPT_PRIORITY);
        NVIC_EnableIRQ(GPIO1_Combined_0_15_IRQn);
        NVIC_EnableIRQ(LPUART1_IRQn);

        EnableRx();
        isInitialized = true;
    }



@@ 140,8 164,8 @@ namespace bsp
        DisableTx();

        NVIC_DisableIRQ(LPUART1_IRQn);
        NVIC_DisableIRQ(GPIO1_Combined_0_15_IRQn);
        LPUART_DisableInterrupts(CELLULAR_UART_BASE, kLPUART_IdleLineInterruptEnable | kLPUART_RxDataRegFullFlag);
        LPUART_DisableInterrupts(CELLULAR_UART_BASE,
                                 kLPUART_IdleLineInterruptEnable | kLPUART_RxDataRegFullInterruptEnable);
        LPUART_ClearStatusFlags(CELLULAR_UART_BASE, 0xFFFFFFFF);
        NVIC_ClearPendingIRQ(LPUART1_IRQn);



@@ 151,7 175,7 @@ namespace bsp
        DMADeinit();

        memset(&uartDmaHandle, 0, sizeof uartDmaHandle);
        blockedTaskHandle = nullptr;
        untilReceivedNewHandle = nullptr;
    }

    void RT1051Cellular::PowerUp()


@@ 210,10 234,16 @@ namespace bsp
    {
        lpuart_transfer_t sendXfer;
#if _RT1051_UART_DEBUG
        LOG_PRINTF("[TX] ");
        LOG_PRINTF("[TX: %d]", nbytes);
        uint8_t *ptr = (uint8_t *)buf;
        LOG_PRINTF("\n{");
        for (size_t i = 0; i < nbytes; i++)
            LOG_PRINTF("%02X ", (uint8_t)*ptr++);
        LOG_PRINTF("}\n<");
        ptr = (uint8_t *)buf;
        for (size_t i = 0; i < nbytes; i++)
            LOG_PRINTF("%c", (uint8_t)*ptr++);
        LOG_PRINTF(">");
        LOG_PRINTF("\n");
#endif
        sendXfer.data     = static_cast<uint8_t *>(buf);


@@ 223,16 253,17 @@ namespace bsp
            ExitSleep();
        }

        EnableTx();

        uartDmaHandle.userData = xTaskGetCurrentTaskHandle();
        SCB_CleanInvalidateDCache();

        EnableTx();
        if (LPUART_SendEDMA(CELLULAR_UART_BASE, &uartDmaHandle, &sendXfer) != kStatus_Success) {
            LOG_ERROR("Cellular: TX Failed!");
            DisableTx();
            return -1;
        }

        // wait for Tx to finish
        auto ulNotificationValue = ulTaskNotifyTake(pdFALSE, 100);

        if (ulNotificationValue == 0) {


@@ 242,38 273,131 @@ namespace bsp
        }

        DisableTx();

        return nbytes;
    }

    bool RT1051Cellular::MoveRxDMAtoStreamBuf(size_t nbytes)
    {
        BaseType_t xHigherPriorityTaskWoken = pdFALSE;

        assert(nbytes > 0);

        if (nbytes > GetFreeStreamBufferSize()) {
            LOG_ERROR("Cannot dump DMA buffer. Data is lost (%d>%d)", nbytes, GetFreeStreamBufferSize());
            return false;
        }

#if _RT1051_UART_DEBUG
        auto ret =
#endif
            xStreamBufferSendFromISR(uartRxStreamBuffer, (void *)&RXdmaBuffer, nbytes, &xHigherPriorityTaskWoken);
        logUARTdebug("[RX] moved %d bytes to streambuf", ret);

        portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
        return true;
    }

    size_t RT1051Cellular::GetFreeStreamBufferSize()
    {
        return xStreamBufferSpacesAvailable(bsp::RT1051Cellular::uartRxStreamBuffer);
    }

    bool RT1051Cellular::StartReceive(size_t nbytes)
    {
        if (!(GetFreeStreamBufferSize() > 0)) {
            logUARTdebug("Not starting RX DMA, stream buffer is full. Be aware");
            return false;
        }

        else {
            // sanitize input
            RXdmaMaxReceivedCount = std::min(nbytes, static_cast<size_t>(RXdmaBufferSize));
            logUARTdebug("Starting DMA RX, max %d bytes", RXdmaMaxReceivedCount);
        }
        assert(RXdmaMaxReceivedCount <= RXdmaBufferSize);

        // start RXfer if there is a byte incoming and no pending RXfer
        lpuart_transfer_t receiveXfer;
        receiveXfer.data     = RXdmaBuffer;
        receiveXfer.dataSize = RXdmaMaxReceivedCount;

        // rx config
        auto status = LPUART_ReceiveEDMA(CELLULAR_UART_BASE, &uartDmaHandle, &receiveXfer);
        switch (status) {
        case kStatus_Success:
            break;
        case kStatus_LPUART_RxBusy:
            LOG_WARN("UART RX DMA already busy");
            return false;
        case kStatus_InvalidArgument:
            LOG_WARN("UART RX DMA invalid argument");
            return false;
        }
        return true;
    }

    void RT1051Cellular::FinishReceive()
    {
        logUARTdebug("[RX] finish");
        bsp::cellular::notifyReceivedNew();
    }

    ssize_t RT1051Cellular::Read(void *buf, size_t nbytes)
    {
        ssize_t ret = xStreamBufferReceive(uartRxStreamBuffer, buf, nbytes, 0);
#if _RT1051_UART_DEBUG
        if (ret > 0) {
            LOG_PRINTF("[RX] ");
            LOG_PRINTF("[RX: %d]", ret);
            uint8_t *ptr = (uint8_t *)buf;
            for (size_t i = 0; i < ret; i++)
            LOG_PRINTF("\n{");
            for (ssize_t i = 0; i < ret; i++)
                LOG_PRINTF("%02X ", (uint8_t)*ptr++);
            LOG_PRINTF("\n");
            LOG_PRINTF("}\n<");
            ptr = (uint8_t *)buf;
            for (ssize_t i = 0; i < ret; i++)
                LOG_PRINTF("%c", (uint8_t)*ptr++);
            LOG_PRINTF(">");
        }
        else {
            LOG_PRINTF("[RX] GOT NOTHING (requested %d)", nbytes);
        }
        LOG_PRINTF("\n");
#endif
        if (RestartReceivingManually) {
            logUARTdebug("[RX] resume on Paused");
            // need to start manually, as RegBuf might be already full, therefore no Active Edge Interrupt
            if (StartReceive(GetFreeStreamBufferSize())) {
                RestartReceivingManually = false;
            }
            else {
                // do not lose information as whether manual start needs to be initiated and schedule next poke on Read
                LOG_WARN("Modem is waiting to send data. Stream buffer likely too small");
                FinishReceive();
            }
        }
        return ret;
    }

    uint32_t RT1051Cellular::Wait(uint32_t timeout)
    {
        if (blockedTaskHandle != nullptr) {
        logUARTdebug("[WAIT]");
        if (untilReceivedNewHandle != nullptr) {
            LOG_FATAL("Wait called simultaneously from more than one thread!");
            return 0;
        }

        // no need to wait: buffer already contains something
        if (xStreamBufferBytesAvailable(uartRxStreamBuffer)) {
            return 1;
        }

        blockedTaskHandle = xTaskGetCurrentTaskHandle();
        auto ret          = ulTaskNotifyTake(pdTRUE, timeout);
        blockedTaskHandle = nullptr;
        EnableRx();

        // …start waiting for [timeout] until a new xfer from modem is received
        untilReceivedNewHandle = xTaskGetCurrentTaskHandle();
        auto ret               = ulTaskNotifyTake(pdTRUE, timeout);
        untilReceivedNewHandle = nullptr;
        return ret;
    }



@@ 333,12 457,6 @@ namespace bsp
                                 1 << static_cast<uint32_t>(BoardDefinitions::CELLULAR_GPIO_2_ANTSEL_PIN));

        // INPUTS

        gpio_1->ConfPin(DriverGPIOPinParams{.dir      = DriverGPIOPinParams::Direction::Input,
                                            .irqMode  = DriverGPIOPinParams::InterruptMode::IntRisingOrFallingEdge,
                                            .defLogic = 0,
                                            .pin = static_cast<uint32_t>(BoardDefinitions::CELLULAR_GPIO_1_CTS_PIN)});

        gpio_1->ConfPin(
            DriverGPIOPinParams{.dir      = DriverGPIOPinParams::Direction::Input,
                                .irqMode  = DriverGPIOPinParams::InterruptMode::IntRisingOrFallingEdge,


@@ 357,12 475,6 @@ namespace bsp
                                .pin = static_cast<uint32_t>(BoardDefinitions::CELLULAR_GPIO_2_SIM_TRAY_INSERTED_PIN)});

        // OUTPUTS

        gpio_1->ConfPin(DriverGPIOPinParams{.dir      = DriverGPIOPinParams::Direction::Output,
                                            .irqMode  = DriverGPIOPinParams::InterruptMode::IntRisingOrFallingEdge,
                                            .defLogic = 1,
                                            .pin = static_cast<uint32_t>(BoardDefinitions::CELLULAR_GPIO_1_RTS_PIN)});

        gpio_1->ConfPin(DriverGPIOPinParams{.dir      = DriverGPIOPinParams::Direction::Output,
                                            .irqMode  = DriverGPIOPinParams::InterruptMode::NoIntmode,
                                            .defLogic = 0,


@@ 420,8 532,7 @@ namespace bsp
        ;
        // ENABLE INTERRUPTS

        gpio_1->EnableInterrupt(1 << static_cast<uint32_t>(BoardDefinitions::CELLULAR_GPIO_1_CTS_PIN) |
                                1 << static_cast<uint32_t>(BoardDefinitions::CELLULAR_GPIO_1_STATUS_PIN));
        gpio_1->EnableInterrupt(1 << static_cast<uint32_t>(BoardDefinitions::CELLULAR_GPIO_1_STATUS_PIN));
        gpio_2->EnableInterrupt(1 << static_cast<uint32_t>(BoardDefinitions::CELLULAR_GPIO_2_SIM_TRAY_INSERTED_PIN) |
                                1 << static_cast<uint32_t>(BoardDefinitions::CELLULAR_GPIO_2_RI_PIN));
    }


@@ 445,32 556,55 @@ namespace bsp
        dma = DriverDMA::Create(static_cast<DMAInstances>(BoardDefinitions::CELLULAR_DMA), DriverDMAParams{});

        txDMAHandle = dma->CreateHandle(static_cast<uint32_t>(BoardDefinitions::CELLULAR_TX_DMA_CHANNEL));
        dmamux->Enable(static_cast<uint32_t>(BoardDefinitions::CELLULAR_TX_DMA_CHANNEL),
                       kDmaRequestMuxLPUART1Tx); // TODO: M.P fix BSP_CELLULAR_UART_TX_DMA_CH
        rxDMAHandle = dma->CreateHandle(static_cast<uint32_t>(BoardDefinitions::CELLULAR_RX_DMA_CHANNEL));

        dmamux->Enable(static_cast<uint32_t>(BoardDefinitions::CELLULAR_TX_DMA_CHANNEL), kDmaRequestMuxLPUART1Tx);
        dmamux->Enable(static_cast<uint32_t>(BoardDefinitions::CELLULAR_RX_DMA_CHANNEL), kDmaRequestMuxLPUART1Rx);

        LPUART_TransferCreateHandleEDMA(CELLULAR_UART_BASE,
                                        &uartDmaHandle,
                                        DMATxCompletedCb,
                                        uartDMACallback,
                                        NULL,
                                        reinterpret_cast<edma_handle_t *>(txDMAHandle->GetHandle()),
                                        NULL);
                                        reinterpret_cast<edma_handle_t *>(rxDMAHandle->GetHandle()));
    }

    void RT1051Cellular::DMADeinit()
    {
        dmamux->Disable(static_cast<uint32_t>(BoardDefinitions::CELLULAR_TX_DMA_CHANNEL));
        dmamux->Disable(static_cast<uint32_t>(BoardDefinitions::CELLULAR_RX_DMA_CHANNEL));
    }

    void RT1051Cellular::DMATxCompletedCb(LPUART_Type *base,
                                          lpuart_edma_handle_t *handle,
                                          status_t status,
                                          void *userData)
    void RT1051Cellular::uartDMACallback(LPUART_Type *base,
                                         lpuart_edma_handle_t *handle,
                                         status_t status,
                                         void *userData)
    {
        BaseType_t higherPriorTaskWoken = pdFALSE;

        switch (status) {
        case kStatus_LPUART_TxIdle: {
            logUARTdebug("[TX done]");
            // task handle to be released in userData
            vTaskNotifyGiveFromISR((TaskHandle_t)userData, &higherPriorTaskWoken);

        BaseType_t higherPriorTaskWoken = 0;
        vTaskNotifyGiveFromISR((TaskHandle_t)userData, &higherPriorTaskWoken);
            portEND_SWITCHING_ISR(higherPriorTaskWoken);

        portEND_SWITCHING_ISR(higherPriorTaskWoken);
            break;
        }
        case kStatus_LPUART_RxIdle:
            logUARTdebug("[RX] Chunk done. Flow control must hold the gate from now on");
            if (MoveRxDMAtoStreamBuf(RXdmaMaxReceivedCount) and StartReceive(GetFreeStreamBufferSize())) {
                // usual mode: append a chunk and wait for line idle to finish receive
            }
            else {
                // the auxiliary exit path on stream buffer full
                RestartReceivingManually = true;
                FinishReceive();
            }
            RXdmaReceivedCount = -1;
            break;
        }
    }

    void RT1051Cellular::SetSendingAllowed(bool state)

M module-bsp/board/rt1051/bsp/cellular/rt1051_cellular.hpp => module-bsp/board/rt1051/bsp/cellular/rt1051_cellular.hpp +34 -9
@@ 1,4 1,4 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#ifndef PUREPHONE_RT1501_CELLULAR_HPP


@@ 64,6 64,12 @@ namespace bsp
        void SelectAntenna(bsp::cellular::antenna antenna) override final;
        bsp::cellular::antenna GetAntenna() override final;

        static lpuart_edma_handle_t uartDmaHandle;

        static void FinishReceive();

        static bool RestartReceivingManually;

      private:
        void MSPInit();



@@ 73,17 79,26 @@ namespace bsp

        void DMADeinit();

        inline void EnableRx()
      public:
        static constexpr uint32_t startIRQMaskEnable =
            kLPUART_RxActiveEdgeInterruptEnable | kLPUART_RxDataRegFullInterruptEnable;
        static constexpr uint32_t finishIRQMaskEnable = kLPUART_IdleLineInterruptEnable;

        static constexpr uint32_t startIRQMask  = kLPUART_RxActiveEdgeFlag | kLPUART_RxDataRegFullFlag;
        static constexpr uint32_t finishIRQMask = kLPUART_IdleLineFlag;

      private:
        static inline void EnableRx(uint32_t irqMask = startIRQMaskEnable | finishIRQMaskEnable)
        {
            LPUART_ClearStatusFlags(CELLULAR_UART_BASE, 0xFFFFFFFF);
            LPUART_EnableInterrupts(CELLULAR_UART_BASE, kLPUART_RxDataRegFullInterruptEnable);
            LPUART_EnableInterrupts(CELLULAR_UART_BASE, irqMask);
            LPUART_EnableRx(CELLULAR_UART_BASE, true);
        }

        inline void DisableRx()
        static inline void DisableRx(uint32_t irqMask = startIRQMaskEnable | finishIRQMaskEnable)
        {
            LPUART_DisableInterrupts(CELLULAR_UART_BASE, kLPUART_RxDataRegFullInterruptEnable);
            LPUART_ClearStatusFlags(CELLULAR_UART_BASE, kLPUART_RxDataRegFullInterruptEnable);
            LPUART_DisableInterrupts(CELLULAR_UART_BASE, irqMask);
            LPUART_ClearStatusFlags(CELLULAR_UART_BASE, irqMask);
            LPUART_EnableRx(CELLULAR_UART_BASE, false);
        }



@@ 105,10 120,9 @@ namespace bsp
        std::shared_ptr<drivers::DriverDMAMux> dmamux;
        std::shared_ptr<drivers::DriverDMA> dma;
        std::unique_ptr<drivers::DriverDMAHandle> txDMAHandle;
        std::unique_ptr<drivers::DriverDMAHandle> rxDMAHandle;

        static lpuart_edma_handle_t uartDmaHandle;

        static void DMATxCompletedCb(LPUART_Type *base, lpuart_edma_handle_t *handle, status_t status, void *userData);
        static void uartDMACallback(LPUART_Type *base, lpuart_edma_handle_t *handle, status_t status, void *userData);

      public:
        static TaskHandle_t blockedTaskHandle;


@@ 122,6 136,17 @@ namespace bsp
        const static uint32_t CELLULAR_BSP_AP_READY_PIN_ACTIVE_STATE = 1;
        const static uint32_t CELLULAR_BSP_ANTSEL_PIN_A_STATE        = 0;
        const static uint32_t CELLULAR_BSP_ANTSEL_PIN_B_STATE        = 1;

      public:
        static constexpr size_t RXdmaBufferSize = 16;
        static uint8_t RXdmaBuffer[RXdmaBufferSize];
        static ssize_t RXdmaReceivedCount;
        static size_t RXdmaMaxReceivedCount;
        static bool MoveRxDMAtoStreamBuf(size_t nbytes);
        static size_t GetFreeStreamBufferSize();
        static bool StartReceive(size_t nbytes);

        static TaskHandle_t untilReceivedNewHandle;
    };

} // namespace bsp

M module-bsp/board/rt1051/common/irq/irq_gpio.cpp => module-bsp/board/rt1051/common/irq/irq_gpio.cpp +0 -4
@@ 73,10 73,6 @@ namespace bsp
                xHigherPriorityTaskWoken |= cellular::status::statusIRQhandler();
            }

            if (irq_mask & (1 << BSP_CELLULAR_UART_CTS_PIN)) {
                LOG_DEBUG("CELLULAR CTS IRQ!");
            }

            // Clear all IRQs
            GPIO_PortClearInterruptFlags(GPIO1, irq_mask);


M module-bsp/bsp/BoardDefinitions.hpp => module-bsp/bsp/BoardDefinitions.hpp +9 -8
@@ 23,8 23,8 @@ enum class BoardDefinitions
    AUDIOCODEC_I2C            = static_cast<int>(drivers::I2CInstances ::I2C2),
    AUDIOCODEC_DMAMUX         = static_cast<int>(drivers::DMAMuxInstances ::DMAMUX0),
    AUDIOCODEC_DMA            = static_cast<int>(drivers::DMAInstances ::DMA_0),
    AUDIOCODEC_TX_DMA_CHANNEL = 5,
    AUDIOCODEC_RX_DMA_CHANNEL = 6,
    AUDIOCODEC_TX_DMA_CHANNEL = 6,
    AUDIOCODEC_RX_DMA_CHANNEL = 7,
    AUDIOCODEC_IRQ            = 31, // GPIO_B1_15  requires pull-up 10kΩ
    AUDIOCODEC_IRQ_GPIO       = static_cast<int>(drivers::GPIOInstances ::GPIO_2),



@@ 52,12 52,13 @@ enum class BoardDefinitions
    BATTERY_CHARGER_I2C = AUDIOCODEC_I2C,
    BATTERY_CHARGER_GPIO = static_cast<int >(drivers::GPIOInstances ::GPIO_2),
    BATTERY_CHARGER_INOKB_PIN = 12,
    BATTERY_CHARGER_WCINOKB = 13, /// UNUSABLE as WCIN is not connected to the charger !
    BATTERY_CHARGER_INTB_PIN = 14, /// interrupt on battery percentage change
    BATTERY_CHARGER_WCINOKB = 13, // UNUSABLE as WCIN is not connected to the charger !
    BATTERY_CHARGER_INTB_PIN = 14, // interrupt on charger/fuel-gauge event

    CELLULAR_DMA = static_cast<int >(drivers::DMAInstances ::DMA_0),
    CELLULAR_DMAMUX = static_cast<int >(drivers::DMAMuxInstances ::DMAMUX0),
    CELLULAR_TX_DMA_CHANNEL = 4,
    CELLULAR_RX_DMA_CHANNEL = 5,
    CELLULAR_GPIO_1 = static_cast<int >(drivers::GPIOInstances ::GPIO_1),
    CELLULAR_GPIO_2 = static_cast<int >(drivers::GPIOInstances ::GPIO_2),
    CELLULAR_GPIO_3 = static_cast<int >(drivers::GPIOInstances ::GPIO_3),


@@ 68,8 69,8 @@ enum class BoardDefinitions
    CELLULAR_GPIO_2_RESET_PIN = 17,
    CELLULAR_GPIO_2_RI_PIN = 21,
    CELLULAR_GPIO_2_APRDY_PIN = 16,
    CELLULAR_GPIO_2_WAKEUP_PIN = 22, /// GPIO_B1_06, long time no see. Active low, external pull-down 10kΩ
    CELLULAR_GPIO_2_WIRELESS_DISABLE_PIN = 23, /// GPIO_B1_07, pull-up in modem, active low, equiv. AT+CFUN=4, see docs
    CELLULAR_GPIO_2_WAKEUP_PIN = 22, // GPIO_B1_06, long time no see. Active low, external pull-down 10kΩ. docs: 6. Do not pull up WAKEUP_IN, […], pins unless the module starts up sucessfully.
    CELLULAR_GPIO_2_WIRELESS_DISABLE_PIN = 23, // GPIO_B1_07, pull-up in modem, active low, equiv. AT+CFUN=4, see docs
    CELLULAR_GPIO_2_SIM_TRAY_INSERTED_PIN = 11,
    CELLULAR_GPIO_2_NC = 10, // GPIO_B0_10
    CELLULAR_GPIO_2_SIMCARD_PRESENCE_PIN = 9,


@@ 92,8 93,8 @@ enum class BoardDefinitions

    BLUETOOTH_DMA = static_cast<int >(drivers::DMAInstances ::DMA_0),
    BLUETOOTH_DMAMUX = static_cast<int >(drivers::DMAMuxInstances ::DMAMUX0),
    BLUETOOTH_TX_DMA_CHANNEL = 7,
    BLUETOOTH_RX_DMA_CHANNEL = 8,
    BLUETOOTH_TX_DMA_CHANNEL = 8,
    BLUETOOTH_RX_DMA_CHANNEL = 9,

    EMMC_PLL = static_cast<int >(drivers::PLLInstances::PLL2_PFD2),
    EMMC_USDHC_INSTANCE = static_cast<int >(drivers::USDHCInstances::USDHC_2),

M module-cellular/Modem/TS0710/TS0710.cpp => module-cellular/Modem/TS0710/TS0710.cpp +12 -12
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "TS0710.h"


@@ 221,6 221,17 @@ TS0710::ConfState TS0710::ConfProcedure()
        return ConfState::Failure;
    }

    at::AT flowCmd;
    if (hardwareControlFlowEnable) {
        flowCmd = (at::AT::FLOW_CTRL_ON);
    }
    else {
        flowCmd = (at::AT::FLOW_CTRL_OFF);
    }
    if (!parser->cmd(flowCmd)) {
        return ConfState::Failure;
    }

    LOG_INFO("GSM modem info:");
    auto ret = parser->cmd(at::AT::SW_INFO);
    if (ret) {


@@ 234,17 245,6 @@ TS0710::ConfState TS0710::ConfProcedure()
        return ConfState::Failure;
    }

    at::AT flowCmd;
    if (hardwareControlFlowEnable) {
        flowCmd = (at::AT::FLOW_CTRL_ON);
    }
    else {
        flowCmd = (at::AT::FLOW_CTRL_OFF);
    }
    if (!parser->cmd(flowCmd)) {
        return ConfState::Failure;
    }

    auto commands = at::getCommadsSet(at::commadsSet::modemInit);

    for (auto command : commands) {