#include "project_config.h"
 


//#define EXAMPLE_SPI_BUF_LEN             (256UL) 
uint8 u8TxSPIBuf[SPI_BUF_LEN] = {0};
uint8 u8RxSPIBuf[SPI_BUF_LEN] = {0};
uint16 SPI_SEND_INDEX = 5566;

__IO uint16_t txflag_od = 0, rxflag_od = 0;
__IO uint16_t u16TxIndex = 0U, u16RxIndex = 0U;
void SPI_TransCompleteCallback(void);

SemaphoreHandle_t spi_communication_decode = NULL;
/*******************************************************************************
 * Function implementation - global ('extern') and local ('static')
 ******************************************************************************/
/**
 * @brief  SPI transmit complete callback.
 * @param  None
 * @retval None
 */


/**
 * @brief  SPI receive complete callback.
 * @param  None
 * @retval None
 */
static void SPI_ReceiveCompleteCallback(void)
{
    u8RxSPIBuf[u16RxIndex++] = (char)SPI_ReadData(MPU_SPI_UNIT);		
		if(u16RxIndex >= 256)
		{
				u16RxIndex = 0;		
				xSemaphoreGiveFromISR(spi_communication_decode, NULL);
		}

}



/**
 * @brief  SPI configurate.
 * @param  None
 * @retval None
 */

 
void spi_mpu_init(void)
{
    stc_spi_init_t stcSpiInit;
    stc_irq_signin_config_t stcIrqSignConfig;
	
	  /* Configure Port */
		//GPIO_SetFunc(MPU_SPI_CS_PORT,  MPU_SPI_CS_PIN, MPU_SPI_CS_PIN_FUNC);
    GPIO_SetFunc(MPU_SPI_SCK_PORT, MPU_SPI_SCK_PIN, MPU_SPI_SCK_PIN_FUNC);
    GPIO_SetFunc(MPU_SPI_MOSI_PORT, MPU_SPI_MOSI_PIN, MPU_SPI_MOSI_PIN_FUNC);
    GPIO_SetFunc(MPU_SPI_MISO_PORT, MPU_SPI_MISO_PIN, MPU_SPI_MISO_PIN_FUNC);

    /* Configuration SPI */
    FCG_Fcg1PeriphClockCmd(MPU_SPI_PERIPH_CLK, ENABLE);
    SPI_StructInit(&stcSpiInit);
    stcSpiInit.u32WireMode          = SPI_3_WIRE;
    stcSpiInit.u32TransMode         = SPI_FULL_DUPLEX;
    stcSpiInit.u32MasterSlave       = SPI_SLAVE;
    stcSpiInit.u32Parity            = SPI_PARITY_INVD;
    stcSpiInit.u32SpiMode           = SPI_MD_3;
    stcSpiInit.u32BaudRatePrescaler = SPI_BR_CLK_DIV40;
    stcSpiInit.u32DataBits          = SPI_DATA_SIZE_8BIT;
    stcSpiInit.u32FirstBit          = SPI_FIRST_MSB;
    stcSpiInit.u32FrameLevel        = SPI_1_FRAME;
    (void)SPI_Init(MPU_SPI_UNIT, &stcSpiInit);
		
		SPI_IntCmd(MPU_SPI_UNIT,SPI_INT_RX_BUF_FULL, ENABLE);
  	SPI_IntCmd(MPU_SPI_UNIT,SPI_INT_TX_BUF_EMPTY, ENABLE);
		
    stcIrqSignConfig.enIntSrc    = INT_SRC_SPI3_SPRI;
    stcIrqSignConfig.enIRQn      = INT007_IRQn;
    stcIrqSignConfig.pfnCallback = &SPI_ReceiveCompleteCallback;
    (void)INTC_IrqSignIn(&stcIrqSignConfig);
    NVIC_ClearPendingIRQ(stcIrqSignConfig.enIRQn);
    NVIC_SetPriority(stcIrqSignConfig.enIRQn, DDL_IRQ_PRIO_DEFAULT - 1);
    NVIC_EnableIRQ(stcIrqSignConfig.enIRQn);		
			
    stcIrqSignConfig.enIntSrc    = INT_SRC_SPI3_SPTI;
    stcIrqSignConfig.enIRQn      = INT008_IRQn;
    stcIrqSignConfig.pfnCallback = &SPI_TransCompleteCallback;
    (void)INTC_IrqSignIn(&stcIrqSignConfig);
    NVIC_ClearPendingIRQ(stcIrqSignConfig.enIRQn);
    NVIC_SetPriority(stcIrqSignConfig.enIRQn, DDL_IRQ_PRIO_DEFAULT - 1);
    NVIC_EnableIRQ(stcIrqSignConfig.enIRQn);					
				
		SPI_Cmd(MPU_SPI_UNIT, ENABLE); 
}

