#include "CAN.h"
#include "led.h"
#include "delay.h"
#include "usart.h"
//////////////////////////////////////////////////////////////////////////////////	 
//±¾³ÌÐòÖ»¹©Ñ§Ï°Ê¹ÓÃ£¬Î´¾­×÷ÕßÐí¿É£¬²»µÃÓÃÓÚÆäËüÈÎºÎÓÃÍ¾
//ALIENTEKÕ½½¢STM32¿ª·¢°å
//CANÇý¶¯ ´úÂë	   
//ÕýµãÔ­×Ó@ALIENTEK
//¼¼ÊõÂÛÌ³:www.openedv.com
//ÐÞ¸ÄÈÕÆÚ:2012/9/11
//°æ±¾£ºV1.0
//°æÈ¨ËùÓÐ£¬µÁ°æ±Ø¾¿¡£
//Copyright(C) ¹ãÖÝÊÐÐÇÒíµç×Ó¿Æ¼¼ÓÐÏÞ¹«Ë¾ 2009-2019
//All rights reserved									  
//////////////////////////////////////////////////////////////////////////////////
//CAN³õÊ¼»¯
//tsjw:ÖØÐÂÍ¬²½ÌøÔ¾Ê±¼äµ¥Ôª.·¶Î§:1~3; CAN_SJW_1tq	 CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq
//tbs2:Ê±¼ä¶Î2µÄÊ±¼äµ¥Ôª.·¶Î§:1~8;
//tbs1:Ê±¼ä¶Î1µÄÊ±¼äµ¥Ôª.·¶Î§:1~16;	  CAN_BS1_1tq ~CAN_BS1_16tq
//brp :²¨ÌØÂÊ·ÖÆµÆ÷.·¶Î§:1~1024;(Êµ¼ÊÒª¼Ó1,Ò²¾ÍÊÇ1~1024) tq=(brp)*tpclk1
//×¢ÒâÒÔÉÏ²ÎÊýÈÎºÎÒ»¸ö¶¼²»ÄÜÉèÎª0,·ñÔò»áÂÒ.
//²¨ÌØÂÊ=Fpclk1/((tsjw+tbs1+tbs2)*brp);
//mode:0,ÆÕÍ¨Ä£Ê½;1,»Ø»·Ä£Ê½;
//Fpclk1µÄÊ±ÖÓÔÚ³õÊ¼»¯µÄÊ±ºòÉèÖÃÎª36M,Èç¹ûÉèÖÃCAN_Normal_Init(1,8,7,5,1);
//Ôò²¨ÌØÂÊÎª:36M/((1+8+7)*5)=450Kbps
//·µ»ØÖµ:0,³õÊ¼»¯OK;
//    ÆäËû,³õÊ¼»¯Ê§°Ü;


