#include "DSP2833x_Device.h"     // DSP2833x Headerfile Include File
#include "DSP2833x_SWPrioritizedIsrLevels.h"

#include "filter_bat2.h"
#include "measure.h"
#include "package.h"     // DSP281x Headerfile Include File

#include "ecan.h"     // DSP281x Headerfile Include File
#include "tools.h"     // DSP281x Headerfile Include File

#include "RS485.h"
#include "message.h"
#include "peripher.h"


// Prototype statements for functions found within this file.
interrupt void CANa_handler(void);
interrupt void CANa_reset_err(void);

// Global variable for this example
Uint32  ErrorCount;
Uint32  MessageReceivedCount;
Uint32  MessageTransivedCount=0;

Uint32  TestMbox1 = 0;
Uint32  TestMbox2 = 0;
Uint32  TestMbox3 = 0;

int CanTimeOutErrorTR = 0;

int wait=0;

void InitCan(int Port, int DevNum)
{
  struct ECAN_REGS ECanShadow; 

  volatile struct ECAN_REGS * ECanRegs;
  volatile struct ECAN_MBOXES * ECanMboxes;
  volatile struct MOTO_REGS * ECanMOTORegs;

	long id = 0x80BA0000;

	DevNum--;
	if(DevNum<0)DevNum=0;
	if(DevNum>15)DevNum=15;
	
//	Configure CAN pins using GPIO regs here
	EALLOW;

	ECanRegs = &ECanaRegs;
	ECanMboxes = &ECanaMboxes;
	ECanMOTORegs = &ECanaMOTORegs;

	GpioCtrlRegs.GPAMUX2.bit.GPIO30 = 1;
	GpioCtrlRegs.GPAMUX2.bit.GPIO31 = 1;

//	Configure the eCAN RX and TX pins for eCAN transmissions
	ECanRegs->CANTIOC.all = 8;	//	only 3rd bit, TXFUNC, is significant
	ECanRegs->CANRIOC.all = 8;	//	only 3rd bit, RXFUNC, is significant

//	Specify that 8 bits will be sent/received
    ECanMboxes->MBOX0.MSGCTRL.all = 0x00000008;
    ECanMboxes->MBOX1.MSGCTRL.all = 0x00000008;
     
//	Disable all Mailboxes
//	Required before writing the MSGIDs
    ECanRegs->CANME.all = 0;

//	задаем адрес 0 ащикa на передачу
    ECanMboxes->MBOX0.MSGID.all = id +  0x10 + DevNum; 

//	задаем адрес 1 ащикa на прием
    ECanMboxes->MBOX1.MSGID.all = id + DevNum; //поменать!!!! 1 и 0!!!

//	задаем режимы работы ащикa 0 на передачу, остальные на прием
    ECanRegs->CANMD.all = 0xFFFFFFFE; 
    
//	выбираем только 2 ащикa дла работы, остальные запрещаем
    ECanRegs->CANME.all = 0x00000003;

//	Clear all TAn bits
	ECanRegs->CANTA.all	= 0xFFFFFFFF;
//	Clear all RMPn bits
	ECanRegs->CANRMP.all = 0xFFFFFFFF;
//	Clear all interrupt flag bits
	ECanRegs->CANGIF0.all = 0xFFFFFFFF;
	ECanRegs->CANGIF1.all = 0xFFFFFFFF;
//	Clear all error and status bits
    ECanRegs->CANES.all=0xffffffff;

//	Request permission to change the configuration registers
    ECanShadow.CANMC.all = 0;
	ECanShadow.CANMC.bit.MBCC = 1;	//	Mailbox timestamp counter clear bit
    ECanShadow.CANMC.bit.TCC = 1;	//	Time stamp counter MSB clear bit
    ECanShadow.CANMC.bit.SCB = 1;	//	eCAN mode (reqd to access 32 mailboxes)
	ECanShadow.CANMC.bit.WUBA = 1;	//	Wake up on bus activity
	ECanShadow.CANMC.bit.ABO = 1;	//	Auto bus on
    ECanShadow.CANMC.bit.CCR = 1;	          
//    ECanShadow.CANMC.bit.STM = 1;	//	self-test loop-back
    ECanRegs->CANMC.all = ECanShadow.CANMC.all;
    while(!ECanRegs->CANES.bit.CCE);	// Wait for CCE bit to be set..
   
// настриваем скорость CAN
    ECanShadow.CANBTC.all = ECanRegs->CANBTC.all;
	ECanShadow.CANBTC.bit.SJWREG=1;

    ECanShadow.CANBTC.bit.BRPREG	= (CLKMULT * 3) - 1;
    ECanShadow.CANBTC.bit.TSEG1REG	= 15;
    ECanShadow.CANBTC.bit.TSEG2REG	= 2;

    ECanRegs->CANBTC.all = ECanShadow.CANBTC.all;
    ECanShadow.CANMC.bit.CCR = 0; 			// Set CCR = 0
    ECanRegs->CANMC.all = ECanShadow.CANMC.all;
    while(ECanRegs->CANES.bit.CCE);	// Wait for CCE bit to be cleared..

//	задаем таймауты дла ожиданиа отправки получениа посылки
   	ECanMOTORegs->MOTO0 = 550000;
	ECanMOTORegs->MOTO1 = 550000;

	ECanRegs->CANTOC.all = 1;
	ECanRegs->CANTOS.all = 0;	//	clear all time-out flags
	ECanRegs->CANTSC = 0;		//	clear time-out counter

	ECanShadow.CANGIM.all = 0;

    ECanRegs->CANMIM.all = 2;	//	Enable interrupts of box 1
	ECanRegs->CANMIL.all = 0x00000000; // All mailbox interrupts are generated on interrupt line 0.
	ECanShadow.CANGIM.bit.I0EN = 1;

	ECanShadow.CANGIM.bit.MTOM = 1;
	ECanShadow.CANGIM.bit.I1EN = 1;
	ECanShadow.CANGIM.bit.GIL = 1;
	ECanRegs->CANGIM.all = ECanShadow.CANGIM.all;

	PieVectTable.ECAN0INTA = &CANa_handler;
	PieCtrlRegs.PIEIER9.bit.INTx5=1;     // PIE Group 9, INT6
	PieVectTable.ECAN1INTA = &CANa_reset_err;
	PieCtrlRegs.PIEIER9.bit.INTx6=1;     // PIE Group 9, INT6
	
	IER |= M_INT9;	// Enable CPU INT
	EDIS;

// завершили настройку CAN ащиков

    MessageReceivedCount = 0;
    ErrorCount = 0;
	CanTimeOutErrorTR=0;
	MessageTransivedCount=0;
}

