

/**
 ******************************************************************************
 *
 * @file        retarget.C
 * @brief       BLE_MG126 retarget c Code. 
 *
 * @par         Project
 *              MG32x02z
 * @version     V1.04
 * @date        2022/09/26
 * @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.
 *******************************************************************************
 *******************************************************************************
 */

/* Includes ------------------------------------------------------------------*/
#include "mg_api.h"
#include "MG0404A_BSP.h"
#include "UserEvent.h"

/* Wizard menu ---------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
uint8_t BleRxBuf[BLE_RETARGET_MAX_SIZE - 40];    // BLE Rx Data Buffer to URTx TX.
volatile uint8_t BleRxBufInCount = 0;            // RxBuf Receive index.
volatile uint8_t BleRxBufOutCount = 0;           // RxBuf Transmitted index.


uint8_t BleTxBuf[BLE_RETARGET_MAX_SIZE];         // BLE Tx Data Buffer from URTx RX.
volatile uint8_t BleTxBufInCount = 0;            // TxBuf Receive index.
volatile uint8_t BleTxBufOutCount = 0;           // TxBuf Transmitted Index.

/* Private function prototypes -----------------------------------------------*/
void LED_Flash(void);
unsigned int GetSysTickCount(void);
char IsIrqEnabled(void);
void moduleOutData(uint8_t*data, uint8_t len);
void CheckComPortInData(void);
void UsrProcCallback(void);
unsigned char SPI_WriteBuf(unsigned char reg, unsigned char const *pBuf, unsigned char len);
unsigned char SPI_ReadBuf(unsigned char reg, unsigned char *pBuf, unsigned char len);

void SysClk8to48(void);
void SysClk48to8(void);
void DisableEnvINT(void);
void EnableEnvINT(void);
void UpdateLEDValueAll(void);
void McuGotoSleepAndWakeup(void);
unsigned char aes_encrypt_HW(uint8_t *_data, uint8_t *_key);

/* Exported variables --------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
extern char GetConnectedStatus(void);

/* External vairables --------------------------------------------------------*/
extern uint32_t SystemCoreClock;


/**
 *******************************************************************************
 * @brief       LED module initial
 * @details
 * @return      None
 * @note
 * @par         Example
 * @code
    LED_Flash();
 * @endcode
 *******************************************************************************
 */
void LED_Flash(void)
{
    BLE_LED ^= 0x1;
}

/**
 *******************************************************************************
 * @brief       Get sys tick count
 * @details
 * @return      None
 * @note
 * @par         Example
 * @code
    GetSysTickCount();
 * @endcode
 *******************************************************************************
 */
unsigned int GetSysTickCount(void) //porting api
{
    return MID_GetTick();
}

/**
 *******************************************************************************
 * @brief       IS IRQ Enable
 * @details
 * @return      None
 * @note
 * @par         Example
 * @code
    IsIrqEnabled();
 * @endcode
 *******************************************************************************
 */
char IsIrqEnabled(void) //porting api
{
    return !(BLE_IRQ);
}

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

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

/**
 *******************************************************************************
 * @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 */