void DMA_TransCompleteCallback(void);

static void DMA_ReceiveCallback(void)
{
    //enRxCompleteFlag = SET;
    DMA_ClearTransCompleteStatus(DMA_UNIT, DMA_RX_INT_CH);
    //DMA_SetSrcAddr(DMA_UNIT, DMA_TX_CH, (uint32_t)(&u8TxSPIBuf[0]));
   // DMA_SetTransCount(DMA_UNIT, DMA_TX_CH, SPI_BUF_LEN);
    DMA_SetDestAddr(DMA_UNIT, DMA_RX_CH, (uint32_t)(&u8RxSPIBuf[0]));
    DMA_SetTransCount(DMA_UNIT, DMA_RX_CH, SPI_BUF_LEN);
    /* Enable DMA channel */
    //DMA_ChCmd(DMA_UNIT, DMA_TX_CH, ENABLE);
    DMA_ChCmd(DMA_UNIT, DMA_RX_CH, ENABLE);
}

static void SPI_IDLECallback(void)
{
	__nop();
    //enRxCompleteFlag = SET;
    //DMA_ClearTransCompleteStatus(DMA_UNIT, DMA_RX_INT_CH);
}

void spi_mpu_init_hc(void)
{
    stc_spi_init_t stcSpiInit;
    stc_dma_init_t stcDmaInit;
    stc_irq_signin_config_t stcIrqSignConfig;
    /* Configure Port */
		//GPIO_SetFunc(MPU_SPI_CS_PORT,  MPU_SPI_CS_PIN, MPU_SPI_CS_PIN_FUNC);
    GPIO_SetFunc(MPU_SPI_SCK_PORT, MPU_SPI_SCK_PIN, MPU_SPI_SCK_PIN_FUNC);
    GPIO_SetFunc(MPU_SPI_MOSI_PORT, MPU_SPI_MOSI_PIN, MPU_SPI_MOSI_PIN_FUNC);
    GPIO_SetFunc(MPU_SPI_MISO_PORT, MPU_SPI_MISO_PIN, MPU_SPI_MISO_PIN_FUNC);
	    /* Configuration SPI */
    FCG_Fcg1PeriphClockCmd(MPU_SPI_PERIPH_CLK, ENABLE);
    SPI_StructInit(&stcSpiInit);
	
	  stcSpiInit.u32WireMode          = SPI_3_WIRE;
    stcSpiInit.u32TransMode         = SPI_FULL_DUPLEX;
    stcSpiInit.u32MasterSlave       = SPI_SLAVE;
    stcSpiInit.u32Parity            = SPI_PARITY_INVD;
    stcSpiInit.u32SpiMode           = SPI_MD_3;
    stcSpiInit.u32BaudRatePrescaler = SPI_BR_CLK_DIV40;
    stcSpiInit.u32DataBits          = SPI_DATA_SIZE_8BIT;
    stcSpiInit.u32FirstBit          = SPI_FIRST_MSB;
		stcSpiInit.u32FrameLevel        = SPI_1_FRAME;
		(void)SPI_Init(MPU_SPI_UNIT, &stcSpiInit);
		//RX
		/*SPI_IntCmd(MPU_SPI_UNIT,SPI_INT_RX_BUF_FULL, ENABLE);
    stcIrqSignConfig.enIntSrc    = INT_SRC_SPI3_SPRI;
    stcIrqSignConfig.enIRQn      = INT008_IRQn;
    stcIrqSignConfig.pfnCallback = &SPI_ReceiveCompleteCallback;
    (void)INTC_IrqSignIn(&stcIrqSignConfig);
    NVIC_ClearPendingIRQ(stcIrqSignConfig.enIRQn);
    NVIC_SetPriority(stcIrqSignConfig.enIRQn, DDL_IRQ_PRIO_DEFAULT - 1);
    NVIC_EnableIRQ(stcIrqSignConfig.enIRQn);					*/
		//TX
		SPI_IntCmd(MPU_SPI_UNIT,SPI_INT_TX_BUF_EMPTY, ENABLE);
    stcIrqSignConfig.enIntSrc    = INT_SRC_SPI3_SPTI;
    stcIrqSignConfig.enIRQn      = INT007_IRQn;
    stcIrqSignConfig.pfnCallback = &SPI_TransCompleteCallback;
    (void)INTC_IrqSignIn(&stcIrqSignConfig);
    NVIC_ClearPendingIRQ(stcIrqSignConfig.enIRQn);
    NVIC_SetPriority(stcIrqSignConfig.enIRQn, 0);
    NVIC_EnableIRQ(stcIrqSignConfig.enIRQn);	
		
		SPI_Cmd(MPU_SPI_UNIT, ENABLE); 
		
		//DMA
		FCG_Fcg0PeriphClockCmd(DMA_CLK, ENABLE);
		(void)DMA_StructInit(&stcDmaInit);
		stcDmaInit.u32IntEn       = DMA_INT_ENABLE;
    stcDmaInit.u32BlockSize  = 1UL;
    stcDmaInit.u32TransCount = 256;
    stcDmaInit.u32DataWidth  = DMA_DATAWIDTH_8BIT;
		
		/* Configure TX */
 /*   stcDmaInit.u32SrcAddrInc  = DMA_SRC_ADDR_INC;
    stcDmaInit.u32DestAddrInc = DMA_DEST_ADDR_FIX;
    stcDmaInit.u32SrcAddr     = (uint32_t)(&u8TxSPIBuf[0]);
    stcDmaInit.u32DestAddr    = (uint32_t)(&MPU_SPI_UNIT->DR);
    if (LL_OK != DMA_Init(DMA_UNIT, DMA_TX_CH, &stcDmaInit)) {
        for (;;) {
        }
    }
    AOS_SetTriggerEventSrc(DMA_TX_TRIG_CH, SPI_TX_EVT_SRC);*/
		
		/* Configure RX */
    //stcDmaInit.u32IntEn       = DMA_INT_ENABLE;
    stcDmaInit.u32SrcAddrInc  = DMA_SRC_ADDR_FIX;
    stcDmaInit.u32DestAddrInc = DMA_DEST_ADDR_INC;
    stcDmaInit.u32SrcAddr     = (uint32_t)(&MPU_SPI_UNIT->DR);
    stcDmaInit.u32DestAddr    = (uint32_t)(&u8RxSPIBuf[0]);
    if (LL_OK != DMA_Init(DMA_UNIT, DMA_RX_CH, &stcDmaInit)) {
        for (;;) {
        }
    }
		AOS_SetTriggerEventSrc(DMA_RX_TRIG_CH, SPI_RX_EVT_SRC);
				
		/* DMA receive NVIC configure */
    stcIrqSignConfig.enIntSrc    = INT_SRC_DMA1_TC1;
    stcIrqSignConfig.enIRQn      = INT006_IRQn;
    stcIrqSignConfig.pfnCallback = &DMA_TransCompleteCallback;
    (void)INTC_IrqSignIn(&stcIrqSignConfig);
    NVIC_ClearPendingIRQ(stcIrqSignConfig.enIRQn);
    NVIC_SetPriority(stcIrqSignConfig.enIRQn, DDL_IRQ_PRIO_DEFAULT);
    NVIC_EnableIRQ(stcIrqSignConfig.enIRQn);
		
		DMA_Cmd(DMA_UNIT, ENABLE);
		//DMA_ChCmd(DMA_UNIT, DMA_TX_CH, ENABLE);
		DMA_ChCmd(DMA_UNIT, DMA_RX_CH, ENABLE);
}



