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 on 18F4680 [Solved]
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
Fredrik



Joined: 18 Apr 2006
Posts: 8

View user's profile Send private message

CAN on 18F4680 [Solved]
PostPosted: Tue Apr 18, 2006 6:46 am     Reply with quote

Without any luck I am trying to get the CAN-bus up and running on a 18F4680. At this point I think I've tried everything...

I am using the example file EX_CAN.C with some minor modifications (I am using a 10Mhz crystal instead of a 20Mhz) interfacing the bus through a MCP2551 tranceiver.

The problem is that when I measure the activity on the CANTX pin, it remains constantly high. Calling the function can_putd the data gets loaded into the buffers and the Transmit Request Status bit is set. However since no data is ever sent this bit never clears and the buffer remains occupied. Any ideas on what to do?

I have also tried to configure the operation mode into Loopback mode in the same matter as newguy did Here but without any luck. Any tries to change operation mode once a mode previously mode been set causes no effect, the mode never changes.

Help would be greatly appreciated, right now I am going slightly mad.

// Fredrik


Last edited by Fredrik on Thu Apr 20, 2006 8:34 am; edited 1 time in total
newguy



Joined: 24 Jun 2004
Posts: 1907

View user's profile Send private message

PostPosted: Tue Apr 18, 2006 10:07 am     Reply with quote

I wish I could be of more help. The code in the post of mine you mentioned is pretty much the same code I'm using now in a product I'm developing. And I'm using a pair of 18F4680's. No issues with them at all. All I had to do was change my header file to include the 18F4680.h, and it worked right away.

How did you calculate the bit timing parameters?
Fredrik



Joined: 18 Apr 2006
Posts: 8

View user's profile Send private message

PostPosted: Tue Apr 18, 2006 12:17 pm     Reply with quote

I have scaled the timing parameters from the ones given in EX_CAN.C (for the 20Mhz crystal) to make them approx. equal:

-----------------------------------
TQ = 2x(BRP+1)/Fosc. BRP = 1, Fosc = 10M gives TQ = 0.4us
(EX_CAN: BRP = 4, Fosc = 20 gives TQ = 0.5us)

Sync segment = 1xTQ gives 0.4us
(EX_CAN: 1xTQ gives 0.5us)

Propagation Segment = 3xTQ gives 1.2us
(EX_CAN: 3xTQ gives 1.5us)

Phase sync 1 = 8xTQ gives 3.2us
(EX_CAN: 6xTQ gives 3.0us)

Phase sync 2 = 8xTQ gives 3.2us
(EX_CAN: 6xTQ gives 3.0us)

Nominal bit time = 0.4 + 1.2 + 3.2 + 3.2 = 8us (= 125kbit/s)
(EX_CAN: 0.5 + 1.5 + 3.0 + 3.0 = 8us)
-----------------------------------

I've done that because I'm not quite sure on how important the different factors are. Now the main problem is that i can't read out any data at all from CANTX pin.