u8 CAN_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode)
{

	GPIO_InitTypeDef GPIO_InitStructure; 
	CAN_InitTypeDef        CAN_InitStructure;
 	CAN_FilterInitTypeDef  CAN_FilterInitStructure;
#if CAN_RX0_INT_ENABLE 
   	NVIC_InitTypeDef  NVIC_InitStructure;
#endif

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//Ê¹ÄÜPORTAÊ±ÖÓ	                   											 

  	RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);//Ê¹ÄÜCAN2Ê±ÖÓ	

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//¸´ÓÃÍÆÍì
    GPIO_Init(GPIOB, &GPIO_InitStructure);		//³õÊ¼»¯IO
   
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//ÉÏÀ­ÊäÈë
    GPIO_Init(GPIOB, &GPIO_InitStructure);//³õÊ¼»¯IO
	  
 	//CANµ¥ÔªÉèÖÃ
  	CAN_InitStructure.CAN_TTCM=DISABLE;						 //·ÇÊ±¼ä´¥·¢Í¨ÐÅÄ£Ê½  //
    CAN_InitStructure.CAN_ABOM=DISABLE;						 //Èí¼þ×Ô¶¯ÀëÏß¹ÜÀí	 //
  	CAN_InitStructure.CAN_AWUM=DISABLE;						 //Ë¯ÃßÄ£Ê½Í¨¹ýÈí¼þ»½ÐÑ(Çå³ýCAN->MCRµÄSLEEPÎ»)//
  	CAN_InitStructure.CAN_NART=ENABLE;						 	//½ûÖ¹±¨ÎÄ×Ô¶¯´«ËÍ //
  	CAN_InitStructure.CAN_RFLM=DISABLE;						 //±¨ÎÄ²»Ëø¶¨,ÐÂµÄ¸²¸Ç¾ÉµÄ // 
  	CAN_InitStructure.CAN_TXFP=DISABLE;						 //ÓÅÏÈ¼¶ÓÉ±¨ÎÄ±êÊ¶·û¾ö¶¨ //
  	CAN_InitStructure.CAN_Mode= mode;	         //Ä£Ê½ÉèÖÃ£º mode:0,ÆÕÍ¨Ä£Ê½;1,»Ø»·Ä£Ê½; //
  	//ÉèÖÃ²¨ÌØÂÊ
  	CAN_InitStructure.CAN_SJW=tsjw;				//ÖØÐÂÍ¬²½ÌøÔ¾¿í¶È(Tsjw)Îªtsjw+1¸öÊ±¼äµ¥Î»  CAN_SJW_1tq	 CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq
  	CAN_InitStructure.CAN_BS1=tbs1; //Tbs1=tbs1+1¸öÊ±¼äµ¥Î»CAN_BS1_1tq ~CAN_BS1_16tq
  	CAN_InitStructure.CAN_BS2=tbs2;//Tbs2=tbs2+1¸öÊ±¼äµ¥Î»CAN_BS2_1tq ~	CAN_BS2_8tq
  	CAN_InitStructure.CAN_Prescaler=brp;            //·ÖÆµÏµÊý(Fdiv)Îªbrp+1	//
  	CAN_Init(CAN2, &CAN_InitStructure);            // ³õÊ¼»¯CAN1 

   	CAN_FilterInitStructure.CAN_FilterNumber=0;	  //¹ýÂËÆ÷0
  	CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; 
  	CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32Î» 
  	CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;////32Î»ID
  	CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
  	CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//32Î»MASK
  	CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
  	CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//¹ýÂËÆ÷0¹ØÁªµ½FIFO0
  	CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //¼¤»î¹ýÂËÆ÷0

  	CAN_FilterInit(&CAN_FilterInitStructure);//ÂË²¨Æ÷³õÊ¼»¯

	return 0;
}   

//can·¢ËÍÒ»×éÊý¾Ý(¹Ì¶¨¸ñÊ½:IDÎª0X12,±ê×¼Ö¡,Êý¾ÝÖ¡)	
//len:Êý¾Ý³¤¶È(×î´óÎª8)				     
//msg:Êý¾ÝÖ¸Õë,×î´óÎª8¸ö×Ö½Ú.
//·µ»ØÖµ:0,³É¹¦;
//		 ÆäËû,Ê§°Ü;
u8 Can_Send_Msg(u8* msg,u8 len)
{	
  u8 mbox;
  u16 i=0;
  CanTxMsg TxMessage;
  TxMessage.StdId=0x12;					 // ±ê×¼±êÊ¶·ûÎª0
  TxMessage.ExtId=0x12;				 // ÉèÖÃÀ©Õ¹±êÊ¾·û£¨29Î»£©
  TxMessage.IDE=0;			 // Ê¹ÓÃÀ©Õ¹±êÊ¶·û
  TxMessage.RTR=0;		 // ÏûÏ¢ÀàÐÍÎªÊý¾ÝÖ¡£¬Ò»Ö¡8Î»
  TxMessage.DLC=len;							 // ·¢ËÍÁ½Ö¡ÐÅÏ¢
  for(i=0;i<len;i++)
  TxMessage.Data[i]=msg[i];				 // µÚÒ»Ö¡ÐÅÏ¢          
  mbox= CAN_Transmit(CAN2, &TxMessage);   
  i=0;
  while((CAN_TransmitStatus(CAN2, mbox)==CAN_TxStatus_Failed)&&(i<0XFFF))i++;	//µÈ´ý·¢ËÍ½áÊø
  if(i>=0XFFF)return 1;
  return 0;		

}
//can¿Ú½ÓÊÕÊý¾Ý²éÑ¯
//buf:Êý¾Ý»º´æÇø;	 
//·µ»ØÖµ:0,ÎÞÊý¾Ý±»ÊÕµ½;
//		 ÆäËû,½ÓÊÕµÄÊý¾Ý³¤¶È;
u8 Can_Receive_Msg(u8 *buf)
{		   		   
 	u32 i;
	CanRxMsg RxMessage;
    if( CAN_MessagePending(CAN2,CAN_FIFO0)==0)return 0;		//Ã»ÓÐ½ÓÊÕµ½Êý¾Ý,Ö±½ÓÍË³ö 
    CAN_Receive(CAN2, CAN_FIFO0, &RxMessage);//¶ÁÈ¡Êý¾Ý	
    for(i=0;i<8;i++)
    buf[i]=RxMessage.Data[i];  
	return RxMessage.DLC;	
}