void CAN_send(int Port, int data[], int Addr)
{
  unsigned long hiword,loword;
  volatile struct ECAN_REGS * ECanRegs;
  volatile struct ECAN_MBOXES * ECanMboxes;

	ECanRegs = &ECanaRegs;
	ECanMboxes = &ECanaMboxes;

	if(wait)
	if(!(ECanRegs->CANTA.all & 1))
	if(!(ECanRegs->CANAA.all & 1))
	return;

	ECanRegs->CANTA.all = 1;
	ECanRegs->CANAA.all = 1;

	hiword=	((((Uint32)		Addr   ) & 0xffff)<<16)| 0xE0000000 |
			((((Uint32)data[Addr  ]) & 0xffff)    );
	loword=	((((Uint32)data[Addr+1]) & 0xffff)<<16)|
			((((Uint32)data[Addr+2]) & 0xffff)    );

	ECanMboxes->MBOX0.MDH.all = hiword;
	ECanMboxes->MBOX0.MDL.all = loword;

	EALLOW;
	ECanRegs->CANTSC = 0;		//	clear time-out counter
	EDIS;

	ECanRegs->CANTRS.all = 1;	//	запустить передачу
	
	wait=1;
	led1_toggle();
}


void Handlai(volatile struct ECAN_MBOXES * ECanMboxes)
{
  unsigned int adr;
  unsigned int bit[3];
  unsigned long hiword,loword;
  int Data[3];

	Lonely=0;

	hiword = ECanMboxes->MBOX1.MDH.all;
	loword = ECanMboxes->MBOX1.MDL.all;

	adr		= (hiword >> 16);

	bit[0]	= adr & 0x8000;
	bit[1]	= adr & 0x4000;
	bit[2]	= adr & 0x2000;

	adr	&= 0x1fff;

	Data[0] = (hiword    ) & 0xffff;
	Data[1] = (loword>>16) & 0xffff;
	Data[2] = (loword    ) & 0xffff;
	
	if(bit[0]) if(adr < ANSWER_LEN) modbus[adr] = Data[0]; adr++;
	if(bit[1]) if(adr < ANSWER_LEN) modbus[adr] = Data[1]; adr++;
	if(bit[2]) if(adr < ANSWER_LEN) modbus[adr] = Data[2];

	led2_toggle();
}

interrupt void CANa_handler(void)
{
	// Set interrupt priority:
	volatile Uint16 TempPIEIER = PieCtrlRegs.PIEIER9.all;
	IER |= M_INT9;
	IER	&= MINT9;	  	               // Set "global" priority
	PieCtrlRegs.PIEIER9.all &= MG95;   // Set "group"  priority
	PieCtrlRegs.PIEACK.all = 0xFFFF;   // Enable PIE interrupts
	EINT;

	Handlai(&ECanaMboxes);

	ECanaRegs.CANRMP.all = 2;
	PieCtrlRegs.PIEACK.bit.ACK9   |= 1;
	// Restore registers saved:
	DINT;
	PieCtrlRegs.PIEIER9.all = TempPIEIER;
}

interrupt void CANa_reset_err(void)
{
	// Set interrupt priority:
	volatile Uint16 TempPIEIER = PieCtrlRegs.PIEIER9.all;
	IER |= M_INT9;
	IER	&= MINT9;	  	               // Set "global" priority
	PieCtrlRegs.PIEIER9.all &= MG96;   // Set "group"  priority
	PieCtrlRegs.PIEACK.all = 0xFFFF;   // Enable PIE interrupts
	EINT;

	ECanaRegs.CANTRR.all = 1;
	CanTimeOutErrorTR++;

	PieCtrlRegs.PIEACK.bit.ACK9   |= 1;

	// Restore registers saved:
	DINT;
	PieCtrlRegs.PIEIER9.all = TempPIEIER;
}

//===========================================================================
// No more.
//===========================================================================