//        BleTxBuf[BleTxBuffInCount] = URT0->RDAT.B[0];    // Move data to rxBuF
//        BleTxBuffInCount++;                           // URTx rxBuf received index
//        if(BleTxBuffInCount >= BLE_RETARGET_MAX_SIZE) // When rxBuf received index >= MAX_SIZE (200)
//        {
//            BleTxBuffInCount = 0;                     // When index == 0
//        }
//    }
//    if (URT0->STA.MBIT.TCF)                 // When URTx trandmit comlete
//    {
//        if (BleRxBuffOutCount < BleRxBuffInCount)                   // When txBuf transmitted index < txBuf waiting transmit index
//        {
//                                            /* txBuf data to URTx trnasmit */
//            URT0->TDAT.B[0] = BleRxBuf[BleRxBuffOutCount ++];// URTx transmit data. and "txBuf transmitted index + 1"
//        }
//        else
//        {                                   // Clear TCF
//            URT0->STA.B[0] = URT_STA_TCF_mask_b0;
//        }

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

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

    if(BleTxBufInCount != BleTxBufOutCount)                   // When rxBuf index > BLE transmitted index
    {
        if(!GetConnectedStatus())                             // When not Connected
        {
            BleTxBufOutCount = BleTxBufInCount;               // Update BLE read index, BLE not transmit data.
        }
        else                                                  // When Connected
        {
            if(BleTxBufInCount > BleTxBufOutCount)            // When rxBuf waiting move index > BLE transmitted index
            {
                send = sconn_notifydata(BleTxBuf + BleTxBufOutCount, BleTxBufInCount - BleTxBufOutCount);
                                                              // BLE transmit data and return transmit length.
                BleTxBufOutCount += send;                     // Updata BLE transmitted index
            }                                                 
            else                                              // When rxBuf waiting move index =< BLE transmitted index
            {
                send = sconn_notifydata(BleTxBuf + BleTxBufOutCount, BLE_RETARGET_MAX_SIZE - BleTxBufOutCount);
                                                              // BLE transmit data and return transmit length.
                BleTxBufOutCount += send;                     // Updata BLE transmitted index
                BleTxBufOutCount %= BLE_RETARGET_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 ((BleTxBuffInCount) && (0 == BleRxBuffOutCount))         // When URT0 txBuf waiting transmit index != 0
//                                                        // and transmitted index == 0
//    {
//        URT0->TDAT.B[0] = BleRxBuf[BleRxBuffOutCount++];
//    }
}

/**
 *******************************************************************************
 * @brief       SPI write buffer
 * @details  
 * @param[in]   reg: Command
 * @param[in]   *pBuf: Write buffer index
 * @param[in]   len: Data length
 *  @arg\b          0~255
 * @return      DRV_Return
 *  @arg\b          0
 * @note
 * @par         Example
 * @code
    SPI_WriteBuf(CMD, &TXBuf, 128);
 * @endcode
 *******************************************************************************
 */
unsigned char SPI_WriteBuf(unsigned char reg, unsigned char const *pBuf, unsigned char len)
{
    volatile uint8_t i=0,j=0;               /* volatile */

//    uint8_t ch;
    uint8_t Temp8;
    uint16_t Temp16;
    uint32_t Temp24;
    uint32_t Temp32;

    BLE_CSN = 0;                                                                       // NSS = 0

    BLE_SPI->TDAT.B[0] = reg;                                                          // Write 1 byte

    for (i=len;i>3;i-=4)
    {                                                                                  // Write 4 bytes
        Temp32 = ((uint32_t)*(pBuf+j)) | \
                  (uint32_t)(*(pBuf+j+1)<<8) | \
                  (uint32_t)(*(pBuf+j+2)<<16) | \
                  (uint32_t)(*(pBuf+j+3)<<24);
        j+=4;
        BLE_SPI->TDAT.W = Temp32;
        while((BLE_SPI->STA.B[0] & SPI_STA_TXF_mask_b0) == 0);                         // Wait TDAT data move to TX shadow buffer
    }

    for (;i>2;i-=3)
    {                                                                                  // Write 3 bytes
        Temp24 = ((uint32_t)*(pBuf+j)) | \
                  (uint32_t)(*(pBuf+j+1)<<8) | \
                  (uint32_t)(*(pBuf+j+2)<<16);
        j+=3;
        BLE_SPI->TDAT3.W = Temp24;
        while((BLE_SPI->STA.B[0] & SPI_STA_TXF_mask_b0) == 0);                         // Wait TDAT data move to TX shadow buffer
    }

    for (;i>1;i-=2)
    {                                                                                  // Write 2 bytes
        Temp16 = ((uint16_t)*(pBuf+j)) | (uint16_t)(*(pBuf+j+1)<<8);
        j+=2;                                                                          // Index parameter + 2
        BLE_SPI->TDAT.H[0] = Temp16;                                                   // Write 2 bytes to TX
        while((BLE_SPI->STA.B[0] & SPI_STA_TXF_mask_b0) == 0);                         // Wait TDAT data move to TX shadow buffer
    }

    for (;i>0;i--)
    {
        Temp8 = *(pBuf+j);                                                             // Write 1 byte
        j++;
        BLE_SPI->TDAT.B[0] = Temp8;
        while((BLE_SPI->STA.B[0] & SPI_STA_TXF_mask_b0) == 0);                         // Wait TDAT data move to TX shadow buffer
    }                                                                                  
                                                                                       
    if(&BLE_SPI->STA.W == &SPI0->STA.W)                                                // When BLE module used SPI0
    {                                                                                  
        while((BLE_SPI->STA.B[0] & SPI_STA_TCF_mask_b0) == 0);                         // Wait TX data transmit complete
        BLE_SPI->CR1.B[0] = SPI_CR1_RDAT_CLR_mask_b0;                                  // Clear RX buffe data
        BLE_SPI->STA.H[0] = SPI_ALLF;                                                  // Clear SPI all flag
    }                                                                                  
    else                                                                                  // When BLE moudle used URTx
    {                                                                                  
        while((BLE_SPI->STA.B[0] & URT_STA_TCF_mask_b0) == 0);                         // Wait TX data transmit complete
        BLE_SPI->CR4.B[0] = URT_CR4_RDAT_CLR_mask_b0;                                  // Clear RX buffe data
        BLE_SPI->STA.W = URT_IT_Mask;                                                  // Clear URTx all flag
    }

    BLE_CSN = 1;                        // NSS = 1
    return 0;
}

/**
 *******************************************************************************
 * @brief       SPI Read buffer
 * @details  
 * @param[in]   reg: Command
 * @param[in]   *pBuf: Read buffer index
 * @param[in]   len: Data length
 *  @arg\b          0~255
 * @return      DRV_Return
 *  @arg\b          0
 * @note
 * @par         Example
 * @code
    SPI_ReadBuf(CMD, &RXBuf, 128);
 * @endcode
 *******************************************************************************
 */
unsigned char SPI_ReadBuf(unsigned char reg, unsigned char *pBuf, unsigned char len)
{
    volatile unsigned char i=0;                 /* volatile */

    BLE_CSN = 0;                                                    // NSS = 0

    BLE_SPI->TDAT.B[0] = reg;                                    // Write 1 byte

    if(SystemCoreClock <= 12000000)                                // When CK_AHB <= 12MHz
    {
        BLE_SPI->TDAT.B[0] = 0xff;                                   // Write 1 byt 
    }

    while((BLE_SPI->STA.B[0] & SPI_STA_RXF_mask_b0) == 0);       // Wait RDAT not empty
    BLE_SPI->RDAT.B[0];                                          // Clear RDAT

    for (i=0;i<len;i++)                                             // Waiting  
    {
        BLE_SPI->TDAT.B[0] = 0xff;                               // Write 1 byt
        while((BLE_SPI->STA.B[0] & SPI_STA_RXF_mask_b0) == 0);   // Wait RDAT not empty
        *(pBuf+i) = BLE_SPI->RDAT.B[0];                          // Read data
    }
       /*wait tCF transm complete*/
    BLE_CSN = 1;                                                    // NSS = 1

    if(&BLE_SPI->STA.W == &SPI0->STA.W)                          // When BLE module used SPI0
    {
        BLE_SPI->CR1.B[0] = SPI_CR1_RDAT_CLR_mask_b0;            // Clear RX buffe data
    }
    else
    {
        BLE_SPI->CR4.B[0] = URT_CR4_RDAT_CLR_mask_b0;            // Clear RX buffe data
    }
    return 0;
}

//////DO NOT REMOVE, used in ble lib///////
void SysClk8to48(void)
{
}

void SysClk48to8(void)
{
}

void DisableEnvINT(void)
{
}

void EnableEnvINT(void)
{
}

void UpdateLEDValueAll(void)
{
}

void McuGotoSleepAndWakeup(void)
{
}

unsigned char aes_encrypt_HW(uint8_t *_data, uint8_t *_key)
{
    ((void)(_data));
    ((void)(_key));
    
    return 0; //Hardware AES not supported
}