static void DMA_ReloadConfig(void)
{
    DMA_SetSrcAddr(DMA_UNIT, DMA_TX_CH, (uint32_t)(&u8TxSPIBuf[0]));
    DMA_SetTransCount(DMA_UNIT, DMA_TX_CH, 256);
  //  DMA_SetDestAddr(DMA_UNIT, DMA_RX_CH, (uint32_t)(&u8RxSPIBuf[0]));
  //  DMA_SetTransCount(DMA_UNIT, DMA_RX_CH, 36);
    /* Enable DMA channel */
    DMA_ChCmd(DMA_UNIT, DMA_TX_CH, ENABLE);
    //DMA_ChCmd(DMA_UNIT, DMA_RX_CH, ENABLE);
}

 

#include "FreeRTOS.h"
#include "task.h"
uint8_t data_decode_mpu(uint8_t *input_data, uint32_t input_data_len, uint8_t* output, uint32_t* output_data_len);

void SPI_TransCompleteCallback(void)
{
	if(SPI_SEND_INDEX >= FRAME_MAX_LENGTH)
		SPI_WriteData(MPU_SPI_UNIT, 0XBB);
	else /**/
		SPI_WriteData(MPU_SPI_UNIT, u8TxSPIBuf[txflag_od + SPI_SEND_INDEX++]);
}
void DMA_TransCompleteCallback(void)
{

		rxflag_od = rxflag_od == FRAME_MAX_LENGTH ? 0 : FRAME_MAX_LENGTH;
		DMA_ClearTransCompleteStatus(DMA_UNIT, DMA_RX_INT_CH);
		DMA_SetDestAddr(DMA_UNIT, DMA_RX_CH, (uint32_t)(&u8RxSPIBuf[rxflag_od]));
		DMA_SetTransCount(DMA_UNIT, DMA_RX_CH, FRAME_MAX_LENGTH);			
    DMA_ChCmd(DMA_UNIT, DMA_RX_CH, ENABLE);
		xSemaphoreGiveFromISR(spi_communication_decode, NULL);
}

