#include <stdint.h>
#include <stdbool.h>



#include "../mcc_generated_files/pin_manager.h"
#include "userSPI.h"
#include "userComm.h"
#include "userGEN.h"
#include "misc.h"


volatile static bool commMsgReceived = false;
static bool commGetResponse = false;

volatile static uint8_t rxBuff[20];
volatile static uint8_t txBuff[20];

static uint32_t dataFreqSet[100];
static volatile bool dataSent = false;
static bool requestToCommScheduled = false;
volatile static bool readyToAsk = false;


volatile static uint8_t accData[300];
static uint16_t accDataStart;
static uint16_t accDataEnd;

static bool firstInRow = true;

void GEN_CommInit(void)
{
    uint8_t i;
    for(i=0;i<16;i++)
    {
        txBuff[i] = 0xAA;
    }
    //DMA_Initialize((uint8_t*)&rxBuff[0],(uint8_t*)&txBuff[0]);
    DRV_SPIInit((uint8_t*)&rxBuff[0],(uint8_t*)&txBuff[0]);
    DRV_SPI2Init((uint8_t*)&accData[0],(uint8_t*)&txBuff[0],240);
    
}

static uint8_t accDataCnt;
void SPI2_CallbackAcc(uint16_t endIndex)
{
    accDataEnd = endIndex;
    GEN_SearchForMax(&accData[endIndex - 24], 24);
    //check for maximum
    accDataCnt++;
    if (accDataCnt >= 23 )
    {
        GEN_GetAmplitudeAndRegulate();
    }

    
    
    if (accDataEnd > 100)
    {
        
        Nop();
    }

    
}

void GEN_ResetAccDataStart(void)
{
    accDataStart = 0;
    firstInRow = true;
}


void DMA0_CallBack(void)
{
    commMsgReceived = true;

    dataSent = true;
}


void GEN_ReadyToAsk(void)
{
    readyToAsk = true;
    LED9_Toggle();
}


static uint8_t spiCnt;

void GEN_CommTask(void )
{
    uint16_t tmpAux;
    
    if ((commMsgReceived == false) && (readyToAsk == true) && (commGetResponse == false ))
    {
        if ((SPI_CS_GetValue() == 1) && (requestToCommScheduled == false) )
        {
            readyToAsk = false;
            requestToCommScheduled = true;
            SPI_READY_Toggle();
        }
    }

    
    if ((commMsgReceived == false) && (((GEN_STATUS)GEN_GetStatusByte()).genReady == true) && (commGetResponse == true))
    {
        if ((SPI_CS_GetValue() == 1) && (requestToCommScheduled == false))
        {
            //request SPI comm
            commGetResponse = false;
            requestToCommScheduled = true;
            SPI_READY_Toggle();
            //LED10_SetHigh();
        }
    }

    
    if (commMsgReceived == true)
    {
        //LED10_Toggle();
        
        //GEN_OpNack();
        switch(rxBuff[0])
        {
            case GEN_STOP:
            {
                if (rxBuff[1] == 'S')
                {
                    GEN_Stop();
                }
                commGetResponse = true;
                GEN_OpAck();
            }break;

            case GEN_START:
            {
                if (rxBuff[1] == 'R') 
                {
                    GEN_Start();
                }
                commGetResponse = true;
                GEN_OpAck();
            }break;

            case GEN_SET_FREQ:
            {
                uint32_t freq;
                freq = ((uint32_t)rxBuff[4] << 24) + ((uint32_t)rxBuff[3] << 16) + ((uint32_t)rxBuff[2] << 8) + ((uint32_t)rxBuff[1]);
                GEN_SetNewFrequency(freq);
                commGetResponse = true;
                GEN_OpAck();
            }break;

            case GEN_SET_SCALE:
            {
                uint16_t scale;
                scale = ((uint16_t)rxBuff[2] << 8) + rxBuff[1];
                GEN_SetNewScale(scale);
                commGetResponse = true;
                GEN_OpAck();
                
            }break;
            
            case GEN_SET_OFFSET:
            {
                uint16_t offset;
                offset = ((uint16_t)rxBuff[2] << 8) + rxBuff[1];
                GEN_SetNewOffset(offset);
                commGetResponse = true;
                GEN_OpAck();
                
            }break;
            
            case GEN_SET_MM:
            {
                uint32_t um;
                um = ((uint32_t)rxBuff[4] << 24) + ((uint32_t)rxBuff[3] << 16) + ((uint32_t)rxBuff[2] << 8) + ((uint32_t)rxBuff[1]);
                GEN_SetAmplitudeUm(um);
                GEN_UmRegulationOn(true);
                commGetResponse = true;
                GEN_OpAck();
                
                
            }break;

            case GEN_SET_MODE:
            {
                if (rxBuff[1] == 0)
                {
                    GEN_SetMode(GEN_MODE_NORMAL);
                }else{
                    GEN_SetMode(GEN_MODE_HALFSIN);
                }

            }break;

            //default:
            case GEN_SET_PROGRAM:
            {
                uint16_t index;
                uint8_t localBuffIndex = 0;
                index = ((uint16_t)rxBuff[2] << 8) + rxBuff[1];
                
                dataFreqSet[localBuffIndex] = ((uint32_t)rxBuff[6] << 24) + ((uint32_t)rxBuff[5] << 16) + ((uint32_t)rxBuff[4] << 8) + ((uint32_t)rxBuff[3]);
                localBuffIndex++;
                dataFreqSet[localBuffIndex] = ((uint32_t)rxBuff[10] << 24) + ((uint32_t)rxBuff[9] << 16) + ((uint32_t)rxBuff[8] << 8) + ((uint32_t)rxBuff[7]);
                localBuffIndex++;
                dataFreqSet[localBuffIndex] = ((uint32_t)rxBuff[14] << 24) + ((uint32_t)rxBuff[13] << 16) + ((uint32_t)rxBuff[12] << 8) + ((uint32_t)rxBuff[11]);

                //start calculate
                GEN_OrderJob(3,index,&dataFreqSet[0]);
                commGetResponse = true;
                GEN_OpAck();
            }break;
            
            case GEN_GET_STATUS:
            {
                commGetResponse = false;
                requestToCommScheduled = false;
                
            }break;

            default:
            break;
        }

        commMsgReceived = false;
  
    }else
    
        if (SPI_CS_GetValue() == 1)
        {
            if (accDataEnd != accDataStart)
            {

                    if(ScheduleAccData(&accData[accDataStart], 24) == true)
                    {
                        accDataStart += 24;
                        if (accDataStart >= 240)
                        {
                            accDataStart = 0;
                        }
                        
                        if (firstInRow == true)
                        {
                            firstInRow = false;
                            //LED8_Toggle();
                            commGetResponse = true;
                        }

                    }
                                            
            
            }else{
                firstInRow = true;
            }
        }

    
}