/*******************************************************************************
 *  気象情報端末
 * 　　main ：キューとセマフォの定義とTC4の割込み処理
 * 　　task1：APとMQTTのサーバへ接続し、完了後サスペンド
 * 　　task2：センサからデータを取得し3種のキューに送信
 * 　　task3：キューからデータ取り出しLCD表示
 * 　　task4：MQTTへセンサデータをパブリッシュ
 * 　　task5：センサと電圧データをSDカードにログ
 * 　　task6：電圧データを計測しキューに送信 
 *******************************************************************************/

// *****************************************************************************
// *****************************************************************************
// Section: Included Files
// *****************************************************************************
// *****************************************************************************

#include <stddef.h>                     // Defines NULL
#include <stdbool.h>                    // Defines true
#include <stdlib.h>                     // Defines EXIT_FAILURE
#include "definitions.h"                // SYS function prototypes

// キューハンドル定義
QueueHandle_t  LCDQueue;
QueueHandle_t  MQTTQueue;
QueueHandle_t  LOGQueue;
// セマフォハンドル定義
SemaphoreHandle_t  ADCSemaphore;
SemaphoreHandle_t  MQTTSemaphore;
// グローバル変数定義
char buff[128];

/*** 関数プロト ***/
void SendStr(const char * str);
bool getResponse(char * word, uint8_t timeout);
void ftostring(int seisu, int shousu, float data, uint8_t *buffer);

/*********************************************
 *　TC4割り込み処理関数
 *　　0.5秒周期でセマフォをGive
 *********************************************/
void TC4_ISR(TC_TIMER_STATUS status, uintptr_t context){
    static portBASE_TYPE HigherTask;
  
    /** セマフォGive **/
    HigherTask = pdFALSE;
    xSemaphoreGiveFromISR(ADCSemaphore, &HigherTask);
}

// *****************************************************************************
// *****************************************************************************
// Section: Main Entry Point
// *****************************************************************************
// *****************************************************************************

int main ( void )
{
    /* Initialize all modules */
    SYS_Initialize ( NULL );

    /** キュー定義 **/
    LCDQueue = xQueueCreate(10, 20);        // 20byte x 10    
    MQTTQueue = xQueueCreate(10, 20);       // 20byte x 10  
    LOGQueue = xQueueCreate(10, 20);        // 20byte x 10  
    /** タイマ4割り込み処理関数定義 **/
    TC4_TimerCallbackRegister(TC4_ISR, (uintptr_t)NULL); 
    /** セマフォ生成 **/
    ADCSemaphore = xSemaphoreCreateBinary();  
    MQTTSemaphore = xSemaphoreCreateBinary();
    /** センサBME280初期化 **/
    bme_init();                             // センサ初期設定
    bme_gettrim();                          // センサ較正値読み出し
    
    TC4_TimerStart();                       // 電圧計測開始
    
    /****** メインループ *******************/
    while ( true )
    {
        /* Maintain state machines of all polled MPLAB Harmony modules. */
        SYS_Tasks ( );
    }

    /* Execution should not come here during normal operation */

    return ( EXIT_FAILURE );
}
/********************************
 * WiFi文字列送信関数
 *******************************/
void SendStr(const char * str){
    while(*str != 0){                           // 文字列最後まで繰り返し
        SERCOM5_USART_Write((char *)str, 1);    // 送信実行
        str++;
    }
}
/************************************
* ESP応答待ち
*************************************/
bool  getResponse(char * word, uint8_t timeout){
    char flag, a=0;
    int j;
    
    for(j=0;j<128;j++)                                  // 受信バッファリセット
        buff[j] = 0x20;
    j = 0;    
    flag = 0;                                           // 文字列発見フラグリセット
    TC5_Timer16bitPeriodSet(3906*timeout);              // タイマ3秒数セット
    TC5_Timer16bitCounterSet(0);
    TC5_TimerStart();                                   // タイマ5スタート
    /******/
    while(TC5_TimerPeriodHasExpired() == false){        // タイムアップまで繰り返し
        while(SERCOM5_USART_ReceiverIsReady() == true){ // 受信データありの場合
            a = SERCOM5_USART_ReadByte();               // 受信データ取得
            SERCOM3_USART_WriteByte(a);
            if(a == '\0') continue;                     // 0x00は省く
            buff[j] = a;                                // 受信バッファに追加
            if(j<126)                                   // 126文字以上は無視
                j++;                                    // 次のバッファへ
            buff[j] = 0;                                // 文字列終わりのフラグ
        }
        if(strstr(buff, word) != 0){                    // 文字列検索
            flag = 1;                                   // 文字列発見フラグオン
            TC5_TimerStop();                            // タイマ1停止
            break;                                      // 強制終了
        }
    }
    if(flag == 1)
        return true;                                    // 文字列が見つかった場合
    else
        return false;                                   // タイムアップの場合        
}

/***********************************
* Floatから文字列へ変換
* 合計有効桁は8桁以下とすること
***********************************/
void ftostring(int seisu, int shousu, float data, uint8_t *buffer)
{
    int i;
    long dumy;

    if(shousu != 0)                                 //小数部桁ありか
        buffer += seisu+shousu+1;                   //全体桁数＋小数点
    else                                            //小数部桁なしのとき
        buffer += seisu + shousu;                   //全体桁数のみ
    buffer--;                                       //配列ポインタ-1
    for(i=0; i<shousu; i++)                         //小数部を整数に変換
        data = data * 10;                           //１０倍
    /// dumyがオーバーフローすると変換不可(８桁が限界)
    dumy = (long) (data + 0.5);                     //四捨五入して整数に変換
    for(i=shousu; i>0; i--)	{                       //小数桁数分繰り返し
        *buffer =(unsigned char)(dumy % 10)+'0';    //数値を文字に変換格納
        buffer--;                                   //格納場所下位から上位へ
        dumy /= 10;                                 //次の桁へ
    }
    if(shousu != 0) {                               //小数桁0なら小数点なし
        *buffer = '.';                              //小数点を格納
        buffer--;                                   //ポインタ-1
    }
    for(i=seisu; i>0; i--) {                        //整数桁分繰り返し
        *buffer = (unsigned char)(dumy % 10)+'0';   //数値を文字に変換格納
        buffer--;                                   //ポインタ-1
        dumy /= 10;                                 //次の桁へ
    }
}


/*******************************************************************************
 End of File
*/

