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

ECAN works fine in LEGACY_MODE, but not in ENHANCED_MODE?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Dirk
Guest







ECAN works fine in LEGACY_MODE, but not in ENHANCED_MODE?
PostPosted: Mon Sep 14, 2009 10:53 am     Reply with quote

Hello,
I am trying to start with CAN communication with a PIC18F2685. After solving first problems by reading older posts about CAN in this Forum now I have big trouble with ENHANCED Mode.
Everything is working fine if I use LEGACY Mode, but changing the Mode to ENHANCED (no FIFO), switching off all filters and program Buffers B0 to B5 as TX, I do a double receive every time a CAN-Message is sent to on the bus. First I receive on Buffer 0 with filter 0, but data is wrong. The second kbhit is on correct buffer with correct Data. And: I receive my own TX, but with wrong data and wrong ID.
It seems to me as the kbhit comes, but no data was received. What am I missing?
Here is the interesting part of the code (tested):
Code:

void can_init(void){
   byte mode;
   can_set_mode(CAN_OP_CONFIG);                                                   //must be in config mode before params can be set
   mode = CAN_FUN_OP_ENHANCED;                                                   // choose functional mode CAN_FUN_ENHANCED
   //mode = CAN_FUN_OP_LEGACY;
   ECANCON.mdsel= mode;                                                           // CAN_FUN_ENHANCED       
   curfunmode=mode;                                                              // CAN_FUN_ENHANCED_FIFO                                                                                             
   
   can_set_baud();
   RXB0CON=0;
   RXB0CON.rxm=CAN_RX_VALID;                                                      // RX-Mode: Valid = STD and extended IDs, STD = only STD IDs, EXT = only extended IDs
   RXB0CON.rxb0dben= CAN_USE_RX_DOUBLE_BUFFER;                                    // Receive Buffer 0 overflow will write to Receive Buffer 1
   RXB1CON=RXB0CON;

   CIOCON.endrhi=CAN_ENABLE_DRIVE_HIGH;                                          // CANTX pin will drive VDD when recessive
   CIOCON.cancap=CAN_ENABLE_CAN_CAPTURE;                                          // Enable CAN capture, CAN message receive signal replaces input on RC2/CCP1
                                                                                 // used to generate a time-stamp within Timer1 or Timer3
   can_set_id(RX0MASK, CAN_MASK_ACCEPT_ALL, CAN_USE_EXTENDED_ID);  //set mask 0
   can_set_id(RXFILTER0, 0, CAN_USE_EXTENDED_ID);  //set filter 0 of mask 0
   can_set_id(RXFILTER1, 0, CAN_USE_EXTENDED_ID);  //set filter 1 of mask 0

   can_set_id(RX1MASK, CAN_MASK_ACCEPT_ALL, CAN_USE_EXTENDED_ID);  //set mask 1
   can_set_id(RXFILTER2, 0, CAN_USE_EXTENDED_ID);  //set filter 0 of mask 1
   can_set_id(RXFILTER3, 0, CAN_USE_EXTENDED_ID);  //set filter 1 of mask 1
   can_set_id(RXFILTER4, 0, CAN_USE_EXTENDED_ID);  //set filter 2 of mask 1
   can_set_id(RXFILTER5, 0, CAN_USE_EXTENDED_ID);  //set filter 3 of mask 1

   // set dynamic filters
   can_set_id(RXFILTER6, 0, CAN_USE_EXTENDED_ID);                                // set IDs for all RX-filters                                               
   can_set_id(RXFILTER7, 0, CAN_USE_EXTENDED_ID);
   can_set_id(RXFILTER8, 0, CAN_USE_EXTENDED_ID);
   can_set_id(RXFILTER9, 0, CAN_USE_EXTENDED_ID);
   can_set_id(RXFILTER10, 0, CAN_USE_EXTENDED_ID);
   can_set_id(RXFILTER11, 0, CAN_USE_EXTENDED_ID);
   can_set_id(RXFILTER12, 0, CAN_USE_EXTENDED_ID);
   can_set_id(RXFILTER13, 0, CAN_USE_EXTENDED_ID);
   can_set_id(RXFILTER14, 0, CAN_USE_EXTENDED_ID);
   can_set_id(RXFILTER15, 0, CAN_USE_EXTENDED_ID);

   can_disable_filter(RXF6EN);
   can_disable_filter(RXF7EN);
   can_disable_filter(RXF8EN);
   can_disable_filter(RXF9EN);
   can_disable_filter(RXF10EN);           
   can_disable_filter(RXF11EN);                               
   can_disable_filter(RXF12EN);
   can_disable_filter(RXF13EN);
   can_disable_filter(RXF14EN);
   can_disable_filter(RXF15EN);

   can_enable_b_transfer(0xFC);

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

   can_set_mode(CAN_OP_NORMAL);
}



