// Example for the Function "Set_DOUTByteMask()"
// DOU 0-6 are set in the MAIN-LOOP, 
// DOUT 7 is set in the Timer-Interrupt

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

//*************************************************************
static void Eval_CANFrames(void);			//CAN receive function
//***********************************************************************
// 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,...
//**************************************************************
//UART-Queues
#define TX_entries 17		//UART transmit buffer 16 Byte (max. size + 1)		
#define RX_entries 17		//UART receive buffer 16 Byte (max. size + 1)
//*************** Globale Variablen ****************************
CANI_qentrytyp rcv_queue[QUEUE_RCV_SIZE];	
CANI_qentrytyp xmt_queue[QUEUE_XMT_SIZE];	

u8_t Buf_XMTQueue[TX_entries];
u8_t Buf_RCVQueue[RX_entries];

u8_t second;
u32_t counter=0;
//***********************************************************************

// This function based on Interrupt and should be as short as possible.
// Returnvalue 1: CAN-Message was is interpreted and will not be written into the CAN queue
// Returnvalue 0: Message will be written into the CAN-queue and will evaluated from CAN_Read() later
int CANRxISRCallBack(CANI_qentrytyp* p)
{
	if(p->ID==0x400)
	{
		UART1_Write((u8_t*)"\rCallBack calledo",16);		//string output
		return 1;					//return value 1 will skip the CAN Read processing via CAN_Read
	}
	else return 0;
}
//****************************************************************
void Timer_2000Hz()
{
	static u8_t n;
	static int m;
	
	n++;
	m++;
	if(n&1)	// runs only ever second call
	{
		LED_1000Hz();
	}
	// Toggle DOUT 7 every 1000 Milliseconds
	if(m>2000)
	{
		m=0;
		second = 1;
		//toggle^=1;
		//Set_DOUT(7,toggle);	//do not use Set_Dout when asyncron Set_DOUTByteMask is running		
	}
}

//***********************************************************************
static void Eval_CANFrames()
{
	if(CAN_Read()==CAN_ERR_OK)	// if an new CAN-Message was received
	{
		switch(CAN_BUFF_ID)
		{
			// Firmwareupdate via CAN
			//convert x.mhx into x.bin via mot2bin.exe (see ...\Release\ABS) and upload with CAN2Flash.exe to MicroMod  
			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_DOUTByte(0);
								
				mCAN_EvalInitialCmd();			
			break;
	//process other CAN-ID 
			case 0x444:						//clear all Dout and the running Counter
				Set_DOUTByte(0);
				counter = 0;
			break;
			
			default:			
			break;
		} // switch
		
	} // if(CAN_Read()=...
}
//****************************************************************
void main()
{	u8_t toggle=0;
	
	
	InitIrqLevels();
    __set_il(7);		// allow all levels 
    
    Hardware_Init();	
	Timer_Init();

	UART1_SetXMTQueue(Buf_XMTQueue, TX_entries);		//transmit-buffer
	UART1_SetRCVQueue(Buf_RCVQueue, RX_entries);		//receive-buffer
	UART1_Init(19200,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);
	EnableExtendedID(1);	// one CAN-receive buffer for 29bit-IDs prepared, default is 0
							// possible parameters: 0-7
	CAN_RxCallback=CANRxISRCallBack;	// assign callback function pointer
	CAN_Online();
	
	
	UART1_Write((u8_t*)"\rHallo",6);	// example for String output
		
	__EI();				// Enable Interrupts
	
	for(;;)							//endless_loop
	{
		
		WATCHDOG;
		Eval_CANFrames();		//call CAN receive function
		
		counter++;
		Set_DOUTByteMask(0x7f,counter>>13); // only DOUT 0-6 changing, 
											//Shift 13 for slower changing of values and more visibility of patterns
		if(second ==1)
		{
		second = 0;
		toggle^=1;
		Set_DOUT(7,toggle);			//do not change the Douts in an asyncron loop (like "Timer_2000Hz") when Set_DOUTByteMask is used
		}
	} //for_ever loop
}