/*
 * misc.h
 *
 *  Created on: 30-07-2013
 *      Author: Krzysztof Jakubczyk
 */

#ifndef MISC_H_
#define MISC_H_

#include "tdefs.h"
#include "logman.h"
#include "config.h"

/*
#include <ti/sysbios/hal/Timer.h>
#include <ti/sysbios/knl/Semaphore.h>
#include <ti/sysbios/knl/Swi.h>
*/
#include "mocks.h"

#define MAX_AN_CARDS	16
#define MAX_BIN_CARDS	16
#define MAX_OUT_CARDS	16

#define NEED_RELOAD_IC	0x01

#define IN_CARDS_BASE_ADDR	0x64000000

extern u32 logman_notify;

#define LOGMAN_NOTIFY_NEW_EVENTS	0x01
#define LOGMAN_NOTIFY_NEW_DFR		0x02
#define LOGMAN_NOTIFY_NEW_DDR		0x04
#define LOGMAN_NOTIFY_BANK0			0x08
#define LOGMAN_NOTIFY_BANK1			0x10
#define LOGMAN_NOTIFY_BANK2			0x20
#define LOGMAN_NOTIFY_BANK3			0x40
#define LOGMAN_NOTIFY_BANK4			0x80
#define LOGMAN_NOTIFY_BANK5			0x100

extern volatile short analog_buf[127];
extern volatile int shared_buf[1024];
extern volatile int analog_buf_ready;
extern volatile int analog_buf_cnt;
extern unsigned int analog_buf_card;
extern unsigned int analog_buf_channel;
extern volatile unsigned short samples_dropped;
extern volatile struct timeval cur_time;
extern volatile struct timeval cur_time_sw;
extern volatile u8 ext_sync;
extern volatile u8 have;
extern u8 cur_sample_diff;
extern int omapl138EthSendPacket(u8 *buf,u16 len);
extern int asn_parse(u8 **buf,int *bytes_left, u8 *tag);

extern u8 bus_an_samples_neg[MAX_AN_CARDS][4];
enum arg_type { ARG_TYPE_BOOL = 0, ARG_TYPE_TEXT = 1, ARG_TYPE_DOUBLE = 2, ARG_TYPE_LONG = 3 };

struct timeval
{
    u32	tv_sec; 	/* seconds 			*/
	u32	tv_usec;	/* and microseconds */
};

struct parsed_cfg_transport_line
{
	char name[32];
	enum arg_type type;
	char text_val[256];
	double double_val;
	long int long_val;
	unsigned char bool_val;
};

struct klapacz_config
{
	unsigned int interval1;
	unsigned int interval2;
};

struct device_config
{
	unsigned char mwd_ac_mask[MAX_OUT_CARDS];
	unsigned int bits;
};

extern struct device_config dev_cfg;


struct config_lookup_table
{
	char name[32];
	enum arg_type type;
	void *addr;
	unsigned char size;
	unsigned char bit_mask;
	unsigned char flags;
};

#define CFG_BIT_KLAPACZ_ENABLED		(1<<4)

extern struct klapacz_config klap_cfg;

/* CPU registers */
#define SET_RIS_TRIG67 	 *((volatile int*)0x01E2609C)
#define SET_RIS_TRIG8	 *((volatile int*)0x01E260C4)
#define INTSTAT67		 *((volatile int*)0x01E260AC)

#define PINMUX0			 *((volatile int*)0x01C14120)
#define PINMUX1			 *((volatile int*)0x01C14124)
#define PINMUX2			 *((volatile int*)0x01C14128)
#define PINMUX3			 *((volatile int*)0x01C1412C)
#define PINMUX7			 *((volatile int*)0x01C1413C)
#define DIR8			 *((volatile int*)0x01E260B0)
#define SETDATA8		 *((volatile int*)0x01E260B8)
#define CLRDATA8		 *((volatile int*)0x01E260BC)
#define SPIGCR0 		 *((volatile int*)0x01C41000)
#define SPIGCR1 		 *((volatile int*)0x01C41004)
#define SPIPC0	 		 *((volatile int*)0x01C41014)
#define SPIDAT0			 *((volatile int*)0x01C41038)
#define SPIDAT1			 *((volatile int*)0x01C4103C)
#define SPIFMT0			 *((volatile int*)0x01C41050)
#define SPIGCR1			 *((volatile int*)0x01C41004)
#define SPIINT0			 *((volatile int*)0x01C41008)
#define SPILVL			 *((volatile int*)0x01C4100C)
#define SPIBUF			 *((volatile int*)0x01C41040)
#define SPIFLG			 *((volatile int*)0x01C41010)

#define DIR01			 *((volatile int*)0x01E26010)
#define IN_DATA01		 *((volatile int*)0x01E26020)

