/*
Example for direct processing of an CAN Message, not from the CAN-queue
*/

#include "compiler.h"
#include "mb90495.h"
#include "vectors.h"
#include "can.h"
#include "hardware.h"
#include "uart1.h"
#include "timer.h"
#include "i2c.h"
#include "eeprom.h"
#include "adi.h"
#include "pwm.h"
#include "mcan.h"


//************************************************************
static void Eval_CANFrames(void);

//************************************************************
//UART-Queues, only transmit
#define TX_entries 18

// CAN-Queues
#define QUEUE_RCV_SIZE	8	// reserve memory for CAN-Queue, count must be 2,4,8,16,...
#define QUEUE_XMT_SIZE	8	// reserve memory for CAN-Queue, count must be 2,4,8,16,...

//**************************************************************
CANI_qentrytyp rcv_queue[QUEUE_RCV_SIZE];	
CANI_qentrytyp xmt_queue[QUEUE_XMT_SIZE];

u8_t Buf_XMTQueue[TX_entries];				//transmit-buffer for 18 entries
u8_t flag_2000hz;
//**********************************************************************
/*
This function runs at Interrupt-Level (CAN) and should be as soon as possible. 
When using an separat function while CAN processing a function-pointer !=0 is generated and the 
return value of the function decide over the following steps.
return value 1: CAN-Message was direct processed and goes not into the CAN-Queue 
return value 0: Message will be write into the CAN-Queue and precessed in function CAN_Read().
*/

int CANRxISRCallBack(CANI_qentrytyp* p)
{
	if(p->ID==0x400)
	{
		UART1_Write((u8_t*)"\rReceive-ID 0x400",17);
		return 1;
	}
	else return 0;
}
//**********************************************************************
void Timer_2000Hz()	
{
	static u8_t twotimes;
	
	flag_2000hz=1;
	twotimes ++;
	if(twotimes & 1)		//function runs only ever second call 
	{
		LED_1000Hz();	
	}
	
}
//**********************************************************************
static void Eval_CANFrames()
{
	if(CAN_Read()==CAN_ERR_OK)	// if an new CAN-Message was received
	{
		switch(CAN_BUFF_ID)
		{
			// Firmwareupdate via CAN
			case 0x7e7:
/* 
The Library-Funktion  CAN_Read() fills the variables CAN_BUFF_ID, CAN_BUFF_LEN, CAN_BUFF_DATA[8] with the last Queue-entry of the CAN-message.
When using own CAN-LowLevel drivers must befor call the function mCAN_EvalInitialCmd() the variables
CAN_BUFF_ID
CAN_BUFF_LEN
CAN_BUFF_DATA[8]
be filled with the CAN-data.
*/
				// all outputs off
				Set_DOUT(0,0);
				Set_DOUT(1,0);
				Set_DOUT(2,0);
				Set_DOUT(3,0);
				Set_DOUT(4,0);
				Set_DOUT(5,0);
				Set_DOUT(6,0);
				Set_DOUT(7,0);
				
				mCAN_EvalInitialCmd();
			break;
			
			default:
				CAN_BUFF_ID--;	// Echo der CAN-Messages auf ID-1
				CAN_Write();	
				CAN_BUFF_ID++;
			break;
		} // switch
		
	} // if(CAN_Read()=...
}

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

void main()
{
	InitIrqLevels();
    __set_il(7);		// allow all levels 

	Hardware_Init();
	Timer_Init();
	I2C_Init();
	
	
	UART1_SetXMTQueue(Buf_XMTQueue, TX_entries);		//send-buffer		
	UART1_Init(38400,BITLEN_8,NO_PARITY,STOPLEN_1);		
	
	CAN_SetRCVQueue(rcv_queue, QUEUE_RCV_SIZE);	// Set Receive Queue to 8 entries, 
	CAN_SetXMTQueue(xmt_queue, QUEUE_XMT_SIZE);	// Set CAN Transmit Queue to 8 entries
	CAN_Init(CAN_BAUD_500K);
	CAN_RegisterMsg(0);
	CAN_RxCallback = CANRxISRCallBack;	// assign Callback function-pointer
	CAN_Online();
	__EI();				// Enable Interrupts

	UART1_Write((u8_t*)"\rTest!",6);
	
	for(;;)
	{
		WATCHDOG;
		Eval_CANFrames();		//call CAN receive function		
	} //for_ever loop
}