And here is my main program:

Code:


#opt 0
#if defined(__PCH__)
#include <18F2685.h>
#DEVICE  ADC=10, HIGH_INTS = TRUE
#fuses NOPBADEN,BBSIZ1K,NOIESO,STVREN,NOWRT,NOWRTD,NOFCMEN,NOWRTC,NOWRTB,NOCPB,NOLPT1OSC,MCLR,NOXINST,PUT,BROWNOUT,BORV45,HS,WDT,NOPROTECT,NOLVP
#use delay(clock = 40M, oscillator = 10M, restart_wdt) 
#use i2c(master, SDA=PIN_C4, SCL=PIN_C3, FORCE_HW, restart_wdt)
#use fixed_io(A_outputs = PIN_A4)
#use fixed_io(B_outputs = PIN_B5, PIN_B6, PIN_B7)
#use fixed_io(C_outputs = PIN_C0, PIN_C2, PIN_C5, PIN_C6, PIN_C7)

#define CAN_BRG_PRESCALAR           9     // baud rate generator prescalar value: 3

#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     7       // phase segment 1 (def: 6 x Tq)
#define CAN_BRG_PHASE_SEGMENT_2       4       // phase segment 2 time select (def: 6 x Tq)

#define CAN_BRG_SEG_2_PHASE_TS        1     // phase segment 2 time select bit (true: free programmable)
#define CAN_BRG_SAM                   0     // sample once
#define CAN_BRG_WAKE_FILTER          0      // selects can bus line filter for wake up   bit                                                                                   
#define CAN_ENABLE_DRIVE_HIGH       1      // CANTX will drive Vdd when recessive
#define CAN_USE_EXTENDED_ID         1      // use extended or standard ID 
#include <string.h>
#include <can-18F2685.c>
#include <F:\PCWH\LCDIIC3\LCDIIC3_tools.c>
#zero_ram
#define     LCD1                    30                               // i2c-address for external intelligent LCD
#define    RelAuf   PIN_A4
#define   RelAb      PIN_C2
#define   CurrSens   PIN_B0
#define   CANEN      PIN_C5
// Global Variables
struct rx_stat rxstat;
   int32 rx_id;
   int in_data[8];
   int rx_len;

   int out_data[8];
   int32 tx_id = 1400;
   int1 tx_rtr = 0;
   int1 tx_ext = 1;
   int tx_len = 2;
   int tx_pri = 3;
   
   byte rtr_data = 50;
   byte rtr_len = 1;
 // ********** Makros ************************************************

#define    RelAuf_on   output_high   (RelAuf);
#define    RelAuf_off   output_low   (RelAuf);

#define    RelAb_on      output_high   (RelAb);
#define    RelAb_off   output_low   (RelAb);

#define    CAN_enable   output_low   (CANEN);
#define    CAN_disable   output_high   (CANEN);      

