//-------------------------------------------------------------------------
//  Nucleo ボードの USB コネクタに対応するシリアルポート受送信割込みで
//  複数のキャラクタ受送信をサポ－トするクラス
//
//  2023/01/17, Copyright (c) 2023 MIKAMI, Naoki
//-------------------------------------------------------------------------

#include "SerialRxTxIntr.hpp"

namespace Mikami
{
    // コンストラクタ
    SerialRxTxIntr::SerialRxTxIntr(int maxChar, int baud)
        : pc_(USBTX, USBRX, baud), tx_(pc_), RX_MAX_(maxChar),
          eol_(false), rxBuffer_(""), buffer2_(""), echoOn_(false)
    {
        pc_.format();    // default: 8 bits, nonparity, 1 stop bit
        pc_.attach(callback(this, &SerialRxTxIntr::RxIsr));
    }

    // メッセージの終了であればそのメッセージを保存し true を返す
    bool SerialRxTxIntr::IsEol()
    {
        if (!eol_) return false;

        eol_ = false;
        buffer2_ = rxBuffer_;   // メッセージの保存
        rxBuffer_ = "";         // 受信バッファをクリア
        return true;
    }

    // メッセージの終了を確認してからバッファの内容を取得
    string SerialRxTxIntr::WaitGetBuffer()
    {
        while (!IsEol()) {}
        return GetBuffer();
    }
    // シリアル･ポートの受信割り込みに対する割り込みサービス･ルーチン
    void SerialRxTxIntr::RxIsr()
    {
        unsigned char chr = pc_.getc();
        if (echoOn_)            // エコーバックが有効な場合
        {
            tx_.TxChar(chr);    // エコーバック
            if (chr == '\r') tx_.TxChar('\n');
        }
        // "\r" を受信した場合はメッセージの終了とする
        // "\r" は rxBuffer_ に追加されない
        if (chr == '\r') eol_ = true;
        else             rxBuffer_ += chr;

        // 受信するメッセージの文字数のチェック
        if (rxBuffer_.size() > RX_MAX_)
        {
            char ch[32];
            sprintf(ch, "Exceeded %d characters", RX_MAX_);
            mbed_assert_internal(ch, __FILE__, __LINE__);
        }
    }
}
