Forum Discussion
Altera_Forum
Honored Contributor
9 years agoHi, I need help, I'm testing the CAN controller with a DE0-nano board and I used the wrapper and it works fine, I have made the software test and it responds, but when I try to send a message, the can controller generates errors (reflected in the status reg). I'm using a 25Mhz can clock and I don't know what else should I test, can you help me, I send the code used in software to test and send a message.
main program code:
printf("Start CAN operation:\n");
unsigned int temp;
i=0;
read_status();
reset_mode();
read_status();
op_mode();
read_status();
can_init(Basic_can , 0x00FF, 0x00FF, Fosc_14);
read_status();
can_tx= 0x0F;
can_tx= 0x0E;
can_tx= 0x0D;
can_tx= 0x0C;
can_tx= 0x0B;
can_tx= 0x0A;
can_tx= 0xF1;
can_tx= 0xF7;
reset_mode();
read_regs_can();
op_mode();
read_regs_can();
send_msg(can_tx, 0x0001, 0x08, 0);
read_regs_can();
read_status();
while(1)
{}
in a header file (M_can.h) I define:# define Basic_can 0x00# define Peli_can 0x80# define Fosc_14 0x06# define Bus_Tx_libre 0x0C in a source file (M_can.c) I define the functions: # include"M_can.h"
# include <stdio.h># include <string.h>
void reset_mode()
{
unsigned char temp;
printf("Reset mode\n");
temp = IORD_32DIRECT(CAN_CONTROLLER_0_BASE,0x0000);
printf("%u : Reg %X h \n",0,temp);
printf("%u : Reg %u decimal \n",0,temp);
IOWR_32DIRECT(CAN_CONTROLLER_0_BASE,0, (temp | 0x01));
temp = IORD_32DIRECT(CAN_CONTROLLER_0_BASE,0x0000);
printf("%u : Reg %X h \n",0,temp);
printf("%u : Reg %u decimal \n",0,temp);
}
void op_mode()
{
unsigned char temp;
printf("OP mode:\n");
temp = IORD_32DIRECT(CAN_CONTROLLER_0_BASE,0x0000);
printf("%u : Reg %X h \n",0,temp);
printf("%u : Reg %u decimal \n",0,temp);
IOWR_32DIRECT(CAN_CONTROLLER_0_BASE,0, (0xFE & temp));
temp = IORD_32DIRECT(CAN_CONTROLLER_0_BASE,0x0000);
printf("%u : Reg %X h \n",0,temp);
printf("%u : Reg %u decimal \n",0,temp);
}
unsigned char read_status()
{
unsigned char status;
printf("reading status \n");
status = IORD(CAN_CONTROLLER_0_BASE,2);
printf("Now %u : Reg %X h \n",2,status);
printf("%u : Reg %u decimal \n",2,status);
return(status);
}
void read_regs_can(void)
{
int i;
unsigned char temp;
for(i = 0; i < 32; i++)
{
temp = IORD_32DIRECT(CAN_CONTROLLER_0_BASE,i*4);
printf("Reg %u : %X h ",i,temp);
printf("Reg %u: %u decimal \n",i,temp);
}
}
void send_msg(unsigned char *vector, unsigned int id, unsigned char long_bytes_msg, unsigned char rtr)
{
unsigned char filtro_h, filtro_l, status;
int i;
printf("sending msg");
status=0x00;
filtro_h = (id >> 3);
filtro_l = (id << 5);
if (rtr ==1)
filtro_l = filtro_l | 0x10;
if(long_bytes_msg > 0x08)
long_bytes_msg = 0x08;
filtro_l = filtro_l | long_bytes_msg;
IOWR(CAN_CONTROLLER_0_BASE,10,filtro_h);
IOWR(CAN_CONTROLLER_0_BASE,11,filtro_l);
for(i=0 ; i<long_bytes_msg ; i++)
{
IOWR(CAN_CONTROLLER_0_BASE,(12+i),*vector);
vector = vector+1;
}
// sending request
IOWR(CAN_CONTROLLER_0_BASE,1,0x01);
while(status != Bus_Tx_free)
{
status = read_status();
status = status & Bus_Tx_libre;
}
printf("Msg Sended \n");
}
void can_init(unsigned char mode, unsigned int masc, unsigned int filtro, unsigned char fout)
{
printf("init can \n");
unsigned char temp;
reset_mode();
temp = modo | fout;
temp = temp | 0x60;
IOWR(CAN_CONTROLLER_0_BASE,31,temp);
IOWR(CAN_CONTROLLER_0_BASE,4,filtro);
config_timing_reg(1000000, SJW_1, SAM_1);
config_output(normal_mode, push_pull);
op_mode();
printf("end init \n");
}
void config_timing_reg(float frec_CAN, unsigned char SJW, unsigned char muest)
{
float BRP;
unsigned int BRP_int;
unsigned char temp, temp2;
BRP = (( (F_crystal * T_crystal) / (2.0) ) - 1.0);
BRP_int = BRP; // casting a int.
temp = BRP_int; // casting a char.
temp = SJW | temp;
IOWR(CAN_CONTROLLER_0_BASE,6,temp);
temp2 = muest | seg1 | seg2;
IOWR(CAN_CONTROLLER_0_BASE,7,temp2);
}
void config_output(unsigned char mode, unsigned char output_pol)
{
unsigned char temp;
temp= mode | output_pol;
IOWR(CAN_CONTROLLER_0_BASE,8,temp);
}
when I test the main program, the CAN controller send bits in the Tx pin, but then the Bus_off pin changes and in the status reg I see the 0xD4h errors, I don't know if maybe the process of sending the message is right. thanks.