void ec600g_task(void *argv)
{
	//SPI_ClearStatus(MPU_SPI_UNIT, SPI_FLAG_MD_FAULT | SPI_FLAG_UNDERLOAD);
	//SPI_WriteData(MPU_SPI_UNIT, 0);
	
	spi_communication_decode = xSemaphoreCreateBinary();
	uint32_t output_data_len_hc = 0;
	
	while(1)
	{ 
		
		xSemaphoreTake(spi_communication_decode, portMAX_DELAY);
		//vTaskDelay(10);
		txflag_od = 0 == txflag_od ? FRAME_MAX_LENGTH : 0;
		memset(u8TxSPIBuf + txflag_od, 0, FRAME_MAX_LENGTH);
		output_data_len_hc = 0;
		data_decode_mpu(u8RxSPIBuf + (rxflag_od == FRAME_MAX_LENGTH ? 0 : FRAME_MAX_LENGTH), FRAME_MAX_LENGTH,\
			u8TxSPIBuf + txflag_od, &output_data_len_hc);/**/
		memset(u8RxSPIBuf + (rxflag_od == FRAME_MAX_LENGTH ? 0 : FRAME_MAX_LENGTH), 0, FRAME_MAX_LENGTH);
		SPI_SEND_INDEX = output_data_len_hc > 0 ? 0 : 0X5566;
	  
	}
}

 

 