#define PUPD_ENA		 *((volatile int*)0x01E2C00C)
#define PUPD_SEL		 *((volatile int*)0x01E2C010)

#define KICK0R			 *((volatile int*)0x01C14038)
#define KICK1R			 *((volatile int*)0x01C1403C)

#define KICK0R_VAL		 0x83E70B13
#define KICK1R_VAL		 0x95A4F1E0

#define	PINMUX3_3_0 	 0x0000000F
#define	PINMUX3_11_8 	 0x00000F00
#define	PINMUX3_15_12 	 0x0000F000
#define	PINMUX3_19_16 	 0x000F0000
#define PINMUX3_31_28    0xF0000000


// PSC
#define PTCMD 	*((volatile int*)0x01C10120)
#define PTSTAT	*((volatile int*)0x01C10128)
#define MDCTL4	*((volatile int*)0x01C10A10)
#define MDSTAT4 *((volatile int*)0x01C10810)
#define MDSTAT10 *((volatile int*)0x01E27828)

//extern Semaphore_Handle spi_semaphore;

extern volatile int was_irq;
extern u16 bus_an_cur_timestamp;
extern u8 bus_an_cur_sample_num_xkhz;
extern u16 tstamp_khz;

struct an_card
{
	short l1;
	short l2;
	short l3;
	short l4;
};

//mux
#define C37_MUX_BUFSIZE			256

//mux bits
#define MUX_REG_CHAN_NUM_OFFSET		12
#define MUX_REG_EXT_CLK				(1<<11)
#define MUX_REG_WR					(1<<10)
#define MUX_REG_SKIP_FF				(1<<9)
#define MUX_REG_TX_BYTES_MASK		0x00FF

//
#define MUX_STATE_ERR				(1<<15)
#define MUX_STATE_ERR_CNT_MASK		0x7E00
#define MUX_STATE_ERR_CNT_OFFSET	9
#define MUX_STATE_RX_BYTES_MASK		0x00FF
#define MUX_STATE_YELLOW_BIT_IN		(1<<14)

#define YEAR0           1900                    /* the first year */
#define EPOCH_YR        1970            /* EPOCH = Jan 1 1970 00:00:00 */
#define SECS_DAY        (24L * 60L * 60L)
#define LEAPYEAR(year)  (!((year) % 4) && (((year) % 100) || !((year) % 400)))
#define YEARSIZE(year)  (LEAPYEAR(year) ? 366 : 365)
#define FIRSTSUNDAY(timp)       (((timp)->tm_yday - (timp)->tm_wday + 420) % 7)
#define FIRSTDAYOF(timp)        (((timp)->tm_wday - (timp)->tm_yday + 420) % 7)
#define TIME_MAX        ULONG_MAX
#define ABB_LEN         3

struct time_data
{
	uint8_t hour;
	uint8_t min;
	uint8_t sec;
	uint8_t day;
	uint8_t month;
	uint8_t year;
	uint32_t secs;
	uint8_t fix_sat;
};

struct in_cards
{
	struct an_card an_in[MAX_AN_CARDS];
	unsigned char bin_in[MAX_BIN_CARDS];
   	unsigned short out_set[MAX_OUT_CARDS];
	unsigned char bin_ac_mask[MAX_BIN_CARDS];
	unsigned short unused[32];
	struct an_card an_offset[MAX_AN_CARDS];
	unsigned short reverse_curr;
	unsigned short kob_an;
	unsigned short kob_bin;
	unsigned short kob_out;
	unsigned short an_errs;
	unsigned short bin_errs;
	unsigned short out_errs;
	unsigned short valid_an_samples;
	unsigned short sample_no;
	unsigned short spi_reg;
	signed short delta_period_50M; 			//202
	signed short phase_corr; 				//203
	unsigned short sync_reg;				//204   //	bit15-synced pps, 14-synced irig, 13-4kHz imp   0-neg out pps
	unsigned short fpga_verl;
	unsigned short fpga_verh;
	unsigned short sample_sync_no;
	unsigned short mux_reg;
	unsigned short mux_state;
	unsigned short mux2_reg;
	unsigned short mux2_state;
	unsigned char mux_shift;
	unsigned char mux2_shift;
	unsigned short irigb_p[10];
	unsigned short eof;
	unsigned char bin_in_ench[MAX_BIN_CARDS];
	unsigned char bin_ac_mask_ench[MAX_BIN_CARDS];
	unsigned short mwd32_present;
	unsigned short padding[800-512-16-1];
	unsigned char mux_indata[C37_MUX_BUFSIZE];
	unsigned char mux_outdata[C37_MUX_BUFSIZE];
	unsigned char mux2_indata[C37_MUX_BUFSIZE];
	unsigned char mux2_outdata[C37_MUX_BUFSIZE];
	unsigned char spi_frame[2048];
};

