

/**
 ******************************************************************************
 *
 * @file        retarget.C
 * @brief       BLE_MG126 retarget c Code. 
 *
 * @par         Project
 *              MG32
 * @version     V1.03
 * @date        2020/04/30
 * @author      Megawin Software Center
 * @copyright   Copyright (c) 2020 MegaWin Technology Co., Ltd.
 *              All rights reserved.
 *
 ******************************************************************************* 
 * @par Disclaimer
 * The Demo software is provided "AS IS" without any warranty, either
 * expressed or implied, including, but not limited to, the implied warranties
 * of merchantability and fitness for a particular purpose. The author will
 * not be liable for any special, incidental, consequential or indirect
 * damages due to loss of data or any other reason.
 * These statements agree with the world wide and local dictated laws about
 * authorship and violence against these laws.
 *******************************************************************************
 *******************************************************************************
 */


#include "BSP.h"
#include "mg_api.h"


#define MAX_SIZE 200    // rxBuf/txBuf data size
static u8 txBuf[MAX_SIZE];     // BLE data to URTx TX buffer. 
static u8 rxBuf[MAX_SIZE];     // URTx RX buffer data to BLE.
static u16 RxCont = 0;  // rxBuf index.
static u8 PosW = 0;     // txBuf transmitted index
static u8 txLen = 0;    // txBuf waiting transmit index

void URT0_IRQHandler(void);
void moduleOutData(u8*data, u8 len);        //api, BLE received data to txBuf   
void CheckComPortInData(void);
void UsrProcCallback(void);//porting api


extern char GetConnectedStatus(void);

//unsigned char ch;

/**
 *******************************************************************************
 * @brief       URT0_IRQ handler
 * @details
 * @return      None
 * @note
 * @par         Example
 * @code
    URT0_IRQHandler();
 * @endcode
 *******************************************************************************
 */
void URT0_IRQHandler(void)
{
    if(URT0->STA.MBIT.RXF)                  // When URTx get data
    {                                       /* URTx receive data to rxBuf */
        rxBuf[RxCont] = URT0->RDAT.B[0];    // Move data to rxBuF
        RxCont++;                           // URTx rxBuf received index
        if(RxCont >= MAX_SIZE)              // When rxBuf received index >= MAX_SIZE (200)
        {
            RxCont = 0;                     // When index == 0
        }
    }
    if (URT0->STA.MBIT.TCF)                 // When URTx trandmit comlete
    {
        if (PosW < txLen)                   // When txBuf transmitted index < txBuf waiting transmit index
        {
                                            /* txBuf data to URTx trnasmit */
            URT0->TDAT.B[0] = txBuf[PosW++];// URTx transmit data. and "txBuf transmitted index + 1"
        }
        else
        {                                   // Clear TCF
            URT0->STA.B[0] = URT_STA_TCF_mask_b0;
        }

        if (PosW >= txLen)                  // When txBuf transmitted index >= txBuf waiting transmit index
        {
            txLen = 0;                      // Clear txBuf waiting transmit index
            PosW = 0;                       // Clear txBuf transmitted index
        }
    }
}


/**
 *******************************************************************************
 * @brief       BLE data updata to txbuf
 * @details
 * @return      None
 * @note
 * @par         Example
 * @code
    moduleOutData();
 * @endcode
 *******************************************************************************
 */
void moduleOutData(u8*data, u8 len)         //api, BLE received data to txBuf   
{
    unsigned char i;

    if ((txLen+len)<MAX_SIZE)               // When txBuf waiting transmit index + updata length < MAX_SIZE (200)
    {
        for (i=0;i<len;i++)                 // Move BLE get data to txBuf[]
        {
            txBuf[txLen+i] = *(data+i);
        }
        txLen += len;                       // txBuf waiting transmit index + update length
    }
}


#define comrxbuf_wr_pos RxCont
static volatile u16 comrxbuf_rd_pos = 0;           /* Add volatile *///init, com rx buffer

/**
 *******************************************************************************
 * @brief       Move rxBuf data to BLE
 * @details
 * @return      None
 * @note
 * @par         Example
 * @code
    CheckComPortInData();
 * @endcode
 *******************************************************************************
 */
void CheckComPortInData(void) 
{
    u16 send;

    if(comrxbuf_wr_pos != comrxbuf_rd_pos)          // When rxBuf index > BLE transmitted index
    {
        if(!GetConnectedStatus())                   // When not Connected
        {
            comrxbuf_rd_pos = comrxbuf_wr_pos;      // Update BLE read index, BLE not transmit data.
        }
        else                                        // When Connected
        {
            if(comrxbuf_wr_pos > comrxbuf_rd_pos)   // When rxBuf waiting move index > BLE transmitted index
            {
                send = sconn_notifydata(rxBuf+comrxbuf_rd_pos, (unsigned char) (comrxbuf_wr_pos - comrxbuf_rd_pos));
                                                    // BLE transmit data and return transmit length.
                comrxbuf_rd_pos += send;            // Updata BLE transmitted index
            }
            else                                    // When rxBuf waiting move index =< BLE transmitted index
            {
                send = sconn_notifydata(rxBuf+comrxbuf_rd_pos, (unsigned char) (MAX_SIZE - comrxbuf_rd_pos));
                                                    // BLE transmit data and return transmit length.
                comrxbuf_rd_pos += send;            // Updata BLE transmitted index
                comrxbuf_rd_pos %= MAX_SIZE;        // Calculate BLE transmitted index.
            }
        }
    }
}


/**
 *******************************************************************************
 * @brief       User Proc Callback
 * @details
 * @return      None
 * @note
 * @par         Example
 * @code
    UsrProcCallback();
 * @endcode
 *******************************************************************************
 */
void UsrProcCallback(void) //porting api
{    
    IWDT_RefreshCounter();                  // Refresh IWDT counter
    
    LED_Flash();                            // Switch LED outpput state (Flashing)
    
    CheckComPortInData();                   // Move rxBuf data to BLE
    
    if ((txLen) && (0 == PosW))             // When URT0 txBuf waiting transmit index != 0
                                            // and transmitted index == 0
    {
        URT0->TDAT.B[0] = txBuf[PosW++];
    }
}
