CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

CAN you help (pun intended!)
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ferrumvir



Joined: 01 Feb 2006
Posts: 64
Location: England

View user's profile Send private message Visit poster's website

CAN you help (pun intended!)
PostPosted: Fri Apr 07, 2006 8:24 am     Reply with quote

Hi,

I've been struggling with getting CAN to work for too long now and even after reading a great deal on the forum, I'm still stumped.

CAN you help.

What appears to be happening (I'm asssuming quite a bit here), the PIC recieves/sends a message, a device thinks there is an error, sends an error frame and therefore the message is re-transmitted (over and over and over). The external CAN devices go into error... The TX-RX work fine on the CAN BUS until the PIC device is powered/connected

This appears to be happening whether the PIC originated the message or another device.

To assist with the diagnosis here is some information

I'm using PIC18F258 connected to MCP2551

First question is: have I got the wiring correct?

PIC18F258 PIN B2 CANTX > MCP2551 TXD
PIC18F258 PIN B3 CANRX > MCP2551 RXD
5V (with capacitor to 0V) > MCP2551 VDD
0V > MCP2551 VSS + MCP2551 RS
MCP2551 pins CANH and CANL connected to the CAN BUS
MCP2551 pin Vref unconnected

I'm trying to get the EX_CAN.C example working... I've started by setting the baud rate using "Microchip CAN Bit Timing Calculator" (see in the code)

I've checked with an oscilloscope and the TX message appears to have the correct bit timing. Incomming messages also have correct bit timing.

I've tried 2 different BAUD rates and get the same results.

I've also taken out the transmit section from EX_CAN.C, but get the same effect, but at least I know that the message originated from a good/working device.

The following code extract contain the modifications I've made to EX_CAN.C

changes are marked with // CHANGED and additions are between the // ADDITIONAL comments.

Code:

// CHANGED #include <18F248.h>
#include <18F258.h>
#fuses HS,NOPROTECT,NOLVP,NOWDT
// CHANGE #use delay(clock=20000000)
#use delay(clock=10000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)  // Jumpers: 8 to 11, 7 to 12

// ADDITIONAL

// BAUD RATE DEFINITION OVERRIDES

//#DEFINE CAN_500K

#IFDEF CAN_500K // ( tq = 0.200 us )
 #define CAN_BRG_PRESCALAR          0             //baud rate generator prescalar (def: 4) ( Tq = (2 x (PRE + 1))/Fosc )
 #define CAN_BRG_SYNCH_JUMP_WIDTH   1             //synchronized jump width (def: 1 x Tq)
 #define CAN_BRG_PROPAGATION_TIME   1             //propagation time select (def: 3 x Tq)
 #define CAN_BRG_PHASE_SEGMENT_1    5             //phase segment 1 (def: 6 x Tq)
 #define CAN_BRG_PHASE_SEGMENT_2    3             //phase segment 2 time select (def: 6 x Tq)
#ELSE //125K ( tq = 1.000 us )
 #define CAN_BRG_PRESCALAR          4             //baud rate generator prescalar (def: 4) ( Tq = (2 x (PRE + 1))/Fosc )
 #define CAN_BRG_SYNCH_JUMP_WIDTH   1             //synchronized jump width (def: 1 x Tq)
 #define CAN_BRG_PROPAGATION_TIME   1             //propagation time select (def: 3 x Tq)
 #define CAN_BRG_PHASE_SEGMENT_1    3             //phase segment 1 (def: 6 x Tq)
 #define CAN_BRG_PHASE_SEGMENT_2    3             //phase segment 2 time select (def: 6 x Tq)
#ENDIF

// NON-BAUD RATE DEFINITION OVERRIDES

#define CAN_USE_EXTENDED_ID         FALSE
#define CAN_USE_RX_DOUBLE_BUFFER    FALSE        //if buffer 0 overflows, do NOT use buffer 1 to put buffer 0 data
#define CAN_ENABLE_DRIVE_HIGH       1

//TRIED FALSE FALSE 1 - FAILED
//TRIED FALSE FALSE 0 - FAILED
//TRIED TRUE  FALSE 1 - FAILED
//TRIED TRUE  FALSE 0 - FAILED


// END ADDITIONAL

#include <can-18xxx8.c>



From here on down EX_CAN.C is unchanged. (except commenting out the TX section!)

I'm just going through a binary search of the three parameters at the the bottom, all of which have failed, so far.

CAN anyone spot what I'm doing wrong? or offer any ideas as to what to try.

Thanks in advance for any help.

Cheers Scott
sjbaxter



Joined: 26 Jan 2006
Posts: 141
Location: Cheshire, UK

View user's profile Send private message Visit poster's website

PostPosted: Fri Apr 07, 2006 9:56 am     Reply with quote

If the other devices work ok then the usual cause of error frames is either the erroneous node is set to the wrong bit rate, has extended ids (29bit) setup when it should be standard (11 bit) or visa versa, the bus isn't terminated properly or the node is holding the bus in a dominant state. i.e the TX input th the CAN transceiver is perminently low or shorted to ground.

Your pinout of the transceiver looks ok.

In the register selections, dont forget that the BIT time calc gives values ranging from 1 upwards. The PIC however has registers that are zero based (the calc gives number of Tq's, etc. not register values). Use the 'configuration register setup' on the report to confirm the values you set. What bit rate are you using ? 125KBit/sec ?

I notice you have commented out the 20MHz clock and used 10MHz instead. Are the calculated values for baud based on 10 or 20 ?

try...
Code:
//125K @ 10Mhz
#define CAN_BRG_PRESCALAR          3
#define CAN_BRG_SYNCH_JUMP_WIDTH   0
#define CAN_BRG_PROPAGATION_TIME   0
#define CAN_BRG_PHASE_SEGMENT_1    4
#define CAN_BRG_PHASE_SEGMENT_2    2

_________________
Regards,
Simon.


Last edited by sjbaxter on Sun Apr 09, 2006 3:29 am; edited 1 time in total
jma_1



Joined: 08 Feb 2005
Posts: 147
Location: Wisconsin

View user's profile Send private message

PostPosted: Fri Apr 07, 2006 12:06 pm     Reply with quote

Perhaps try changing the default 'CAN_ENABLE_DRIVE_HIGH' (default 0).

// change CAN_ENABLE_DRIVE_HIGH = 1
// 1=cantx PIN WILL DRIVE VDD WHEN RECESSIVE
// 0=cantx PIN WILL BE TRI-STATE WHEN RECESSIVE

Cheers,
Justin
sjbaxter



Joined: 26 Jan 2006
Posts: 141
Location: Cheshire, UK

View user's profile Send private message Visit poster's website

PostPosted: Fri Apr 07, 2006 12:48 pm     Reply with quote

jma_1, looking to his code he already overrides the default.

Although it is a common problem with tranceivers that don't have input pull up resistors fitted i.e. PCA82C250/251 and TJA1050. The effect is that the TX input to the transceiver 'floats' causing random errors on the bus.

I think the MCP2551 has pullups built in so it can be left as 0 for these devices.

It looks more like the wrong speed is configured.
_________________
Regards,
Simon.
ferrumvir



Joined: 01 Feb 2006
Posts: 64
Location: England

View user's profile Send private message Visit poster's website

PostPosted: Fri Apr 07, 2006 3:35 pm     Reply with quote

sjbaxter,

Thanks for confirming the pinouts on the MCP2551, that made me feel a little better.

Thanks again... I tried your CAN_BRG assignments, for baud rate 125k @ 10MHz and things have started to work. Not completely (that'd be expecting too much) but the messages are no longer causing errors. I've now commented back in the TX section of EX_CAN.C and my other devices are now recieving a message. Smile

Unfortunately, there is no data in the signal message (see below for the outgoing message data change), only zeros are recieved, and the PIC does not appear to recieve any messages, i.e. only outgoing messages come back on the RS232. Sad

Code:

   for (i=0;i<8;i++) {
      out_data[i]=0xC0+i;
      in_data[i]=0;
   }


Yes, I'm trying to run 125k, Can you explain the timings?

I (until I found the "Microchip CAN Bit Timing Calculator") was using the following equations, which are straight from the PIC18F258 manual. Which only confirms what the Calculator was generating.

Rate = 1/TBIT
TBIT = TQ * SEG
TQ = (2*(BRP+1))/FOSC

Where SEG, and BRP are the variables to work with. And still work (obviously they don't work but the maths adds up!) for the values I had set.

125K @ 10MHz (BRG=4 SEG = 1+1+3+3)

TQ = (2*(4+1))/10000000 = 0.000001s =1us
TBIT = TQ * 8 = 0.000008s = 8us
Rate = 1/0.000008 = 125000 = 125kbps

But this does not work and the figures you gave do! Am I rightly confused, I am confused, or am I missing the point? Confused

Thanks for your help,

jma_1, I'd tried both but with no luck... until now...

I'm going to see if I can figure out the total lack of incomming messages and the NULL data on the outgoing messages. If anyone CAN help, that'd be great.

Cheers Scott
sjbaxter



Joined: 26 Jan 2006
Posts: 141
Location: Cheshire, UK

View user's profile Send private message Visit poster's website

PostPosted: Fri Apr 07, 2006 4:17 pm     Reply with quote

Scott,

I'm not sure why you aren't getting messages and the data is all zero that you transmit.

Have you passed a dlc of 8 to can_putd. i.e.

Code:
int8 i;

int32 id;
int1 rtr;
int1 ext;
int8 data[8];
int8 dlc;
int8 priority;

// setup the TX message
id = 100;
rtr = 0;
ext = 0;
priority = 3;
for (i=0; i<8;i++)
    data[i] = 0xC0 + i;
dlc = 8;

// send the message
can_putd(id, &data[0], dlc, priority, ext, rtr);


You need to post a few code snippets containing the steps leading upto the call to can_putd(...) and how you are waiting for messages to arrive (i.e. are you using interrupts or polling).

As for the registers, the values you have calculated give you the number of Time Quanta (Tq) for each phase of the bit sampling. The can_init actually sets the configuration registers in the PIC. The corrolation between the two is not a 1 to 1 relationship (have a read of the datasheet section 19.2.4) you will see that 1 x Tq for SJW is actually SJW=0, 2 x Tq = 1, etc. It is the same for the BAUD RATE CONTROL registers.
_________________
Regards,
Simon.
ferrumvir



Joined: 01 Feb 2006
Posts: 64
Location: England

View user's profile Send private message Visit poster's website

PostPosted: Fri Apr 07, 2006 4:44 pm     Reply with quote

Thanks sjbaxster,

I was just about to post that the penny had dropped on how you'd got the can timing to work, when I read you post re-explaining (to the thicky in the corner).

Code:

#define CAN_BRG_SYNCH_JUMP_WIDTH   0
#define CAN_BRG_PROPAGATION_TIME   0
#define CAN_BRG_PHASE_SEGMENT_1    4
#define CAN_BRG_PHASE_SEGMENT_2    2


Actually means 1, 1, 5, 3 = 10 SEG Embarassed

dlc or tx_len as it is in the examples is set to eight.

I'm using the EX_CAN.C code and all the changes I've made I've put in the code segments. But here is the full code anyway

Code:

/////////////////////////////////////////////////////////////////////////
////        (C) Copyright 1996,2003 Custom Computer Services         ////
//// This source code may only be used by licensed users of the CCS  ////
//// C compiler.  This source code may only be distributed to other  ////
//// licensed users of the CCS C compiler.  No other use,            ////
//// reproduction or distribution is permitted without written       ////
//// permission.  Derivative programs created using this software    ////
//// in object code form are not restricted in any way.              ////
/////////////////////////////////////////////////////////////////////////

// CHANGED #include <18F248.h>
#include <18F258.h>
#fuses HS,NOPROTECT,NOLVP,NOWDT
// CHANGE #use delay(clock=20000000)
#use delay(clock=10000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)  // Jumpers: 8 to 11, 7 to 12

// ADDITIONAL

// BAUD RATE DEFINITION OVERRIDES

//#DEFINE CAN_500K

#IFDEF CAN_500K // ( tq = 0.200 us )
 #define CAN_BRG_PRESCALAR          0             //baud rate generator prescalar (def: 4) ( Tq = (2 x (PRE + 1))/Fosc )
 #define CAN_BRG_SYNCH_JUMP_WIDTH   1             //synchronized jump width (def: 1 x Tq)
 #define CAN_BRG_PROPAGATION_TIME   1             //propagation time select (def: 3 x Tq)
 #define CAN_BRG_PHASE_SEGMENT_1    5             //phase segment 1 (def: 6 x Tq)
 #define CAN_BRG_PHASE_SEGMENT_2    3             //phase segment 2 time select (def: 6 x Tq)
#ELSE //125K ( tq = 1.000 us )
/* NOT WORKING
#define CAN_BRG_PRESCALAR          4             //baud rate generator prescalar (def: 4) ( Tq = (2 x (PRE + 1))/Fosc )
#define CAN_BRG_SYNCH_JUMP_WIDTH   1             //synchronized jump width (def: 1 x Tq)
#define CAN_BRG_PROPAGATION_TIME   1             //propagation time select (def: 3 x Tq)
#define CAN_BRG_PHASE_SEGMENT_1    3             //phase segment 1 (def: 6 x Tq)
#define CAN_BRG_PHASE_SEGMENT_2    3             //phase segment 2 time select (def: 6 x Tq)
*/// NOT WORKING
// WORKING
#define CAN_BRG_PRESCALAR          3
#define CAN_BRG_SYNCH_JUMP_WIDTH   0
#define CAN_BRG_PROPAGATION_TIME   0
#define CAN_BRG_PHASE_SEGMENT_1    4
#define CAN_BRG_PHASE_SEGMENT_2    2
// WORKING
/*// TEST - ALSO WORKING
#define CAN_BRG_PRESCALAR          4
#define CAN_BRG_SYNCH_JUMP_WIDTH   0
#define CAN_BRG_PROPAGATION_TIME   0
#define CAN_BRG_PHASE_SEGMENT_1    2
#define CAN_BRG_PHASE_SEGMENT_2    2
*/// TEST - ALSO WORKING

#ENDIF

// NON-BAUD RATE DEFINITION OVERRIDES

#define CAN_USE_EXTENDED_ID         FALSE
#define CAN_USE_RX_DOUBLE_BUFFER    FALSE       //if buffer 0 overflows, do NOT use buffer 1 to put buffer 0 data
#define CAN_ENABLE_DRIVE_HIGH       1
#define CAN_ENABLE_CAN_CAPTURE      0

// USED TO CHECK VERSION CORRECTLY PROGRAMMED ON PIC
#define MY_VERSION 24

// TRIED TRUE TRUE 0 0 - FAILED (DEFAULT)
// TRIED TRUE TRUE 1 0 - FAILED
// TRIED FALSE TRUE 0 0 - FAILED
// TRIED FALSE TRUE 1 0 - FAILED
// TRIED TRUE FALSE 0 0 - FAILED
// TRIED TRUE FALSE 1 0 - FAILED
// TRIED FALSE FALSE 0 0 - FAILED
// TRIED FALSE FALSE 1 0 - FAILED

// END ADDITIONAL

#include <can-18xxx8.c>

int16 ms;

#int_timer2
void isr_timer2(void) {
   ms++; //keep a running timer that increments every milli-second
}

void main() {
   struct rx_stat rxstat;
   int32 rx_id;
   int in_data[8];
   int rx_len;

//send a request (tx_rtr=1) for 8 bytes of data (tx_len=8) from id 24 (tx_id=24)
   int out_data[8];
   int32 tx_id=24;
   int1 tx_rtr=1;
   int1 tx_ext=0;
   int tx_len=8;
   int tx_pri=3;

   int i;

   for (i=0;i<8;i++) {
// CHANGED      out_data[i]=0;
      out_data[i]=0xC0+i;
      in_data[i]=0;
   }

   printf("\r\n\r\nCCS CAN EXAMPLE\r\n");

   setup_timer_2(T2_DIV_BY_4,79,16);   //setup up timer2 to interrupt every 1ms if using 20Mhz clock

   can_init();

   enable_interrupts(INT_TIMER2);   //enable timer2 interrupt
   enable_interrupts(GLOBAL);       //enable all interrupts (else timer2 wont happen)

// CHANGED  printf("\r\nRunning...");
   printf("\r\nRunning...%d",MY_VERSION);

   while(TRUE)
   {

      if ( can_kbhit() )   //if data is waiting in buffer...
      {
         if(can_getd(rx_id, &in_data[0], rx_len, rxstat)) { //...then get data from buffer
            printf("\r\nGOT: BUFF=%U ID=%LU LEN=%U OVF=%U ", rxstat.buffer, rx_id, rx_len, rxstat.err_ovfl);
            printf("FILT=%U RTR=%U EXT=%U INV=%U", rxstat.filthit, rxstat.rtr, rxstat.ext, rxstat.inv);
            printf("\r\n    DATA = ");
            for (i=0;i<rx_len;i++) {
               printf("%X ",in_data[i]);
            }
            printf("\r\n");
         }
         else {
            printf("\r\nFAIL on GETD\r\n");
         }

      }

      //every two seconds, send new data if transmit buffer is empty
      if ( can_tbe() && (ms > 2000))
      {
         ms=0;
         i=can_putd(tx_id, out_data, tx_len,tx_pri,tx_ext,tx_rtr); //put data on transmit buffer
         if (i != 0xFF) { //success, a transmit buffer was open
            printf("\r\nPUT %U: ID=%LU LEN=%U ", i, tx_id, tx_len);
            printf("PRI=%U EXT=%U RTR=%U\r\n   DATA = ", tx_pri, tx_ext, tx_rtr);
            for (i=0;i<tx_len;i++) {
               printf("%X ",out_data[i]);
            }
            printf("\r\n");
         }
         else { //fail, no transmit buffer was open
            printf("\r\nFAIL on PUTD\r\n");
         }
      }

   }
}


Thanks for all your help.

Cheers Scott
sjbaxter



Joined: 26 Jan 2006
Posts: 141
Location: Cheshire, UK

View user's profile Send private message Visit poster's website

PostPosted: Sat Apr 08, 2006 2:48 am     Reply with quote

Scott,

You are sending remote frames. These are requests for data from another node. They send NO data, only an id and the requested data length (dlc). As you are populating the out_data, I suspect this isn't what you were after.

change...

Code:
tx_rtr=1;


to

Code:
tx_rtr=0;


if you are sending a data frame then this needs to be zero. Setting to 1 will send a remote frame, which isn't what is required in this instance. This looks like a simple 'send a message at a specifed interval' and receive 'any message that is present on the bus'.

One note here .... if the bus load is medium to high, then you may want to consider using the #fuses H4 option instead of HS to step the clock upto 40MHz and/or utilize CAN RX filters. Otherwise the PIC will get bogged down with message or even miss quite a few. Also, consider using interrupts.

Remote frames only work if the target node supports them. i.e. the remote node's controller, which has direct access to the requested message object/data, automatically sends the data for the requested id. For simple controllers this request is passed onto the node micro which needs to generate the response.

Generally CAN networks (that I have been involved with, in the automotive and aerospace fields, don't use remote frames.) request/responses are usually done using a protocol layered on CAN.

BTW : What compiler version are you using ?
_________________
Regards,
Simon.
ferrumvir



Joined: 01 Feb 2006
Posts: 64
Location: England

View user's profile Send private message Visit poster's website

PostPosted: Sat Apr 08, 2006 6:35 am     Reply with quote

Hi Simon,

You're right again, The change you sugested works beautifully, and now the PIC transmits the data as I want. Thanks Very Happy

I've recently been programming a PC interface to CAN networks, automotive components, and have never heard of a remote frame, at least not on a CAN network.

Using the correct timing information (i.e. taking into account the val-1) I've managed to get the PIC sending messages at 500kbps, which is the rate the rest of the network will be running. So making good progress...

Still no joy on the recieve CAN message, is there something similar that I'm missing for the RX? Sad

My compiler is version 3.180, I've just purchased the latest compiler, and it should arrive very soon.

At the moment the only messages on the CAN BUS are ones manually sent by pressing buttons on my PC side software, so I don't think the BUS is overloaded yet!

I will move on to using faster crystals and interupts, but I'm trying to get the basics working and increase my understanding before moving on. I don't think there should be any issue with either. Providing I understand how to set the bit timings I should be able to use any crystal. And I've previously writen buffered/interupt driven RS232 communications, so fingers crossed the CAN interupts will not baffle me.

Thanks again

Scott
sjbaxter



Joined: 26 Jan 2006
Posts: 141
Location: Cheshire, UK

View user's profile Send private message Visit poster's website

PostPosted: Sat Apr 08, 2006 11:38 am     Reply with quote

Scott,

Good to see that your making progress.

As for remote frames, they are not used very often (if at all from my experience). Have a read of the CAN 2.0B spec (just do a search on google ... its a free download from Bosch).

I have built a commercial CAN to USB interface and a faster clock, filtering and interrupts will be a must for monitoring a CAN network. You might find RS232 a bit restrictive due to low bandwidth, but its a good starting point.

As for CAN RX, I'm not sure why that isn't working !! You may want to try putting the CAN module in loopback mode. Its easier to test TX/RX code when you know the hardware is out of the loop.

To do this put a :

Code:
can_set_mode(CAN_OP_LOOPBACK);


after can_init and before the while(1) loop. In this mode any message you send will be received by the PIC without ever leaving the PIC. It's another useful builtin CAN debug tool.
_________________
Regards,
Simon.
ferrumvir



Joined: 01 Feb 2006
Posts: 64
Location: England

View user's profile Send private message Visit poster's website

PostPosted: Sat Apr 08, 2006 12:44 pm     Reply with quote

Hi Simon,

I've tried the loopback mode but this does not appear to function any differently! I'm begining to feel rather stupid... Confused

In the LOOPBACK mode the TX messages are output on RS232, but no RX messages are recieved.

I've added a few extra diagnostics too the program.

To see if I'm getting any kbhits.

Code:

      if ( can_kbhit() )   //if data is waiting in buffer...
      {
// ADDITIONAL
         printf(".");
// END ADDITIONAL
         if(can_getd(rx_id, &in_data[0], rx_len, rxstat)) { //...then get data from buffer


To see if I'm getting any interupts

Code:

// ADDITIONAL
#INT_CANRX0
void can_rx0(void)
{
  printf("0");
}
#INT_CANRX1
void can_rx1(void)
{
  printf("1");
}
// END ADDITIONAL

void main() {


and

Code:

   enable_interrupts(INT_TIMER2);   //enable timer2 interrupt
// ADDITIONAL
   enable_interrupts(INT_CANRX0);   //enable CANRX0 interrupt
   enable_interrupts(INT_CANRX1);   //enable CANRX1 interrupt
// END ADDITIONAL
   enable_interrupts(GLOBAL);       //enable all interrupts (else timer2 wont happen)


I've also turned on the CAN_DO_DEBUG (the internal software debug messages)

Code:

#define CAN_DO_DEBUG TRUE   


The TX messages are reported on the RS232 (twice now, once in the main routine and once from the DEBUG diagnostics)

However, none of the RX messages (from anywhere) are being sent.

Interestingly the CANTX continues past the first three messages. Previously when the CANBUS was erroring the 3 TX buffers would fill and no further messages would be reported as being sent. So it appears that the messages are being taken off the TX buffers but are not filling the CANRX buffers in a manner that the can-18xxx8.h and can-18xxx8.c understand.

The only thing I can think of is that the above to files are not compatible with the PIC18F258 or that I'm filtering out messages somehow?

I've now just added the TX interupts and they (only TX0 is ever used) are executed just fine.

I'll see if I can check what the masks and filters are actually set to... The code would indicate zeros, therefore accepting everything... but you never know!

Cheers Scott
ferrumvir



Joined: 01 Feb 2006
Posts: 64
Location: England

View user's profile Send private message Visit poster's website

PostPosted: Sat Apr 08, 2006 1:00 pm     Reply with quote

Checked the masks and filters,

Code:

   can_init();
   can_set_mode(CAN_OP_LOOPBACK);

// ADDITIONAL
   maskfilter = can_get_id(RX0MASK, 1);  //get mask 0
   printf("RX0MASK = %4X\r\n",maskfilter);
   maskfilter = can_get_id(RX0FILTER0, 1);  //get filter 0 of mask 0
   printf("RX0FILTER0 = %4X\r\n",maskfilter);
   maskfilter = can_get_id(RX0FILTER1, 1);  //get filter 1 of mask 0
   printf("RX0FILTER1 = %4X\r\n",maskfilter);
   maskfilter = can_get_id(RX1MASK, 1);  //get mask 1
   printf("RX1MASK = %4X\r\n",maskfilter);
   maskfilter = can_get_id(RX1FILTER2, 1);  //get filter 0 of mask 1
   printf("RX1FILTER2 = %4X\r\n",maskfilter);
   maskfilter = can_get_id(RX1FILTER3, 1);  //get filter 1 of mask 1
   printf("RX1FILTER3 = %4X\r\n",maskfilter);
   maskfilter = can_get_id(RX1FILTER4, 1);  //get filter 2 of mask 1
   printf("RX1FILTER4 = %4X\r\n",maskfilter);
   maskfilter = can_get_id(RX1FILTER5, 1);  //get filter 3 of mask 1
   printf("RX1FILTER5 = %4X\r\n",maskfilter);
// END ADDITIONAL



which produces the following on RS232, which I have to say is expected...
Code:

RX0MASK = 0000
RX0FILTER0 = 0000
RX0FILTER1 = 0000
RX1MASK = 0000
RX1FILTER2 = 0000
RX1FILTER3 = 0000
RX1FILTER4 = 0000
RX1FILTER5 = 0000


Exclamation Question

So I'm still losing the incoming messages somewhere?

Cheers Scott
sjbaxter



Joined: 26 Jan 2006
Posts: 141
Location: Cheshire, UK

View user's profile Send private message Visit poster's website

PostPosted: Sun Apr 09, 2006 3:25 am     Reply with quote

Scott,

can-18xxx8 is fine with the 18F258. By default, in the can-18xxx8.h, is setup to use extended id's for TX and the filters are setup for extended id's.
Code:
#IFNDEF CAN_USE_EXTENDED_ID
  #define CAN_USE_EXTENDED_ID         TRUE
#ENDIF

you don't define this as FALSE in your code, so extended are assumed.

In can_init, by default, both rx filters are setup for use with extended id's

In your code, for the tx message, you set ext=0; (so you are using standard id's).

So, either change...

Code:
ext=1;

or add...
Code:
#define CAN_USE_EXTENDED_ID FALSE

and in your application, change the can_init (or create your own) to accept either type of id...

Code:
void can_init_ex(void)
{
    // this is basically the can_init() function with
    // one receiver set to standard IDs
    // and the other set to filter on Extended IDs

    // Set receive filters and masks
    can_set_mode(CAN_OP_CONFIG);

    RXB0CON          = 0;
    RXB0CON.rxm      = 0x00;
    RXB0CON.rxb0dben = 1;
    RXB1CON          = RXB0CON;
    CIOCON.endrhi    = 1;
    CIOCON.cancap    = 0;

    // Standard IDs
    can_set_id(RX0MASK,    CAN_MASK_ACCEPT_ALL, 0);
    can_set_id(RX0FILTER0, 0,                   0);
    can_set_id(RX0FILTER1, 0,                   0);

    // Extended IDs
    can_set_id(RX1MASK,    CAN_MASK_ACCEPT_ALL, 1);
    can_set_id(RX1FILTER2, 0,                   1);
    can_set_id(RX1FILTER3, 0,                   1);
    can_set_id(RX1FILTER4, 0,                   1);
    can_set_id(RX1FILTER5, 0,                   1);

    set_tris_b((*0xF93 & 0xFB ) | 0x08);   //b3 is out, b2 is in

    can_set_mode(CAN_OP_NORMAL);
}


NOTE : If the tx buffers empty, then this is another good sign that at least one node on the bus has acknowleged the message. So it confirms to me that, if you are in loopback mode, the message has been received by the hardware but has been rejected by the filters.
_________________
Regards,
Simon.
ferrumvir



Joined: 01 Feb 2006
Posts: 64
Location: England

View user's profile Send private message Visit poster's website

PostPosted: Sun Apr 09, 2006 10:30 am     Reply with quote

Hi Simon,

Thanks for sticking with this,

You mention the CAN_USE_EXTENDED_ID, now I probably should have explained my code a little better.

Code:

#define CAN_USE_EXTENDED_ID         FALSE
#define CAN_USE_RX_DOUBLE_BUFFER    FALSE       //if buffer 0 overflows, do NOT use buffer 1 to put buffer 0 data
#define CAN_ENABLE_DRIVE_HIGH       1
#define CAN_ENABLE_CAN_CAPTURE      0

// USED TO CHECK VERSION CORRECTLY PROGRAMMED ON PIC
#define MY_VERSION 24

// TRIED TRUE TRUE 0 0 - FAILED (DEFAULT)
// TRIED TRUE TRUE 1 0 - FAILED
// TRIED FALSE TRUE 0 0 - FAILED
// TRIED FALSE TRUE 1 0 - FAILED
// TRIED TRUE FALSE 0 0 - FAILED
// TRIED TRUE FALSE 1 0 - FAILED
// TRIED FALSE FALSE 0 0 - FAILED
// TRIED FALSE FALSE 1 0 - FAILED


These TRIED comments are different setups that I've used in the previous definitions, so numbers 3,4,7,8 are all with the standard IDs. Effectively I've done a binary search to find if a different set up actually works, all have performed the same, which surprised me a little. My CAN network will only be using standard IDs but I've tried the extended IDs just to check that was not the problem, and they perfomed no differently.

I'd assumed that because the can-18xxx8 did not give an external option to change the mask/filter standard/extended that it did not matter. From what you say that is not the case.

I'll make the modifications you sugest to the can_init() routine and give it a try.

Thanks also for your hints and tips on the RS232 being too slow and USB being the best option for PC interface. I'm using KVasers for the PC interface, and see no reason to (other than cost) to re-invent the wheel. The system we are developing is controlled by and MPC555 with 2 CAN channels, effectively 1 WAN-CAN to control the system and the other LAN-CAN for the system to control it's periferals. The devices I'm working on are all periferal devices sitting on the LAN-CAN BUS, one will be a 6x thermistor sensor (6xADC), another 4x PWM output, a RTC, some NV memory. Some of these will be on the same PIC, but others depending on the physical location of what they are controlling/measuring will be separate.

Thanks for the help, I'm off to test...

Scott
ferrumvir



Joined: 01 Feb 2006
Posts: 64
Location: England

View user's profile Send private message Visit poster's website

PostPosted: Sun Apr 09, 2006 12:16 pm     Reply with quote

Very Happy

Thanks Simon,

The whole kit and caboodle is now functioning. I can't thank you enough without buying you a pint! Shocked or three...

For those of you who don't want to trawl through all the help Simon has given me, I'll reitterate here the three mistakes/misconceptions I was making, while trying to use the example code EX_CAN.C

Firstly: My bit timing was incorrect The segments sizes are effectively all minus 1 (or zero=one), the following code sets up the segment synch=1, prop=1, phase1=5 and phase2=3, total number of segments = 10. Embarassed This was my mistake for not reading the data sheet properly.

Code:

 #define CAN_BRG_SYNCH_JUMP_WIDTH   0             //synchronized jump width (def: 1 x Tq)
 #define CAN_BRG_PROPAGATION_TIME   0             //propagation time select (def: 3 x Tq)
 #define CAN_BRG_PHASE_SEGMENT_1    4             //phase segment 1 (def: 6 x Tq)
 #define CAN_BRG_PHASE_SEGMENT_2    2             //phase segment 2 time select (def: 6 x Tq)


Secondly, I could only transmiting zeros. The variable "tx_rtr", when set to one, requests a remote frame and does not send the data in "out_data", or rather the 6th argument of can_putd should be zero to actually send data. Embarassed The example code EX_CAN.C does actually have a comment a couple of lines above where it sets this variable, saying just that!

Thirdly, I was unable to recieve messages. This was caused by the masks and filters being set up for extended IDs, this required a modification to can_init. The last argument in the can_set_id(mask/filter, xxx, EX) should be zero for the filter to accept standard IDs. Exclamation This, I think, is an oversite by CCS in the example. This oversite makes it really tough to get the example working if your CAN BUS is using standard IDs.

Thanks again for all the help Simon, got there in the end. I dread to think how long it would have taken me to figure all this out myself.

Cheers Scott
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group