// MAIN 
void main(){
   byte val = 0;
   byte info = 0;
         port_b_pullups(false);   
           setup_adc_ports(NO_ANALOGS);
         setup_adc(ADC_OFF); 
         setup_wdt(WDT_OFF);
         setup_timer_0(RTCC_OFF);
         setup_timer_1(T1_DISABLED);
         setup_timer_2(T2_DISABLED,0,1);
         setup_timer_3(T3_DISABLED);   
         setup_ccp1(CCP_OFF);       
         setup_vref(FALSE);
 
         RelAuf_off
         RelAb_off                 
           
         CAN_enable                                                               // enable the PCA82C250            
         can_init();
         can_set_filter(800, 100, 400, 400, 600, 900, 400, 400, 400, 400);       // set recieve filter
              
         
      do{
           restart_wdt(); 
           if (can_kbhit()){                                                         // if data is waiting in buffer...          
              LCD_mode(LCD1,clear);
               if(RXB0CON.rxful){
                  LCD_showchar(LCD1,'0');
                  delay_ms(1000);                                                    // wait a little bit                       
               }
              else if(RXB1CON.rxful){
                  LCD_showchar(LCD1,'1');
                  delay_ms(1000);
               }
               else if(B0CONR.rxful){
                  LCD_showchar(LCD1,'2');
                  delay_ms(1000);
               }
               else if(B1CONR.rxful){
                  LCD_showchar(LCD1,'3');
                  delay_ms(1000);
               }
                      
            if(can_getd(rx_id, &in_data[0], rx_len, rxstat)) {                   //...then get data from buffer
               
               LCD_gotoyx(LCD1,2,1);                                             // set cursor on Line 2
               LCD_showvalue(LCD1, integer5, nosign, make16(make8(rx_id,1),make8(rx_id,0)));
               LCD_showvalue(LCD1, integer3, nosign, in_data[0]);
               LCD_showvalue(LCD1, integer3, nosign, in_data[1]);
               LCD_showvalue(LCD1, integer3, nosign, in_data[2]);
               LCD_gotoyx(LCD1,3,1);                                             // set Cursor on Line 3                               
                 LCD_showvalue(LCD1, integer3, nosign, rxstat.buffer);
               LCD_showvalue(LCD1, integer3, nosign, rxstat.filthit);
               
               if (in_data[0] == 2){                                             // turn on Relay "AUF"                             
                  RelAuf_on
               }
               else if (in_data[0] == 4){                                          // turn on Relay "AB"                                   
                  RelAb_on
               }
               else if (in_data[0] == 1){                                          // turn off both Relays                                   
                  RelAuf_off
                  RelAb_off
               }
            }
            else {
                  LCD_backlight(LCD1,off);                                          // blink backlight if there was an error
                  delay_ms(500);
                  LCD_backlight(LCD1,bright);
            }
            delay_ms(1000);
           }
           if(input(CurrSens)){
              out_data[0] = 50;
              out_data[1] = 4;
              //tx_id = 20;
              if(can_putd(tx_id, &out_data[0], tx_len, tx_pri, tx_ext, tx_rtr)){
                 LCD_showchar(LCD1,'G');                                            // sign for: GOOD TX                             
              }
              else {
                 LCD_backlight(LCD1,off);                                          // blink backlight if there was an error                                 
                 delay_ms(100);
                 LCD_backlight(LCD1,bright);
              }
           }
      }while(true);
}




And here is my can_set_filter - routine:

Code:

void can_set_filter(int16 rxid1, int16 rxid2, int16 rxid3, int16 rxid4, int16 rxid5, int16 rxid6, int16 rxid7, int16 rxid8, int16 rxid9, int16 rxid10) {
   can_set_mode(CAN_OP_CONFIG);   //must be in config mode before params can be set
   
   
   can_set_id(RX0MASK, CAN_MASK_FILTER_ALL, 1);                                  //set mask 0 // MATCH MASK 100%
   can_set_id(RX0FILTER0, rxid1, CAN_USE_EXTENDED_ID);                             //set filter 0 of mask 0
   can_set_id(RX0FILTER1, rxid2, CAN_USE_EXTENDED_ID);                             //set filter 1 of mask 0
   
   can_set_id(RX1MASK, CAN_MASK_FILTER_ALL, 1);                                  //set mask 1 // MATCH MASK 100%
   can_set_id(RX1FILTER2, rxid3, CAN_USE_EXTENDED_ID);                             //set filter 0 of mask 1
   can_set_id(RX1FILTER3, rxid4, CAN_USE_EXTENDED_ID);                             //set filter 1 of mask 1
   can_set_id(RX1FILTER4, rxid5, CAN_USE_EXTENDED_ID);                             //set filter 2 of mask 1
   can_set_id(RX1FILTER5, rxid6, CAN_USE_EXTENDED_ID);                             //set filter 3 of mask 1
   
   can_set_id(RXFILTER6, rxid7, CAN_USE_EXTENDED_ID);                             //                                                   
   can_set_id(RXFILTER7, rxid8, CAN_USE_EXTENDED_ID);
   can_set_id(RXFILTER8, rxid9, CAN_USE_EXTENDED_ID);
   can_set_id(RXFILTER9, rxid10, CAN_USE_EXTENDED_ID);
   
   
   can_set_mode(CAN_OP_NORMAL);
}


The routines about the LCD work on i2c and are tested well.
I use the LCD because there is no RS232 on the hardware.

There is only one other node on the bus and it sends one single message with ID 600 every time it is triggered.

Thanks for Your help anywhere.

Dirk
Bernhard
Guest







can-18F2685.c
PostPosted: Thu Mar 04, 2010 10:41 am     Reply with quote

Hallo Dirk,

wir haben auch den 18F2685 und den CCS-Compiler im Einsatz für eine Aufgabe mit dem CAN-Bus. Eine can-18F2685.c haben wir nicht von CCS bekommen und haben die can-18F4580.c genommen und abgeändert. Das Senden mit der can_putd-Routine funktioniert gut. Das am CAN-Bus angeschlossene Gerät arbeitet. Mit der can_getd-Routine kämpfen wir aber noch. Wäre schön wenn wir einen Kontakt in Deutschland bekämen mit Leuten, die sich auch mit Microchip und CCS rumschlagen Smile .
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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