202 lines
4.6 KiB
C
202 lines
4.6 KiB
C
|
|
#include "Includes.h"
|
|
|
|
|
|
typedef struct{
|
|
uint32_t id28_18:11;
|
|
uint32_t id17_00:18;
|
|
uint32_t ide:1;
|
|
uint32_t rtr:1;
|
|
uint32_t NA0:1;
|
|
uint32_t len;
|
|
uint8_t dat[8];
|
|
}CAN_INFO;
|
|
|
|
void can_pin_init(void)
|
|
{
|
|
gpio_mux_ctl(8,2);//tx
|
|
gpio_mux_ctl(9,2);//rx
|
|
}
|
|
/*
|
|
FPGA OSC_12M
|
|
tq=2*tclk(BRP+1) //CAN_BTR0->BRP
|
|
|
|
Tsyncseg=1*tq
|
|
Ttseg1=tq*(TSEG1+1) //CAN_BTR1->TSEG1
|
|
Ttseg2=tq*(TSEG2+1) //CAN_BTR1->TSEG2
|
|
|
|
can_baud=1/(Tsyncseg+Ttseg1+Ttseg2)
|
|
=1/(tq*(1+6+1+7+1))
|
|
=1/(tq*16)
|
|
=1/(16*2*tclk*(2+1))
|
|
=1/(16*6*tclk)
|
|
=1/(96*tclk)
|
|
=1/(96*(1/12M))=12M/96=12000000/96=125000bps
|
|
*/
|
|
|
|
void can_init(void)
|
|
{
|
|
|
|
|
|
__write_hw_reg32(((volatile unsigned *)(CPR_BASE+0x24)),0x00110014);//CPR_CTL_PCLK_GRCTL(pclk=mclk/2)
|
|
CPR_CAN_CLK_CTL->CAN_PCLK_EN=1;
|
|
CPR_CAN_CLK_CTL->CAN_MCLK_EN=1;
|
|
CPR_CAN_CLK_CTL->CAN_MCLK_DIV=0;
|
|
|
|
CAN_CDR->CDR3=0x07;
|
|
CAN_CDR->CDR4=0x0C;
|
|
// CAN_IER->TIE=1;
|
|
CAN_IER->RIE=1;
|
|
|
|
CAN_MOD->RM=1;
|
|
//config can baud
|
|
CAN_OCR->OCMODE=2;
|
|
CAN_BTR0->BRP=2;
|
|
CAN_BTR0->SJW=2;
|
|
CAN_BTR1->TSEG2=7;
|
|
CAN_BTR1->TSEG1=6;
|
|
//config can filter
|
|
CAN_MOD->AFM=1;//single filter
|
|
*CAN_ACR0=0x00;//id28-21
|
|
*CAN_ACR1=0x00;//id20-13
|
|
*CAN_ACR2=0x00;//id12-05
|
|
*CAN_ACR3=0x00;//id04-00 +rtr
|
|
*CAN_AMR0=0x00;//1 identify the corresponding bits as do not care
|
|
*CAN_AMR1=0x10;
|
|
*CAN_AMR2=0x00;
|
|
*CAN_AMR3=0x04;//*CAN_AMR3=0x04;
|
|
|
|
CAN_MOD->RM=0;
|
|
//config rev filter
|
|
|
|
|
|
}
|
|
uint8_t Buffer_Released,Transmission_Complete;
|
|
uint8_t can_send_mes(CAN_INFO *can_information)
|
|
{
|
|
uint8_t fifo_index;
|
|
//if(CAN_SR->TBS == 0) return 1;// CAN_SR->TBS ----volatile
|
|
while(CAN_SR->TBS == 0); //wait transmit buffer released. CAN_SR->TBS ----volatile
|
|
*CAN_FI = (can_information->len&(0xF))|((can_information->rtr)<<6)|((can_information->ide)<<7);//1:remote frame , 0:data frame
|
|
if(can_information->ide){//extended frame format
|
|
*CAN_ID1=(can_information->id28_18)>>3;
|
|
*CAN_ID2=(((can_information->id28_18)&0x07)<<5)|((can_information->id17_00)>>13);
|
|
*CAN_ID3=((can_information->id17_00)>>5)&0xFF;
|
|
*CAN_ID4=((can_information->id17_00)&0x1F)<<3;
|
|
fifo_index=2;
|
|
}else{ //standard frame format
|
|
*CAN_ID1=(can_information->id28_18)>>3;
|
|
*CAN_ID2=((can_information->id28_18)&0x07)<<5;
|
|
fifo_index=0;
|
|
}
|
|
if(can_information->rtr == 0)
|
|
{
|
|
for(uint8_t i=0;i<8;i++)
|
|
{
|
|
__write_hw_reg32(CAN_TX_BUFF(fifo_index++), can_information->dat[i]); //set transmission data
|
|
}
|
|
}
|
|
CAN_CMR->TR=0x01;
|
|
return 0;
|
|
}
|
|
|
|
uint8_t can_receive_msg(CAN_INFO *can_information)
|
|
{
|
|
uint8_t fifo_index;
|
|
if(CAN_SR->RBS==0) return 0;
|
|
can_information->ide = *CAN_FI&0x80 ? 1:0; /*0:standard_frame , 1:extended_frame*/
|
|
can_information->rtr = *CAN_FI&0x40 ? 1:0; /*0:data frame , 1:remote frame */
|
|
can_information->len = *CAN_FI&0xF;
|
|
if(can_information->len>8)
|
|
{
|
|
can_information->len=8;
|
|
}
|
|
can_information->id28_18=(*CAN_ID1<<3)|(*CAN_ID2>>5);
|
|
if(can_information->ide){//1:extended
|
|
can_information->id17_00=((*CAN_ID2&0x1F)<<13)|(*CAN_ID3<<5)|(*CAN_ID4>>3);
|
|
fifo_index=2;
|
|
}else{//1:standard
|
|
fifo_index=0;
|
|
}
|
|
if(can_information->rtr==0)
|
|
{
|
|
for(int i=0;i<can_information->len;i++)
|
|
{
|
|
__read_hw_reg32(CAN_RX_BUFF(fifo_index++), can_information->dat[i]);
|
|
}
|
|
}
|
|
CAN_CMR->RRB=1; /* Release the FIFO */
|
|
return can_information->len;
|
|
|
|
|
|
}
|
|
void tx_msg(void)
|
|
{
|
|
static CAN_INFO can_tmsg={
|
|
.rtr=0,//1:remote frame , 0:data frame
|
|
.ide=1,//1:extended frame format , 0:standard frame format
|
|
.len=8,
|
|
.id28_18=0x12,
|
|
.id17_00=0x73,
|
|
.dat[0]=0x01,
|
|
.dat[1]=0x02,
|
|
.dat[2]=0x03,
|
|
.dat[3]=0x04,
|
|
.dat[4]=0x05,
|
|
.dat[5]=0x06,
|
|
.dat[6]=0x07,
|
|
.dat[7]=0x08,
|
|
};
|
|
#if 1 //tx
|
|
can_tmsg.dat[0]++;
|
|
if(can_tmsg.rtr)//1: remote frame(remote frame has no data part)
|
|
{
|
|
if(can_tmsg.len>=8)
|
|
{
|
|
can_tmsg.len=1;//request length
|
|
}else
|
|
{
|
|
can_tmsg.len++;//request length
|
|
}
|
|
}
|
|
can_send_mes(&can_tmsg);
|
|
#endif
|
|
|
|
|
|
|
|
|
|
}
|
|
void rx_msg(void)
|
|
{
|
|
CAN_INFO can_rmsg;
|
|
if(can_receive_msg(&can_rmsg))
|
|
{
|
|
printf("id28_18=%#x ,id17_00=%#x ,rtr=%#x ,ide=%#x ,len=%#x \n",can_rmsg.id28_18,can_rmsg.id17_00,can_rmsg.rtr,can_rmsg.ide,can_rmsg.len);
|
|
if(can_rmsg.rtr==0)
|
|
{
|
|
printf("dat:");
|
|
for(int i=0;i<can_rmsg.len;i++) printf("%#x ",can_rmsg.dat[i]);
|
|
printf("\n");
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
void CAN_Handler(void)
|
|
{
|
|
rx_msg();
|
|
}
|
|
void test_can(void)
|
|
{
|
|
can_pin_init();
|
|
can_init();
|
|
NVIC_EnableIRQ(CAN_IRQn);
|
|
while(1)
|
|
{
|
|
tx_msg();
|
|
|
|
}
|
|
|
|
|
|
}
|