#include <stdint.h>
#include <stdio.h>
#include <unistd.h>

#include "platform.h"
#include "encoding.h"

#define IOF_SPI1_MASK (0x38 | 0x4)
int factorial(int i){

	volatile int result = 1;
	for (int ii = 1; ii <= i; ii++) {
		result = result * ii;
	}
	return result;

}

unsigned read_adc(unsigned index){
    unsigned char txdata[3];
    unsigned result=0;
    volatile int x;

    txdata[0]=0x1;
    txdata[1]=(0x8 | (index&0x7))<<4;
    txdata[2]=0x0;

    GPIO_REG(GPIO_IOF_SEL) &= ~IOF_SPI1_MASK;
    GPIO_REG(GPIO_IOF_EN) |= IOF_SPI1_MASK;

    SPI1_REG(SPI_REG_FMT) =
            SPI_FMT_PROTO(SPI_PROTO_S) |
            SPI_FMT_ENDIAN(SPI_ENDIAN_MSB) |
            SPI_FMT_DIR(SPI_DIR_RX) |
            SPI_FMT_LEN(8);
    SPI1_REG(SPI_REG_CSID)   = 0;
    SPI1_REG(SPI_REG_CSDEF) = 0xFFFF;
    SPI1_REG(SPI_REG_SCKDIV)  = 7;
    SPI1_REG(SPI_REG_SCKMODE) = SPI_SCK_PHA | SPI_SCK_POL; //shifted on the leading edge, sampled on trailing, Inactive state of SCK is logical 1
    SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD;

    while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL) ;
    SPI1_REG(SPI_REG_TXFIFO) = txdata[0];
    while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY);

    while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL) ;
    SPI1_REG(SPI_REG_TXFIFO) = txdata[1];
    while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY);
    result = (x & 0xFF)<<8;

    while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL) ;
    SPI1_REG(SPI_REG_TXFIFO) = txdata[2];
    while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY);
    result += (x & 0xFF);

    SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO;
    return result&0x03ff;
}

int main()
{
	GPIO_REG(GPIO_IOF_EN) |= 0x30000;
	int result = factorial (10);
	printf("Factorial of 10 is %d\n", result);
	for(unsigned i=0; i<8; ++i)
	    printf("ADC%u value read is %u\n", i, read_adc(i));
	printf("End of execution");
	return 0;
}
