Thanks so much for the help. I went back and started looking at my code again used the CAN calculator mentioned in JPortici's post and lo and behold I had been using Fcy to calculate my numbers instead of Fcan
! So I made that change and I also set up the receive buffers and DMA channel, and it works!! Well sort of, I am now getting a stuff error after every successful transmission. It looks like it is starting another transmission right after the first one and then aborting after the start of frame is sent. Maybe something else is interrupting it?
could be, could be not
https://www.kvaser.com/about-can/the-can-protocol/can-error-handling/ (go to Bit Stuffing)
a stuff condition is seen, doesn't mean it's an error
I happen to know the guy that wrote the code for that demo board (he once was a microchip FAE, he now builds killer synthesizers!
http://www.synthtech.com/ )
it's failry easy to understand, but i decided to throw all the CAN part away and write my own, one bit at a time until i had my library.
It is just a suggestion but divide your problem in three parts
1) the application code, with its buffers and data, with interfaces that generate can frames and retreive data from single frames
2) the can protocol code, which has its buffers for can RX and TX and handles stuff like networking (ISO15765-2 and -3 for example). here i defined my can_t frame (ID, flags, data) and can_buffer_t
3) the device specific code, so the interrupts, configuration and the interfaces that get a can_t frame and stuff the registers or the hardware buffers in the format required by the MCU and vice-versa. This is the part that you will have to change when porting code.
Case in point, i have designed a couple of OBD gadgets i ported between three architectures in which
1) Has the error codes list, status variables, IO over can handling etc. It also has the state machine that runs in the superloop so it doesn't hang in there too much
2) Is the code that get CAN frames and put them in a separate frame types which i called uds_t and obd_t which have a DTC list, size, index for read/write etc. Also handles the merging and splitting of multi-frame messages
3) Is the only part of code i had to change, no issues at all.
the three architectures were dsPIC33EV, PIC32MX and ATSAMC21. Luckily for me the 33EV and the 32MX both use the same CAN IP from kvaser, but with minor differences in other registers and how DMA plays a role in the peripheral (mandatory in the dsPIC and eats up two channels, dedicated in the PIC32) whereas the ATSAM used a completely different peripheral. Easy peasy.