/*--------------------------------NET_MODUL.C-------------------------------------


--------------------------------------------------------------------------------*/

#include <rtl_debug.h>
//#include <rtl.h>
#include <time.h>
#include <pthread.h>
#include <rtl_printf.h>
#include <rtl_fifo.h>
#include <rtl_sched.h>
#include <rtl_mutex.h>
//#include <asm/io.h>
#include "can.h"
#include "isarw.h"

//rx/tx boxes
extern struct mod_boxes out_box,in_box;

//mutex
extern pthread_mutex_t out_box_vmtx,in_box_vmtx;	//box mutex
extern pthread_mutex_t tx_read_fmtx,rx_read_fmtx;	//thread mutex

//variables
extern char net_ok; 


pthread_t thread_tx_can,thread_rx_can;
pthread_attr_t attr_tx_can,attr_rx_can;

struct CAN_MSG RX_MSG, TX_MSG;

void *can_tx_thread(void *arg)
{
int box_n,msg_n,byte_n;
int dato;
char *ptr_dato,reg;

rtl_printf("can_thread run \n");

RAM_CLEAN();
isa_writeb(CAN_MODE,TX_MODE_TARGET);//can mode       

//mensaje de inicializacion motores
TX_MSG.CAN_ID=0;
TX_MSG.CAN_DLC=0;
                                                                                                              
WR_CAN_BOX(&TX_MSG.CAN_ID,TX_MSG.CAN_DLC,&TX_MSG.DATA[0],0);



                       
                                                                           
        while(1)
        {
	pthread_mutex_lock(&tx_read_fmtx);      //thread waiting
	pthread_mutex_lock(&out_box_vmtx);	

	//mensaje de inicializacion motores
	TX_MSG.CAN_ID=0;
	TX_MSG.CAN_DLC=0;
                                                                                
	WR_CAN_BOX(&TX_MSG.CAN_ID,TX_MSG.CAN_DLC,&TX_MSG.DATA[0],0);

	
	for(box_n=0;box_n<20;box_n++)
	{
		if(out_box.msg[box_n] > 0)	//if has a msg on the buffer
		{
			for(msg_n=0;msg_n<out_box.msg[box_n];msg_n++)
			{
				dato=out_box.box[box_n][msg_n];
				ptr_dato=&dato;
				TX_MSG.DATA[0]=*ptr_dato;
				TX_MSG.DATA[1]=*(ptr_dato + 1);

				for(byte_n=0;byte_n<out_box.dlc[box_n][msg_n];byte_n++)
					TX_MSG.DATA[byte_n]=out_box.box[box_n][msg_n][byte_n];
				TX_MSG.CAN_ID=out_box.id[box_n][msg_n];
				TX_MSG.CAN_DLC=out_box.dlc[box_n][msg_n];	

				WR_CAN_BOX(&TX_MSG.CAN_ID,TX_MSG.CAN_DLC,&TX_MSG.DATA[0],0); 
				out_box.msg[box_n]--;//decrement the box msg counter
			}
		}
	}


	pthread_mutex_unlock(&out_box_vmtx);

//        reg=isa_readb(TX_MODE_TARGET)+0x80;//flag tx msg for target
//        isa_writeb(reg,TX_MODE_TARGET);

//	rtl_printf("periodica \n");
        //pthread_wait_np();

        
        }//end while                                                                   
return 0;
                                                                           
}

void *can_rx_thread(void *arg)
{
int msg_n,rx_box_count,data;
char rx_control_word;


for(msg_n=0;msg_n<20;msg_n++)
	in_box.msg[msg_n]=0;		//clean the buffers

msg_n=0;

while(1)
{
	pthread_mutex_lock(&rx_read_fmtx);
	pthread_mutex_lock(&in_box_vmtx);

	for(rx_box_count=0;rx_box_count<35;rx_box_count)
	{
		
		rx_control_word=isa_readb(BASE_CAN_RX + 11*rx_box_count);

		if( (rx_control_word & 0x80) > 0 )			// full box ??
			RD_CAN_BOX(&RX_MSG.CAN_ID,&RX_MSG.DATA[0]);	//read msg

//cambiar pues solo escribe en un box y leer el dlc
		in_box.box[0][msg_n][0] = RX_MSG.DATA[0] ;	
		in_box.box[0][msg_n][1] = RX_MSG.DATA[1];
		in_box.id[0][msg_n]= RX_MSG.CAN_ID;
		in_box.msg[msg_n]++;
	
	}

	pthread_mutex_unlock(&in_box_vmtx);

}//end while

return 0;
}



int can_init_module(void)
{
struct sched_param p_tx_can,p_rx_can;

	net_ok=1;//net_modul inside
        rtl_printf("Estoy en can_init_module\n");
        pthread_attr_init(&attr_tx_can);
        //pthread_attr_setfp_np(&attr_tx_can,1);
        p_tx_can.sched_priority=4;
        pthread_attr_setschedparam(&attr_tx_can,&p_tx_can);
        pthread_create(&thread_tx_can, &attr_tx_can , can_tx_thread,0);
	rtl_printf("Lanzando TXcan Thread \n");

        pthread_attr_init(&attr_rx_can);
        pthread_attr_setfp_np(&attr_rx_can,1);
        p_rx_can.sched_priority=4;
        pthread_attr_setschedparam(&attr_rx_can,&p_rx_can);
        pthread_create(&thread_rx_can, &attr_rx_can , can_rx_thread,0);
        rtl_printf("Lanzando RXcan Thread \n");


        return 0;
}


void can_cleanup_module(void)
{
                                                                           
//        pthread_cancel(can_tx_thread);
//	pthread_join(can_tx_thread,NULL);

//        pthread_cancel(can_rx_thread);
//        pthread_join(can_rx_thread,NULL);

        rtl_printf("cancelada periodic \n");
                                                                           
                                                                           
}



