/*
 * spi.c
 *
 *  Created on: 19-12-2016
 *      Author: K
 */

#include <ti/sysbios/hal/Timer.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Clock.h>
#include <ti/sysbios/knl/Semaphore.h>

#include <ti/ipc/Ipc.h>
#include <ti/ipc/MultiProc.h>
#include <ti/ipc/MessageQ.h>
#include <ti/ipc/Notify.h>

#include "misc.h"
#include "spi.h"
#include "tdefs.h"
#include "logic_elements/virt_in_drv.h"
#include "logic_elements/leds_drv.h"
#include "logic_elements/pkw.h"
#include "logic_elements/cnt.h"
#include "logic_elements/s_demux.h"
#include "logic_elements/events_reg.h"
#include "comm.h"

u8 spi_fram_restored = 0;

void spi_init()
{
	u32 psc;

	PINMUX3=(PINMUX3 & ~(PINMUX3_3_0|PINMUX3_15_12|PINMUX3_11_8|PINMUX3_31_28)) | (1<<0) | (1<<12) | (1<<8) | (4<<28); // spi0 clk, mosi, miso, gp8_1 cs
	DIR8&=~(1<<1); // GP8_1 as output

	// enable psc
	while(PTSTAT & 0x00000001);
	MDCTL4=0x00000003;
	PTCMD=0x00000001;

	while(PTSTAT & 0x00000001);
	while((MDSTAT4 & 0x0000003F) != 0x00000003);

	SPI_DEASSERT();

	SPIGCR0=0;
	SPIGCR0=1;
	SPIGCR1=0x00000003;
	SPIPC0=0x00000E00;
    SPIDAT1=0x04000000;

    psc = 10;

    SPIFMT0 = 0x00020008 | (psc << 8); //polarity 1
    SPIGCR1 = 0x01000003;
//    SPIINT0 = (1<<8); // RXINT
//    SPILVL = (1<<8); // RXINT

}


void spi_putc_bl(u16 word)
{
	SPIDAT0=word;
	while(!(SPIFLG & (1<<8)))
		Task_sleep(1);
	SPIFLG|=(1<<8);
}

void spi_wr_en_bl()
{
	SPI_ASSERT();
	Task_sleep(1);
	spi_putc_bl(0x06);
	Task_sleep(1);
	SPI_DEASSERT();
	Task_sleep(1);
}

void spi_wr_buf_bl(u16 addr, u8 *buf, u16 len)
{
	u32 i;

	spi_wr_en_bl();
	SPI_ASSERT();
	Task_sleep(1);
	spi_putc_bl(0x02);
	spi_putc_bl((addr & 0xFF00)>>8);
	spi_putc_bl((addr & 0x00FF)>>0);
	for(i=0;i<len;i++)
		spi_putc_bl(buf[i]);
	Task_sleep(1);
	SPI_DEASSERT();
}

void spi_rd_buf_bl(u16 addr, u8 *buf, u16 len)
{
	u32 i;

	SPI_ASSERT();
	Task_sleep(1);
	spi_putc_bl(0x03);
	spi_putc_bl((addr & 0xFF00)>>8);
	spi_putc_bl((addr & 0x00FF)>>0);
	for(i=0;i<len;i++)
	{
		spi_putc_bl(0xFF);
		buf[i]=SPIBUF&0xFF;
	}
	Task_sleep(1);
	SPI_DEASSERT();
}