The chip also refuses to change the operation mode once it has been set after the first init. from config. mode (The chip starts in config. mode, and when a mode is set, the chip don't ever go back to config. mode even if I request it).

If you don't mind I would like to have a look at your source, so i can verify that it is not there the problem lies. Or perhaps you could test mine?

Is there by the way an easy way to fake an ideal bus connected to CANTX/CANRX, so that any possible hardware error can be ignored at this time? Of course the bus wont work if there is no answer, but at least so I can se any data coming out of CANTX.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Apr 18, 2006 12:47 pm     Reply with quote

Quote:
I have scaled the timing parameters from the ones given in EX_CAN.C
See this thread for CAN bit timing info:
http://www.ccsinfo.com/forum/viewtopic.php?t=22138&start=7
Fredrik



Joined: 18 Apr 2006
Posts: 8

View user's profile Send private message

PostPosted: Wed Apr 19, 2006 12:29 am     Reply with quote

Thanks for the link PCM Programmer, that made me understand the bit timing better. Unfortunatley this was not the problem, even thoug it made me change the values a bit.

I will insert one of the many codes I have tried. Maybe someone can figure out the error(s):

Code:
#include <18F4680.h>
#fuses HS,NOPROTECT,NOLVP,NOWDT
#use delay(clock=10000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#define DEBUG
#define WAIT

#byte CANCON     = 0xF6F
#byte CANSTAT    = 0xF6E
#byte ECANCON    = 0xF77
#byte COMSTAT   = 0xF74

#byte TXERRCNT   = 0xF76

#byte BRGCON1    = 0xF70
#byte BRGCON2    = 0xF71
#byte BRGCON3    = 0xF72

#byte CIOCON    = 0xF73

#byte TXB0CON    = 0xF40
#byte TXB1CON    = 0xF30
#byte TXB2CON    = 0xF20

#byte TXB0SIDH   = 0xF41
#byte TXB0SIDL   = 0xF42
#byte TXB0EIDH   = 0xF43
#byte TXB0EIDL    = 0xF44

#byte TXB0DLC   = 0xF45

#byte TXB0D0      = 0xF46
#byte TXB0D1      = 0xF47
#byte TXB0D2      = 0xF48
#byte TXB0D3      = 0xF49
#byte TXB0D4      = 0xF4A
#byte TXB0D5      = 0xF4B
#byte TXB0D6      = 0xF4C
#byte TXB0D7      = 0xF4D

void can_init(void);
int1 can_t0_putd(void);

void main() {
   
   int i;
   
      can_init();

      printf("Running...\r\n");
   
      while(TRUE)
      {   

       //every second, send new data if transmit buffer is empty
      delay_ms(1000);
        i = can_t0_putd(); //put data to transmit buffer 0
       
      if (i == TRUE) { //success, a transmit buffer was open
            printf("SUCCESS, Buffer 0 loaded\r\n");
      }
        else { //fail, transmit buffer was occupied
            printf("FAIL, Buffer 0 occupied\r\n");
        }


#ifdef WAIT
      printf("Waiting for message to get transmitted...\r\n");
      while(bit_test(TXB0CON,3) == 1);
#endif

#ifdef DEBUG
      if(bit_test(COMSTAT,5))
         printf("Error: TX_OFF\r\n");
      if(bit_test(COMSTAT,4))
         printf("Error: TX_PASS\r\n");   
      if(bit_test(COMSTAT,2))
         printf("Error: TX_WARN\r\n");

      if(TXERRCNT > 0)
         printf("TXERRCNT: %X",TXERRCNT);
#endif
     }
}

void can_init(void)
{

#ifdef DEBUG
   printf("Can Init\r\n");
#endif

   // Request Configuration mode
   CANCON = 0x80;            
      while( (CANSTAT & 0x80) != 0x80 );   // Wait for Configuration mode

/*  Removing this comment causes the chip to "hang"

   CANCON = CANCON & 0x1F;   // Clear previous mode
   while( (CANSTAT & 0xE0) != 0x00 );   // Wait for Normal mode

   CANCON = 0x80;            
      while( (CANSTAT & 0x80) != 0x80 );   // Wait for Configuration mode !!** HANGS HERE **!!

*/

   // Set baudrate, 125 kbit/s
   BRGCON1 = 0x04;   // Sync Jmp: 1xTQ, Prescaler: TQ = (2x(4+1))/Fosc (1.0us)
   BRGCON2 = 0x98; // Freely prog, One sample, Phase_1 = 4xTQ, Propagation time = 1xTQ
   BRGCON3 = 0x01; // Disable wake-up, line filter not used, Phase_2 = 2xTQ

   // Set I/O
   CIOCON = 0x00;    // CANTX = tristate, Disable CAN capture
   set_tris_b((*0xF93 & 0xFB ) | 0x08);   //b3 is out, b2 is in

   // Set mode
   ECANCON = 0x30;   // CANTX will drive VDD when recessive, Enable CAN capture

   // Request Normal mode
   CANCON = CANCON & 0x1F;   // Clear previous mode
   while( (CANSTAT & 0xE0) != 0x00 );   // Wait for Normal mode
}

int1 can_t0_putd(void)
{
   if((TXB0CON & 0x08) != 0)   // Message pending, abort
      return ( FALSE );

   // Set ID
   TXB0SIDH = 0x02;
   TXB0SIDL = 0x04;
   TXB0EIDH = 0x00;
   TXB0EIDL = 0x00;

   // Set Length
   TXB0DLC = 8;

   // Set RTR
   TXB0DLC = TXB0DLC & 0xBF; // Don't set RTR

   // Set priority
   TXB0CON = TXB0CON | 0x03;   // Highest priority

   // Set Data
   TXB0D0 = 0x00;
   TXB0D1 = 0x01;
   TXB0D2 = 0x02;
   TXB0D3 = 0x03;
   TXB0D4 = 0x04;
   TXB0D5 = 0x05;
   TXB0D6 = 0x06;
   TXB0D7 = 0x07;

   TXB0CON = TXB0CON | 0x08;   // Request transmission

   return ( TRUE );
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Apr 19, 2006 1:11 am     Reply with quote

Unfortunately, you're writing your own low-level driver and that's
undoubtedly the problem. You should use the CCS drivers supplied
with the compiler. Read the posts in the forum archives that tell
how to use loopback mode.
http://www.ccsinfo.com/forum/viewtopic.php?t=23825
Fredrik



Joined: 18 Apr 2006
Posts: 8

View user's profile Send private message

PostPosted: Wed Apr 19, 2006 1:51 am     Reply with quote

Actually I started out with the CCS drivers supplied with the compiler. But since that did not work I narrowed it down to have a better view on the functions. My low-level driver does basicaly the same thing as the CCS drivers. It is just smaller so it would be easier to search for the error.

As I mentioned in my first post I began using the CCS drivers in the exact same way as newguy did in the link that you just sent. I start with EX_CAN.C and then change #include to 18f4680.h. Change the #use delay. Alter the bit timing values according to earlier posts. Changes the setup_timer_2 to work propely with a 10Mhz osc. And adding can_set_mode(CAN_OP_LOOPBACK); right after can_init(); The last function causes the chip to hang (apparently because the operation mode never changes). So testing loopback mode with the CCS drivers unchanged does not work for me (I did not work for Sholto either).

Any further suggestions would be greatly appreciated.
sjbaxter



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

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

PostPosted: Wed Apr 19, 2006 4:30 am     Reply with quote

Fredrik,

First, I suggest you reduce the unknowns by using the ccs driver. It works, so that narrows your problem down to either timing or a compiler bug (you don't state your compiler version, but 3.237 onwards has problems with allocating structures which are used in the CAN driver). Try 3.236.

Second, when you tried to use EX_CAN.C, did you change the include from

Code:
#include <can-18xxx8.c>


to

Code:
#include <can-18F4580.c>


as this is the driver for ALL PICs with the ECAN module not the basic CAN module.

Third, If you use lookback mode, this will rule out any problems with the external hardware (i.e CAN transceiver and other node on the bus).

also have a look at ...

CAN you help (pun intended!)

this thread covers some of the most basic errors and pitfalls when trying to implement CAN.
_________________
Regards,
Simon.
Fredrik



Joined: 18 Apr 2006
Posts: 8

View user's profile Send private message

PostPosted: Wed Apr 19, 2006 9:05 am     Reply with quote

Okay this is getting really annoying. I still can’t get any output from the CANTX pin. Everyone keeps telling me to use the CCS driver supplied. I’ve explained several times that I have tried this approach, but no one seems to believe me. It does not work!

I use version 3.245 of the compiler. I wish I had an older version to test with, but I don't. I only have this version and a really old one not supporting 18f4680. I am starting to beleive that this compiler doesn't support the CAN on 18F4680. Or the CAN on the pic doesn't work?!?

Okay so you still don’t believe me? Here are the changes that I have made to the files EX_CAN.C and can-18F4580.h (yes, it's from the supplied CCS driver).

EX_CAN.C:
Code:

//#include <18F248.h>  // default
#include <18F4680.h>
...
//#use delay(clock=20000000) // default
#use delay(clock=10000000)
...
//#include <can-18xxx8.c> // default
#include <can-18F4580.c>
...
//setup_timer_2(T2_DIV_BY_4,79,16);   //setup up timer2 to interrupt every 1ms if using 20Mhz clock // default
setup_timer_2(T2_DIV_BY_4,79,8);   //setup up timer2 to interrupt every 1ms if using 10Mhz clock
...
can_init();
can_set_mode(CAN_OP_LOOPBACK); // This line is added
...


can-18F4580.h:
Code:

...
// #define CAN_BRG_PHASE_SEGMENT_1  5 //phase segment 1 (def: 6 x Tq) // default
 #define CAN_BRG_PHASE_SEGMENT_1  3 //phase segment 1 4 x Tq)
...
// #define CAN_BRG_PROPAGATION_TIME 2 //propagation time select (def: 3 x Tq) // default
 #define CAN_BRG_PROPAGATION_TIME 0 //propagation time select 1 x Tq)
...
// #define CAN_BRG_PHASE_SEGMENT_2 5 //phase segment 2 time select (def: 6 x Tq) // default
 #define CAN_BRG_PHASE_SEGMENT_2 1 //phase segment 2 time select 2 x Tq)
...
// #define CAN_ENABLE_DRIVE_HIGH 0   // default
 #define CAN_ENABLE_DRIVE_HIGH 1 // drive to Vdd
...


The chip "hangs" when it reaches the function can_set_mode(CAN_OP_LOOPBACK); (as I have mentioned several times before). If i remove that line the chip runs the main loop, but nothing is put out on CANTX pin.

This is not a lot of changes, but it also gives no result. If you still think that i am doing something wrong, or have any idea, please tell me so that i can fix it.
sjbaxter



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

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

PostPosted: Wed Apr 19, 2006 9:54 am     Reply with quote

Fredrik,

If 'everyone' is telling you to use the ccs drivers, thats because we have all been in the same position as you and have learnt how not to do it !! and what you do need to do in order to make it work. Don't introduce more unknowns into an already troubled situation, it just makes the task harder to solve not easier.

You should be able to download 3.236 as is the 'stable' base release for the compiler you currently have. It does support this 18F4680. If you can't get acces to it, mail CCS and they will give you access to the download (as your 3.245 license will be valid for this release).

Have a look at the SYM file and see if any global structs or non-scratch variables are 'overlapping' each other. If they are then this is a 'known' compiler bug introduced around 3.242.

You say that the micro 'hangs'. Put in some breakpoints and step through the program and watch the CAN configuration registers. Step into the can_set_mode and check that the registers are still setup the way can_init has set them (i.e. that they haven't been corrupted). At what point does it hang ? Does it jump into can_set_mode or crash before ?

The reason I suggest you try an earlier version is that I was using 3.242 and everything appeared fine until my call to can_putd, at which point the registers changed as the compiler used a variable scratch location that was one of the global variables used to setup the can (hence the corruption). The earlier version of compiler worked without problems.

You may already know, but in loopback mode you won't see anything on CANTX as the loopback disconnects the output and does the lookback internal to the PIC.

If the example doesn't work ... its one of two things (the compiler or the PIC is no good !!!).
_________________
Regards,
Simon.
Fredrik



Joined: 18 Apr 2006
Posts: 8

View user's profile Send private message

PostPosted: Wed Apr 19, 2006 12:21 pm     Reply with quote

sjbaxter wrote:

If 'everyone' is telling you to use the ccs drivers, thats because we have all been in the same position as you and have learnt how not to do it !! and what you do need to do in order to make it work. Don't introduce more unknowns into an already troubled situation, it just makes the task harder to solve not easier.


That was the reason why I decided to write my own driver when the ccs supplied driver did not work. I wanted to minimize data structures, variables etc. to get a straight forward code to overcome any possible compiler bugs. I thougt that CCS driver introduced more unknowns.

Quote:

You should be able to download 3.236 as is the 'stable' base release for the compiler you currently have. It does support this 18F4680. If you can't get acces to it, mail CCS and they will give you access to the download (as your 3.245 license will be valid for this release).


I will try that, thanks for the tip. But I don't really think that the compiler is the issue.

Quote:

Have a look at the SYM file and see if any global structs or non-scratch variables are 'overlapping' each other. If they are then this is a 'known' compiler bug introduced around 3.242.


This is something I know very little about. I dont understand what the @scratch means. For instance, what does can_set_mode.@SCRATCH stand for? Many of the @scratch variables appear on different locations. I don't see any overlapping non-scratch variables or global structs.

Quote:

You say that the micro 'hangs'. Put in some breakpoints and step through the program and watch the CAN configuration registers. Step into the can_set_mode and check that the registers are still setup the way can_init has set them (i.e. that they haven't been corrupted). At what point does it hang ? Does it jump into can_set_mode or crash before ?


All registers are still setup according to can_init(); settings when stepping into the can_se_mode() function:
Code:
void can_set_mode(CAN_OP_MODE mode) {
   CANCON.reqop=mode;
   while( (CANSTAT.opmode) != mode );
}

CANCON register alters to 0x40 as it should requesting to change mode from Normal to Loopback. This request is not met. CANSTAT is never changed to loopback mode causing while( (CANSTAT.opmode) != mode ); to loop forever.

Quote:

The reason I suggest you try an earlier version is that I was using 3.242 and everything appeared fine until my call to can_putd, at which point the registers changed as the compiler used a variable scratch location that was one of the global variables used to setup the can (hence the corruption). The earlier version of compiler worked without problems.


Good to know that this problem can occur. However I don't believe that this is the case for me. The global (and main) variables and structures used are:
Code:

018     curmode
019     curfunmode
01A-01B ms
01C-01F main.rxstat
020-023 main.rx_id
024-02B main.in_data
02C     main.rx_len
02D-034 main.out_data
035-038 main.tx_id
039.0   main.tx_rtr
039.1   main.tx_ext
03A     main.tx_len
03B     main.tx_pri
03C     main.i

And no other variable uses the same location.

Quote:

You may already know, but in loopback mode you won't see anything on CANTX as the loopback disconnects the output and does the lookback internal to the PIC.

Since I got nothing at all out of the CANTX pin, I wanted to use loopback to se if there were something wrong with the bus. The problem is obviously earlier than that.

Quote:

If the example doesn't work ... its one of two things (the compiler or the PIC is no good !!!).

I quess, but I'm not able to narrow down the specific error. My fault, CCS fault or Microchip fault.

Pardon me for my bad manners, and I don't intend to be disrespectful. It is just very frustrating needing to spend so much time with something that should be fairly easy.
Thank you sjbaxter for your suggestions!

Any other ideas?
amcfall



Joined: 20 Oct 2005
Posts: 44

View user's profile Send private message

PostPosted: Wed Apr 19, 2006 12:25 pm     Reply with quote

Why don't you think the compiler is the problem? Several people have said thhis works with 3.236, but not with the version you have. This is the reason I am still using 3.236 even though I have newer versions.

Do what sjbaxter suggested. If it work with the CCS driver and 3.236 then you have a good startiong point. The only change ONE thing at a timer, such as driver or compiler version.

Avery
sjbaxter



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

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

PostPosted: Wed Apr 19, 2006 2:01 pm     Reply with quote

The datasheet states that a mode request will not be actioned until all pending transmissions are complete (Ref 23.3 of the datasheet). So, you need to pause when the app reaches this point and do some watching of the status registers to see if the TXREQ for each of the transmit buffers is set.

If it is, the next problem is why !!

You could try changing the can_set_mode at the bottom of can_init to default to LOOPBACK instead of NORMAL to see if that has any effect. If you are not connected to a live bus and you go into NORMAL mode and for some reason the PIC thinks there are pending TXs, you can't change the operating mode. You could try a can_abort before the set to LOOPBACK call.

Still doesn't explain why you should have messages in the TX buffers, but it gives you something else to work on.

Could be a bad PIC, not resetting properly.
_________________
Regards,
Simon.
Fredrik



Joined: 18 Apr 2006
Posts: 8

View user's profile Send private message

PostPosted: Thu Apr 20, 2006 12:37 am     Reply with quote

amcfall wrote:
Why don't you think the compiler is the problem? Several people have said thhis works with 3.236, but not with the version you have. This is the reason I am still using 3.236 even though I have newer versions.

I don't think it is the compiler because when I debug the source and look at the registers, the request bits for operation mode change in CANCON are set. But the request is never met and changed into CANSTAT. I don't see this as a compiler issue. But what do I know. So I will try to get an older version and test.

sjbaxter wrote:
The datasheet states that a mode request will not be actioned until all pending transmissions are complete (Ref 23.3 of the datasheet). So, you need to pause when the app reaches this point and do some watching of the status registers to see if the TXREQ for each of the transmit buffers is set.

If it is, the next problem is why !!

Not any of the TXREQ in any transmit buffer is set (all tx buffers are 0x00).

Quote:

You could try changing the can_set_mode at the bottom of can_init to default to LOOPBACK instead of NORMAL to see if that has any effect. If you are not connected to a live bus and you go into NORMAL mode and for some reason the PIC thinks there are pending TXs, you can't change the operating mode. You could try a can_abort before the set to LOOPBACK call.

I have tried to go to any other mode than normal in the can_init() function replacing the last can_set_mode(CAN_OP_NORMAL); to the different modes LISTEN, LOOPBACK and DISABLE. Non of the operating mode change requests are met. The only mode I can switch to is normal. And that doesn't work for me either.
Quote:
Could be a bad PIC, not resetting properly.

Yes it could be, but then I got three of them.
Maybe it is time to buy and try another PIC...
sjbaxter



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

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

PostPosted: Thu Apr 20, 2006 3:52 am     Reply with quote

Fredrik,

have a look at this thread on the Microchip CAN forum :

Difficulty entering configuration mode

it is similar to your problem and has a few other pointers that may help.
_________________
Regards,
Simon.
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