// sync reg
#define PPS_SYNCED		0x8000
#define IRIGB_SYNCED	0x4000
#define NEG_PPS_IN		0x0002
#define NEG_PPS_OUT		0x0004
#define MKI_PPS_IN		0x0008

struct time_data irigb_process_frame();

extern volatile u32 timesync_method;
extern volatile u32 timesync_bits;
extern volatile u16 pps3_timeout_cnt;

extern volatile u16 kob_bin_ench;
extern volatile u16 mwd32_mask;

#define SYNC_METHOD_MGB				0x00 // standardowo czas z MGB + PPS
#define SYNC_METHOD_MKI				0x01 // MGB + MKI4 + PPS
#define SYNC_METHOD_MKI_PTP			0x02 // MKI7 + PPS
#define SYNC_METHOD_IEC103			0x03 // IEC103
#define SYNC_METHOD_IRIG_B_ZPRAE	0x04 // IRIG_B Proto ZPrAE
#define	SYNC_METHOD_IRIG_B			0x05 // IRIG_B
#define SYNC_METHOD_ZP6				0x06 // ZP6 z uwzglednieniem milisekund
#define SYNC_METHOD_MLB				0x07 // ZP6 z uwzglednieniem milisekund, nie przyjmowanie od MGB czasu
#define SYNC_METHOD_CUSTOM			0xFF


#define CFG_TSYNC_ACCEPT_FROM_MGB			(1<<0)
#define CFG_TSYNC_ACCEPT_FROM_ETH_AND_RS	(1<<1)
#define CFG_TSYNC_ACCEPT_IEC103				(1<<2)
#define CFG_TSYNC_FROM_DSP					(1<<3)
#define CFG_TSYNC_USE_PPS					(1<<4)
#define CFG_TSYNC_USE_SWPPS					(1<<6)
#define CFG_TSYNC_USE_SWCLK					(1<<7)

struct debug_info
{
	u32 tick_period;
	u32 logman_cycle_time;
	u32 logman_cycle_time_max;
	u32 logman_buf_size_cur;
	u32 logman_buf_capacity;
	u32 irq_time;
	u32 logman_cycle_period;
	u32 logman_cycle_period_max;
	volatile u32 temp_dbg;
	short delta_period;
	short phase_corr;
	unsigned short sync_reg;
	unsigned short max_elements;
	unsigned short used_elements;
	unsigned short nets_bufsize;
}__attribute__((__packed__));

extern struct debug_info dbg;

// spi reg
#define SPI_GOT_FRAME		0x01
#define SPI_ALLOW_FRAME_N	0x01
#define SPI_ANSWER_READY	0x02
#define SPI_NEW_EVENTS		0x04

extern volatile struct in_cards *ic;
extern void reload_ic_cfg();
extern void ms_hook();
extern void analog_inputs_init();

#define PI 3.14159265

#define CKSUM_IV	0xAB	/* config cksum init vector */
extern u8 mod256_cksum(uint8_t *buf, u32 len);
extern u8 bus_an_cur_sample_num_3khz;
extern u8 bus_an_cur_sample_num;
extern u16 bus_an_samples_buf[MAX_AN_CARDS][4][SAMPLES_PER_MS*MAIN_FREQ_PERIOD_MS*2];
extern u16 bus_out_data[MAX_OUT_CARDS];
extern u8 bus_bin_data[MAX_BIN_CARDS];
extern u16 force_bus_out_data[MAX_OUT_CARDS];
extern u8 force_bus_bin_data[MAX_BIN_CARDS];
extern u8 force_bus_bin_data_ench[MAX_BIN_CARDS];
extern u16 bus_out_data_test[MAX_OUT_CARDS];

extern u8 bus_bin_data_ench[MAX_BIN_CARDS];
extern u8 force_bus_bin_data_ench[MAX_BIN_CARDS];

//extern Swi_Handle swi_notify;

#define PWM1_SET(x,y) *((volatile uint16_t*)x) = y
#define PWM1_GET(x) *((volatile uint16_t*)x)

#define PWM1_BEG 0x01F02000
#define PWM1_TBCTL 0x01F02000
#define PWM1_TBCNT 0x01F02008
#define PWM1_TBPRD 0x01F0200A
#define PWM1_CMPA 0x01F02012
#define PWM1_CMPB 0x01F02014
#define PWM1_AQCTLA 0x01F02016
#define PWM1_ETSEL 0x01F02032
#define PWM1_ETPS 0x01F02034
#define PWM1_ETCLR 0x01F02038
#define PWM1_ETFRC 0x01F0203A

#endif /* MISC_H_ */
