#include "omw_config.h"
#include "omw_dbg.h"
#include "omw_uart.h"
#include "periph_uart.h"
#include "periph_gpio.h"
#include "periph_spim.h"
#include "periph_spis.h"
#include "periph_gpadc.h"

#define SPI_BYTE_NUM 5

int main(void) {
    int i;
    uint8_t rbuf[SPI_BYTE_NUM]; 
    uint8_t tbuf[SPI_BYTE_NUM];
    GPIO_InitTypeDef GPIO_InitStruct;
    SPIS_InitTypeDef SPIS_InitStruct;

    //---------------------------------------
    // init
    //---------------------------------------
    omw_dbg_init();
    printf("SPI slave 4-wire full-duplex test ...\n");
    for(i=0; i<SPI_BYTE_NUM; i++){
        rbuf[i] = 0;
        tbuf[i] = 0x11 + i;
    }

    //---------------------------------------
    // SPIS0 GPIO configuration, GPIO[4]: NCS, GPIO[5]: TXD, GPIO[6]: MOSI, GPIO[7]: MISO
    //---------------------------------------
    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_DriveStrength = GPIO_DRIVE_STRENGTH_3;
    GPIO_InitStruct.GPIO_Pin = GPIO_PIN_4;
    GPIO_InitStruct.GPIO_Mode = GPIO_MODE_IN_FLOATING;
    GPIO_InitStruct.GPIO_AltFunc = OMW_GPIO4_SPIS0_NCS;
    GPIO_Init(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Pin = GPIO_PIN_5;
    GPIO_InitStruct.GPIO_Mode = GPIO_MODE_IN_FLOATING;
    GPIO_InitStruct.GPIO_AltFunc = OMW_GPIO5_SPIS0_SCK;
    GPIO_Init(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Pin = GPIO_PIN_7;
    GPIO_InitStruct.GPIO_Mode = GPIO_MODE_IPD;
    GPIO_InitStruct.GPIO_AltFunc = OMW_GPIO7_SPIS0_MISO;
    GPIO_Init(&GPIO_InitStruct);

    //---------------------------------------
    // SPIS0 configuration
    //---------------------------------------
    // de-init
    SPIS_Cmd(DISABLE);
    SPIS_DeInit();
    // init
    SPIS_StructInit(&SPIS_InitStruct);
    SPIS_InitStruct.SPIS_Direction = SPIS_DIRECTION_TX_AND_RX;
    SPIS_InitStruct.SPIS_SCPOL = SPIS_SCPOL_LOW;
    SPIS_InitStruct.SPIS_SCPH = SPIS_SCPH_MIDDLE;
    SPIS_InitStruct.SPIS_RxFIFOThreshold = 0x08;
    SPIS_InitStruct.SPIS_TxFIFOThreshold = 0x08;
    SPIS_InitStruct.SPIS_Wires = SPIS_WIRES_3;
    SPIS_Init(&SPIS_InitStruct);
    SPIS_ITConfig(SPIS_IT_ALL, DISABLE);
    SPIS_Cmd(ENABLE);

    //---------------------------------------
    // SPI slave receive N bytes
    //---------------------------------------
    //spis switch rx only
    /**/
    SPIS_Cmd(DISABLE);
    /**/
    SPIS_Direction_Switch(SPIS_DIRECTION_RX_ONLY);
    /**/
    SPIS_Cmd(ENABLE);
    // loop
    for(i=0; i<SPI_BYTE_NUM; i++) {
        // wait fifo
        while((SPIS_GetUsrStatus(SPIS_FLAG_RECEIVE_FIFO_NOT_EMPTY)) == RESET); // if rx fifo empty, wait here
        // receive data byte
        rbuf[i] = SPIS_ReceiveData();        
    }
    //---------------------------------------
    // SPI slave send N bytes
    //---------------------------------------
    //spis switch tx only
    /**/
    SPIS_Cmd(DISABLE);
    /**/
    SPIS_Direction_Switch(SPIS_DIRECTION_TX_ONLY);
    /**/
    SPIS_Cmd(ENABLE);
    // loop
    for(i=0; i<SPI_BYTE_NUM; i++) {
        // wait fifo
        while(SPIS_GetUsrStatus(SPIS_FLAG_TRANSMIT_FIFO_NOT_FULL) == RESET); // if tx fifo full, wait here
        // send data byte
        SPIS_SendData(tbuf[i]);        
    }

    //---------------------------------------
    // DELAY
    //---------------------------------------
    DELAY_US(1500);

    //---------------------------------------
    // Display
    //---------------------------------------
    // send data bytes
    printf("    Send Data: ");
    for(i=0; i<SPI_BYTE_NUM; i++) printf("0x%02x ", tbuf[i]);
    printf("\n");
    // recv data bytes
    printf("    Recv Data: ");
    for(i=0; i<SPI_BYTE_NUM; i++) printf("0x%02x ", rbuf[i]);
    printf("\n");
    // end of test
    while(1);
    return 0;
}

