#include "compiler.h"
#include "mb90495.h"
#include "can.h"
#include "mcan.h"
#include "hardware.h"
#include "timer.h"
#include "comptime.h"
#include "main.h"

const char Filesignatur[]={"PCAN_MicroMod"};	// "PCAN_MicroMod" MUSS so bleiben!!!

#define SETID(id) ((( (id) << 13) & 0xE000) | (( (id) >> 3) & 0xFF)) 
#define GETID(Value) (((Value << 3) & 0x7F8) | ((Value >> 13) & 0x007))

void mCAN_Init()
{
    __set_il(0);		// allow all levels 
    __DI();				// disable alle irq

	CSR_HALT = 1;		// Bus stop
	while (! CSR_HALT);
	TCR = 0;           	// Transmit complete Register
	RCR = 0;            // Receive complete Register
	RRTRR = 0;          // Remote request receiving Register
	ROVRR = 0;          // Receive Overrun Register
	TRTRR = 0; 			// Transmit RTR Register
	RFWTR = 0; 			// Remote frame receive waiting Register

	CSR_TOE = 1;		// Output Enable f r TX-Leitung
	BVALR = 0;			// alle Buffer ung ltig machen
//	BTR = baudrate;		// baudrate bleibt so wie konfiguriert!!!
	IDER = 0;			// alle Buffer auf 11bit
	AMSR = 0xAAAA;		// Buffer 0..6 (Empfang), auf Acceptance Mask 0 Full Bit Comparison f r Buffer 7 (Senden)
	AMR0 = 0;
	AMR1 = 0;
	
	IDR(0)  = SETID(0x07E7L); // eben 0x7e7
	IDR(1)  = SETID(0x07E7L);
	IDR(2)  = SETID(0x07E7L);
	IDR(3)  = SETID(0x07E7L);
	IDR(4)  = SETID(0x07E7L);
	IDR(5)  = SETID(0x07E7L);
	IDR(6)  = SETID(0x07E7L);
	IDR(7)  = SETID(0x07E7L);


//	AMR0 = 0x0000;		  alle Bits auf must match

	RIER = 0x00;		// keine irqus   Receive Interrupt f r Buffer 0..6
	TIER = 0x00;

	BVALR = 0x7F;		// Buffer 0..6 aktiv
	CSR_HALT = 0;		// Bus start

	#pragma asm
    MOVW A, #0x8FF      ; repair stack, in case stream_init
    MOVW SP,A           ; was completed by RET (not RETP)
	#pragma endasm

	// code kopierenvon ROM ins RAM
   	for (c2f_counter=0;c2f_counter < SIZE_CODE_C2F+2;c2f_counter+=2)
   	{
   		c2f_src = (unsigned int __far*)(0xFFF000l+c2f_counter);
   		c2f_des = (unsigned int __far*)(0x990l+c2f_counter);
   		*c2f_des=*c2f_src;  
   	}
   		
   	WDTC &= 0xFB;
   	mCAN_flash_main();
   	
}

// ******************************************************************

void mCAN_DetectAnswer()	// CAN2Flash Detect Answer!
{
	CAN_BUFF_ID = 0x7E7;
	CAN_BUFF_LEN= 6;
	CAN_BUFF_DATA[0] = 0x7f;
	CAN_BUFF_DATA[1] = 0xff;
	CAN_BUFF_DATA[2] = 31-(PDR3>>3);	
	CAN_BUFF_DATA[3] = 4;	// Hardware-Typ   MicoMod
	CAN_BUFF_DATA[4] = 4;	// Flash-Typ      MB90F497
	CAN_BUFF_DATA[5] = 0;
	CAN_Write();
} 
// ******************************************************************

void mCAN_EvalInitialCmd()
{
	if( ((CAN_BUFF_DATA[0] & 0xC0) == 0x80) && (CAN_BUFF_DATA[2]==0x06) )	// PPCAN DETECT
	{
		u16_t ModuleID=31-(PDR3>>3);
		u16_t Detect_timeout = 15*ModuleID+(ModuleID>>1);
		Timer_Set(0, Detect_timeout/2);	// nur halb so lange warten, da CPU/Timer mit 1/2 Takt laeuft!
		while(Timer(0)) WATCHDOG;	// Detect Timeout hier abwarten!!!

		ModuleID+= (63<<6)  ; // Module Type MicroMod = 63=0x3f

		CAN_BUFF_ID=0x7E7;	// Send PPCAN Detect Answer!
		CAN_BUFF_LEN = 8;
		CAN_BUFF_DATA[0] = 0xC0 | (ModuleID>>8);
		CAN_BUFF_DATA[1] = ModuleID & 0xff;
		CAN_BUFF_DATA[2] = 0x06;
		CAN_BUFF_DATA[3] = ((__COMPILETIME_DAY__ / 10) << 4) | (__COMPILETIME_DAY__ % 10) ;
        CAN_BUFF_DATA[4] = ((__COMPILETIME_MONTH__ / 10) << 4) | (__COMPILETIME_MONTH__ % 10) ;
        CAN_BUFF_DATA[5] = (((__COMPILETIME_YEAR__ % 100) / 10) << 4) | ((__COMPILETIME_YEAR__ % 100) % 10) ;

		CAN_BUFF_DATA[6] = VERSION2BYTE(_MAIN_,_SUB_);
		CAN_BUFF_DATA[7] = 0;
		CAN_Write();
	}

	// CAN Flash Download Detect
	else if( (CAN_BUFF_LEN==7) &&
		(CAN_BUFF_DATA[0]==0x7f) && 
		(CAN_BUFF_DATA[1]==0xff) &&
		((CAN_BUFF_DATA[2]==31-(PDR3>>3)) || (CAN_BUFF_DATA[2]==0xff)) &&
		(CAN_BUFF_DATA[3]==0))
	{
		mCAN_DetectAnswer();
	}
	// CAN Flash Download Start
	else if( (CAN_BUFF_LEN==7) &&
		(CAN_BUFF_DATA[0]==0x7f) && 
		(CAN_BUFF_DATA[1]==0xff) &&
		((CAN_BUFF_DATA[2]==31-(PDR3>>3)) || (CAN_BUFF_DATA[2]==0xff)) &&
		(CAN_BUFF_DATA[3]==7) &&
		(CAN_BUFF_DATA[4]==0x55))
	{
	int n;
		for(n=0;n<20000;n++) WATCHDOG;
		mCAN_Init();
	}
}
