Forum Discussion
Altera_Forum
Honored Contributor
9 years agoHi,
for you and the people of the future here the wrapper I used:module OC_Can_av_wrapper(
//Avalon common
input av_clk,
input av_reset,
//Avalon control port
input av_address,
input av_chipselect,
input av_write,
input av_read,
input av_writedata,
output av_readdata,
input av_byteenable,
output av_waitrequest_n,
// CAN interface
input CAN_clk,
input CAN_reset,
input CAN_rx,
output CAN_tx,
output CAN_bus_off,
output CAN_irq,
output CAN_clkout
);
wire wb_ack_o;
assign av_waitrequest_n = wb_ack_o;
assign av_readdata = 24'hz;
can_top wishbone_can_inst
(
.wb_clk_i(av_clk),
.wb_rst_i(av_reset | CAN_reset),
.wb_dat_i(av_writedata),
.wb_dat_o(av_readdata),
.wb_cyc_i(av_write | av_read),
.wb_stb_i(av_chipselect & (av_write | av_read)),
.wb_we_i(av_write & ~av_read),
.wb_adr_i({av_address}),
.wb_ack_o(wb_ack_o),
.clk_i(CAN_clk),
.rx_i(CAN_rx),
.tx_o(CAN_tx),
.bus_off_on(CAN_bus_off),
.irq_on(CAN_irq),
.clkout_o(CAN_clkout)
);
endmodule Using this wrapper, the addresses should be according to the data sheet. Here a little snippet I used to verify the correct behaviour: #include <stdio.h>
# include <io.h>
# include "system.h"
# include "sys/alt_stdio.h"
int main()
{
unsigned int temp;
int i = 0;
printf("Control Register \n");
temp = IORD(OC_CAN_VERILOG_WRAP_0_BASE,0x0000);
printf("%u : R %u \n",i,temp);
printf("Goint to OP mode \n");
IOWR_32DIRECT(OC_CAN_VERILOG_WRAP_0_BASE,0,32);
temp = IORD_32DIRECT(OC_CAN_VERILOG_WRAP_0_BASE,0x0000);
printf("%u : R %u \n",i,temp);
/*printf("Goint to reset mode \n");
IOWR_32DIRECT(OC_CAN_VERILOG_WRAP_0_BASE,0,32);
temp = IORD_32DIRECT(OC_CAN_VERILOG_WRAP_0_BASE,0x0000);
printf("%u : R %u \n",i,temp); */
printf("Double check \n");
temp = IORD(OC_CAN_VERILOG_WRAP_0_BASE,0x0000);
printf("%u : R %u \n",i,temp);
printf("Read Clock Divider Reg \n");
i=31;
temp = IORD(OC_CAN_VERILOG_WRAP_0_BASE,31);
printf("%u : R %u \n",i,temp);
printf("Set it to extended mode \n");
IOWR(OC_CAN_VERILOG_WRAP_0_BASE,31,128);
temp = IORD(OC_CAN_VERILOG_WRAP_0_BASE,31);
printf("%u : R %u \n",i,temp);
printf("And back \n");
IOWR(OC_CAN_VERILOG_WRAP_0_BASE,31,0);
temp = IORD(OC_CAN_VERILOG_WRAP_0_BASE,31);
printf("%u : R %u \n",i,temp);
for(i = 1; i < 32; i++) {
IOWR_32DIRECT(OC_CAN_VERILOG_WRAP_0_BASE,i*4,0);
temp = IORD_32DIRECT(OC_CAN_VERILOG_WRAP_0_BASE,i*4);
printf("%u: R %u \n",i,temp);
}
printf("Goint to reset mode \n");
IOWR_32DIRECT(OC_CAN_VERILOG_WRAP_0_BASE,0,33);
temp = IORD_32DIRECT(OC_CAN_VERILOG_WRAP_0_BASE,0x0000);
printf("%u : R %u \n",i,temp);
printf("Double check \n");
temp = IORD(OC_CAN_VERILOG_WRAP_0_BASE,0x0000);
for(i = 1; i < 32; i++) {
IOWR_32DIRECT(OC_CAN_VERILOG_WRAP_0_BASE,i*4,0);
temp = IORD_32DIRECT(OC_CAN_VERILOG_WRAP_0_BASE,i*4);
printf("%u: R %u \n",i,temp);
}
printf("\nDONE");
return 0;
} I mixed a bit the use of IO** and IO**_32DIRECT. This shouldn't be a problem as long as you are aware of the difference (see this thread (http://www.alteraforum.com/forum/showthread.php?t=32282)). The activation of the reset mode is commented to test if the core can just be set to extended mode if in reset mode (see data sheet (http://www.nxp.com/documents/data_sheet/sja1000.pdf) at page 56). I hope this helps!