#include <stdint.h>
#include <stdbool.h>  
#include <stddef.h>
#include "SPIBUS.h"



extern uint8_t SPIWriteRead(SPIBUS_t * pSPIObj);

#ifdef USE_SPI1
SPIBUS_t SPI_myObj1;
extern uint16_t ReadQTY_1[];  //unit: byte or word, Now it is depend on SPI1_USE16BIT_WIDTH
extern uint16_t WriteQTY_1[]; //unit: byte or word, Now it is depend on SPI1_USE16BIT_WIDTH
#endif




#ifdef USE_SPI2
SPIBUS_t SPI_myObj2;
extern uint16_t ReadQTY_2[];  //unit: byte or word, Now it is depend on SPI2_USE16BIT_WIDTH
extern uint16_t WriteQTY_2[]; //unit: byte or word, Now it is depend on SPI2_USE16BIT_WIDTH
#endif


#ifdef USE_SPI3
SPIBUS_t SPI_myObj3;
extern uint16_t ReadQTY_3[];  //unit: byte or word, Now it is depend on SPI3_USE16BIT_WIDTH
extern uint16_t WriteQTY_3[]; //unit: byte or word, Now it is depend on SPI3_USE16BIT_WIDTH
#endif

#ifdef USE_SPI4
SPIBUS_t SPI_myObj4;
extern uint16_t ReadQTY_4[];  //unit: byte or word, Now it is depend on SPI4_USE16BIT_WIDTH
extern uint16_t WriteQTY_4[]; //unit: byte or word, Now it is depend on SPI4_USE16BIT_WIDTH

#endif

/**
 * 
 * @param pSPIMyOBJ
 * @param SPI_Peripheral_No
 * @param pReadData
 * @param pWriteData
 * @param MAxSeq_Qty
 * @param Max_ByteQTY4read
 * @param Max_ByteQTY4write
 */
void SPIBUS_init(SPIBUS_t * pSPIMyOBJ, uint8_t SPI_Peripheral_No, bool Use16bitsBus, uint8_t MAxSeq_Qty, uint16_t * QTY4Read, uint16_t * QTY4Write, 
        uint16_t Max_ByteQTY4ReadWrite, volatile uint8_t * Room4pReadData[], volatile uint8_t * Room4pWriteData[],void (* set_CS_Fn[])(bool)) {

    pSPIMyOBJ->SPI_Peripheral_No= SPI_Peripheral_No;
    pSPIMyOBJ->Use16bitsBus = Use16bitsBus;    
    pSPIMyOBJ->Max_Seq_QTY=MAxSeq_Qty;
    pSPIMyOBJ->pReadData=Room4pReadData;
    pSPIMyOBJ->pWriteData=Room4pWriteData;
    pSPIMyOBJ->QTY4Read=QTY4Read;
    pSPIMyOBJ->QTY4Write=QTY4Write;
    pSPIMyOBJ->Max_ByteQTY4read_Or_write=Max_ByteQTY4ReadWrite;    
    pSPIMyOBJ->LogicRule= 0;
    pSPIMyOBJ->PresentSeqNo=0;  
    //pSPIMyOBJ->DummyDataAllOne=0x7fff;  //Don't do it in case "setup block" init executing after every "read/write block" start
    pSPIMyOBJ->state=0;
    pSPIMyOBJ->set_CS=set_CS_Fn;
}

void SPIBUS_Poll(SPIBUS_t * pSPIObj) {
    
    int8_t TxResult;    
   
    if (pSPIObj->LogicRule & (1u << pSPIObj->PresentSeqNo))
    {
        //Need to read/write
        TxResult=SPIWriteRead(pSPIObj);
        if (0 == TxResult) {
            //Done for read/write            
            pSPIObj->LogicRule &= ~(1U<<pSPIObj->PresentSeqNo); 
            pSPIObj->PresentSeqNo++;
            if (pSPIObj->PresentSeqNo>=pSPIObj->Max_Seq_QTY) pSPIObj->PresentSeqNo=0;
        }
        else if (TxResult < 0) {
            pSPIObj->LogicRule &= ~(1U<<pSPIObj->PresentSeqNo); 
            pSPIObj->PresentSeqNo++;
            if (pSPIObj->PresentSeqNo>=pSPIObj->Max_Seq_QTY) pSPIObj->PresentSeqNo=0;
        }
        else {
            //Run again next time (continue), so do nothing
        }    
    }
    else
    {   
        //no need to read/write
        pSPIObj->PresentSeqNo++;
        if (0x8000==pSPIObj->LogicRule)
        {
            pSPIObj->PresentSeqNo=0;
        }
        else {
            if (pSPIObj->PresentSeqNo==pSPIObj->Max_Seq_QTY) pSPIObj->PresentSeqNo=0;
        } 
        
    }
    
    
}