Void spiFxn(UArg a0, UArg a1)
{
	u8 buf[49+32+6+16+1];
	u8 i;

	spi_init();

	spi_rd_buf_bl(0,buf,sizeof(buf));
	if(buf[48+32+6+16+1]==(u8)(mod256_cksum(buf,sizeof(buf)-1)+CKSUM_IV))
	{
		virt_in_states=((u32)buf[3]<<24)|((u32)buf[2]<<16)|((u32)buf[1]<<8)|((u32)buf[0]<<0);
		memcpy((char*)pkw_mem,(char*)&buf[4],sizeof(pkw_mem));
		led_states=((u32)buf[39]<<24)|((u32)buf[38]<<16)|((u32)buf[37]<<8)|((u32)buf[36]<<0);
		led_blink_states=((u32)buf[43]<<24)|((u32)buf[42]<<16)|((u32)buf[41]<<8)|((u32)buf[40]<<0);
		virt_in2_states=((u32)buf[47]<<24)|((u32)buf[46]<<16)|((u32)buf[45]<<8)|((u32)buf[44]<<0);
		memcpy((char*)cnt_mem,(char*)&buf[48],sizeof(cnt_mem));

		comm_bits_act[0]=(u16)buf[48+32+0] | ((u16)buf[48+32+1]<<8);
		comm_bits_act[1]=(u16)buf[48+32+2] | ((u16)buf[48+32+3]<<8);
		comm_bits_act[2]=(u16)buf[48+32+4] | ((u16)buf[48+32+5]<<8);

		memcpy((char*)saved_events,(char*)&buf[48+32+6],sizeof(saved_events));

		saved_bank=buf[48+32+6+16];
	}
	else
	{
		saved_bank = 0;
		led_states = 0;
		led_blink_states = 0;
		virt_in_states=0;
		virt_in2_states=0;
		for(i=0;i<8;i++)
		{
			pkw_mem[i]=0.0;
			cnt_mem[i]=0.0;
		}
	}

	spi_fram_restored=1;

	for(;;)
	{
		if(Semaphore_pend(spi_semaphore,3000))
		{
		}
		else
		{
        	if((log_manager.status & LOGMAN_STATUS_STARTED) && (log_manager.status & LOGMAN_STATUS_SOFT_STARTED))
        	{
				buf[0]=(virt_in_states>>0)&0xFF;
				buf[1]=(virt_in_states>>8)&0xFF;
				buf[2]=(virt_in_states>>16)&0xFF;
				buf[3]=(virt_in_states>>24)&0xFF;
				memcpy((char*)&buf[4],(char*)pkw_mem,sizeof(pkw_mem));
				buf[36]=(led_states>>0)&0xFF;
				buf[37]=(led_states>>8)&0xFF;
				buf[38]=(led_states>>16)&0xFF;
				buf[39]=(led_states>>24)&0xFF;
				buf[40]=(led_blink_states>>0)&0xFF;
				buf[41]=(led_blink_states>>8)&0xFF;
				buf[42]=(led_blink_states>>16)&0xFF;
				buf[43]=(led_blink_states>>24)&0xFF;
				buf[44]=(virt_in2_states>>0)&0xFF;
				buf[45]=(virt_in2_states>>8)&0xFF;
				buf[46]=(virt_in2_states>>16)&0xFF;
				buf[47]=(virt_in2_states>>24)&0xFF;
				memcpy((char*)&buf[48],(char*)cnt_mem,sizeof(cnt_mem));
				buf[48+32+0]=(comm_bits_act[0]>>0)&0xFF;
				buf[48+32+1]=(comm_bits_act[0]>>8)&0xFF;
				buf[48+32+2]=(comm_bits_act[1]>>0)&0xFF;
				buf[48+32+3]=(comm_bits_act[1]>>8)&0xFF;
				buf[48+32+4]=(comm_bits_act[2]>>0)&0xFF;
				buf[48+32+5]=(comm_bits_act[2]>>8)&0xFF;
				memcpy((char*)&buf[48+32+6],(char*)saved_events,sizeof(saved_events));
				buf[48+32+6+16]=saved_bank;
				buf[48+32+6+16+1]=(u8)(mod256_cksum(buf,sizeof(buf)-1)+CKSUM_IV);
				spi_wr_buf_bl(0,buf,sizeof(buf));
        	}
        }
	}
}
