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 support@ccsinfo.com

After upgrading to 5.019 RDA Interrupt no longer works
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
vafonkin



Joined: 20 Mar 2012
Posts: 16

View user's profile Send private message

After upgrading to 5.019 RDA Interrupt no longer works
PostPosted: Tue Dec 16, 2014 1:05 pm     Reply with quote

I recently upgraded to 5.019 and I am experiencing weird issue - with no code changes made and everything working and compiles with 4.x ccs-c compiler, RDA interrupt no longer works at all.

Any ideas why it works with old but not with 5.019??? Are there any changes to use rs232, it looks like all data over UART is garbled...

here is my fuses:
Code:

#fuses INTRC_IO,NOWDT,NOPROTECT,PUT,NOCPD,NOLVP,NOMCLR,BROWNOUT


here is code:
Code:

#use rs232(baud=19200, parity=N, bits=8, UART1)   


In addition all characters sent out to UART are garbled now.

NO changes to the code - just updated to 5.019
Code:
newguy



Joined: 24 Jun 2004
Posts: 1903

View user's profile Send private message

PostPosted: Tue Dec 16, 2014 2:30 pm     Reply with quote

I'll bet your clock isn't getting set correctly and that's the reason why you're receiving garbled characters from the PIC and that the PIC's RDA interrupt seems to have stopped working.

What is the processor?
vafonkin



Joined: 20 Mar 2012
Posts: 16

View user's profile Send private message

PostPosted: Tue Dec 16, 2014 2:45 pm     Reply with quote

newguy wrote:
I'll bet your clock isn't getting set correctly and that's the reason why you're receiving garbled characters from the PIC and that the PIC's RDA interrupt seems to have stopped working.

What is the processor?


It was working fine and stopped after upgrade. I use PIC18F26k20

UPDATE:

while checking baud rate with oscilloscope, I see it sends out data with 9600, not with the baud rate I set in my settings:

Code:

#use rs232(DISABLE_INTS, BAUD=19200, parity=N, bits=8, UART1)

Shocked

So now I have to change my question ... it looks like interrupt is working however baud rate is not getting set to what I need. Why?
newguy



Joined: 24 Jun 2004
Posts: 1903

View user's profile Send private message

PostPosted: Tue Dec 16, 2014 4:27 pm     Reply with quote

Your processor clock is getting set to half of what you want it to be.

As to why, there are two possibilities.
1. Your old version of the compiler correctly set your PIC's processor clock but now v5 is doing it wrong.
2. Your old version actually set it wrong and v5 now does it correctly but this exposed another compiler issue with v4 that masked the problem by screwing up the UART clock speed.

Either way, just give us a very short program that demonstrates the problem. Include all #use lines, etc.
vafonkin



Joined: 20 Mar 2012
Posts: 16

View user's profile Send private message

PostPosted: Tue Dec 16, 2014 5:54 pm     Reply with quote

Thank you for response,

main.h :

Code:

#define DEV_PIC18F26K20
#include <18F26K20.h>
#device adc=8
#fuses INTRC_IO,NOWDT,NOPROTECT,PUT,NOCPD,NOLVP,NOMCLR,BROWNOUT
#use delay(clock=7995392)


main.c :

Code:

// *********************************************************************************************************//
//    This is RX80M Project by Vadim Afonkin KB1RLI - contact me vadim.afonkin [ at ] gmail.com              //
//    Use Timer0 to clock 1sec - will drift 1-2 sec in 2-3 hours or Timer1 with external 32.768 oscillator   //
//   for precise RTC. Call do_1sec_event()  from Timer0 OR Timer1. Set clock to #use delay(clock=7995392)   //
//   Requires 10k pullup resistor, since port A does not have internal pullups.                              //
// *********************************************************************************************************//

#include <main.h>
#include <stdlib.h>
#include <math.h>

#use rs232(BAUD=19200, parity=N, bits=8, UART1)   //used for GPS

// Needed for Timer0
#define HIGH_START_SLOW    123      // to correcr 1 sec error
#define HIGH_START_FAST    122      // to correcr 1 sec error

// GPS DEFINES
#define GPS_HEADER          0
#define GPS_TIME          1
#define GPS_VALID          2
#define GPS_LAT          3
#define GPS_LAT_N_S       4
#define GPS_LON          5
#define GPS_LON_E_W       6
#define GPS_SPEED         7
#define GPS_TRUE_HEADING   8
#define GPS_DATE_OF_FIX      9
#define GPS_MAG_VAR         10
#define GPS_MAG_VAR_E_W      11
#define GPS_CHECKSUM      12
#define R                6371
#define TO_RAD (3.1415926 / 180)
#define TO_DEG (180 / 3.1415926)

byte high_i, HIGH_START_BYTE=0;

#Byte TMR1H = 0xFCF         // TIMER1 HIGH BYTE LOOK DATASHEET
#Byte T1CON = 0xFCD        // TIMER1 CONFIG REGISTER LOOK DATASHEET
#Byte RCREG = 0xFAE         // UART RECEIVE REGISTER LOOK DATASHEET
static int8 tick=0;         // TIMER COUNTER FOR SECONDS

static int gps_state,gps_have_packet;
static int16 gps_index;
static char gps_string[82],gps_string_copy[82];
static char GPGGA[7]="$GPGGA";
static char GPGSA[7]="$GPGSA";
static char GPGSV[7]="$GPGSV";
static char GPRMC[7]="$GPRMC";
static char GPVTG[7]="$GPVTG";
static char GPS_ARRAY[17];
static char *token=0;
static char delimeter[2] = ",";
static char S[2] = "S";
static char W[2] = "W";
static char ValidFix[2] = "A";
static char LatDegTmp[3];
static char LatMinTmp[9];
static float32 Lat,Lon;
static char LonDegTmp[4];
static char LonMinTmp[10];
static char sLat[];
static char sLon[];
static float MagVar=0;
float dist;


void do_1sec_event(void);
void parse_gps(void);
void get_lat_lon(void);
void distance(void);

#int_rtcc
void Timer0Interrupt(void){   
   if(--high_i==0){
      if(HIGH_START_BYTE==0){
         high_i=HIGH_START_FAST;
         HIGH_START_BYTE=1;
      }else{
         high_i=HIGH_START_SLOW;
         HIGH_START_BYTE=0;
      }
      do_1sec_event();      // update clock, etc
   }
}

#int_TIMER1
void TIMER1_isr()          // 2^16=  65536/2 = 32768 * 1/32.768Hz <--- (1sec)                     
{
      bit_clear(T1CON,7);     //Enable access to the individual bytes of the timer register
      Bit_Set(TMR1H,7);      //Add 32768 to timer1 by setting high bit or timer register       
      Bit_Set(T1CON,7);      //Disable access to the individual bytes of the timer register
}

void do_1sec_event(void){
   if(tick<=59){
      tick++;
   }
}

#INT_RDA
void isr_gps(void){
unsigned char c;

      c = RCREG;

      switch (gps_state){
         case 0: if(gps_have_packet==0){
                     if(c == 0x24){
                        gps_index = 0;
                        gps_string[gps_index] = c;
                        gps_index = 1;
                        gps_state = 1;;
                     }
               }
               break;
         case 1: gps_string[gps_index] = c;

               if((c == 0x0A)||(c == 0x0D)){
                     gps_have_packet = 1;
                     gps_string[gps_index + 1] = 0;
                     gps_state = 0;
               }

            if(gps_index >= sizeof(gps_string)-1){
                     gps_string[gps_index + 1] = 0;
                     gps_have_packet = 1;
                     gps_state = 0;
               }else{
                     gps_index++;
               }

               break;

      default: gps_state = 0;
               break;
   }
}

void main() {
float32 testdeg;

   gps_have_packet=0;   // initialize uart
   high_i=HIGH_START_SLOW;
   setup_timer_0(RTCC_8_BIT|RTCC_DIV_128);
      setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1|T1_CLK_OUT);  // external TIMER1 with 32.768Khz ,clock out for oscillator,asynchronus mode
   enable_interrupts(INT_TIMER1);                   // enable Timer 1 interrupt
   enable_interrupts(INT_RTCC);                      // enable Timer0 interrupt
   enable_interrupts(INT_RDA);                   // enable INT_RDA to read GPS data
    enable_interrupts(GLOBAL);                      // enable all interrupts
   delay_ms(2500);                              // 2.5 sec needed to initialize LCD

   putc(12);   // clear screen
   printf("Ready\n");

   while(1){

      // test our calculation saacuracy
      //testdeg = TO_DEG*asin(acos(atan(tan(cos(sin(9*TO_RAD))))));
      //printf("%f9.7\r\n", testdeg);
      //delay_ms(2000);

      if(gps_have_packet==1){
         parse_gps();
         if(strstr(gps_string_copy, GPRMC)){
            distance();
            printf("DIST: %f\r\n",dist);
         }
      }
   }
}


void parse_gps(void){
int i=0;

//test
/*
for(i=0;i<sizeof(gps_string);i++){
   printf("%s\r\n",gps_string[i]);
}
*/
   strncpy(gps_string_copy,gps_string,82);      //strcpy gone in v5.019????
   gps_have_packet = 0; // release interrupt to get new data
   if(strstr(gps_string_copy, GPRMC)){

      i=0;
      token = strtok(gps_string_copy, delimeter);

      while(token!=NULL){
         GPS_ARRAY[i]=token;
                  token = strtok(NULL, delimeter);
         i++;
            }

      if(strstr(GPS_ARRAY[GPS_VALID],ValidFix)){
         get_lat_lon();
         if(MagVar==0){
            MagVar = atof(GPS_ARRAY[GPS_MAG_VAR]);
            if(strstr(GPS_ARRAY[GPS_MAG_VAR_E_W], W)){
                   MagVar=MagVar * -1;
                }
         }
         printf("MAG VAR: %f\r\n",MagVar);
      }else{
         printf("NO VALID FIX\r\n");
      }
   }
}


void get_lat_lon(void){
int i=0;
   
      // GET LATITUDE
      sLat=GPS_ARRAY[GPS_LAT];

      for (i=0;i<2;i++){
                   LatDegTmp[i]=sLat[i];
                }

                for (i=0;i<8;i++){
                   LatMinTmp[i]=sLat[2+i];
                }

      Lat=atof(LatDegTmp)+(atof(LatMinTmp)/60);

      if(strstr(GPS_ARRAY[GPS_LAT_N_S], S)){
                   Lat=Lat * -1;
                }

      // GET LONGITUDE
      sLon=GPS_ARRAY[GPS_LON];

      for (i=0;i<3;i++){
                   LonDegTmp[i]=sLon[i];
                }

                for (i=0;i<9;i++){
                   LonMinTmp[i]=sLon[3+i];
                }

      Lon=atof(LonDegTmp)+(atof(LonMinTmp)/60);

      if(strstr(GPS_ARRAY[GPS_LON_E_W], W)){
                   Lon=Lon * -1;
                }

      printf("LAT: %9.7f\r\n",Lat);
      printf("LON: %9.7f\r\n",Lon);
}


void distance(void){
float32 mLat1,mLat2,mLon1,mLon2,dLat,dLon,a,c;
char cLat1[8] = "42.3079";
char cLon1[9] = "-71.2010";
char cLat2[8] = "42.3065";
char cLon2[9] = "-71.2020";

   
      // FOR TEST ONLY
      mLat1 = atof(cLat1);
      mLat2 = atof(cLat2);
      mLon1 = atof(cLon1);
      mLon2 = atof(cLon2);


      mLat1 = mLat1*TO_RAD;
      mLat2 = mLat2*TO_RAD;
      mLon1 = mLon1*TO_RAD;
      mLon2 = mLon2*TO_RAD;

      dLat = mLat2-mLat1;
      dLon = mLon2-mLon1;
      a = sin(dLat/2) * sin(dLat/2) + cos(mLat1) * cos(mLat2) * sin(dLon/2) * sin(dLon/2);
      c = 2 * atan2(sqrt(a),sqrt(1-a));
      dist = R * c;
}


As a side note - I noticed strcpy gone in v5.xxx ?
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Tue Dec 16, 2014 6:29 pm     Reply with quote

newguy wrote:
Either way, just give us a very short program that demonstrates the problem. Include all #use lines, etc.

What did he say?

Mike
vafonkin



Joined: 20 Mar 2012
Posts: 16

View user's profile Send private message

PostPosted: Tue Dec 16, 2014 6:52 pm     Reply with quote

Big pardon.... here it is "stripped":

Code:

// *********************************************************************************************************//
//    This is RX80M Project by Vadim Afonkin KB1RLI - contact me vadim.afonkin [ at ] gmail.com              //
//    Use Timer0 to clock 1sec - will drift 1-2 sec in 2-3 hours or Timer1 with external 32.768 oscillator   //
//   for precise RTC. Call do_1sec_event()  from Timer0 OR Timer1. Set clock to #use delay(clock=7995392)   //
//   Requires 10k pullup resistor, since port A does not have internal pullups.                              //
// *********************************************************************************************************//

#include <main.h>
#include <stdlib.h>
#include <math.h>

#use rs232(BAUD=19200, parity=N, bits=8, UART1)   //used for GPS

// Needed for Timer0
#define HIGH_START_SLOW    123      // to correcr 1 sec error
#define HIGH_START_FAST    122      // to correcr 1 sec error

#define TO_RAD (3.1415926 / 180)
#define TO_DEG (180 / 3.1415926)



byte high_i, HIGH_START_BYTE=0;

#Byte TMR1H = 0xFCF         // TIMER1 HIGH BYTE LOOK DATASHEET
#Byte T1CON = 0xFCD        // TIMER1 CONFIG REGISTER LOOK DATASHEET
#Byte RCREG = 0xFAE         // UART RECEIVE REGISTER LOOK DATASHEET
static int8 tick=0;         // TIMER COUNTER FOR SECONDS



#int_rtcc
void Timer0Interrupt(void){   
   if(--high_i==0){
      if(HIGH_START_BYTE==0){
         high_i=HIGH_START_FAST;
         HIGH_START_BYTE=1;
      }else{
         high_i=HIGH_START_SLOW;
         HIGH_START_BYTE=0;
      }
      do_1sec_event();      // update clock, etc
   }
}

#int_TIMER1
void TIMER1_isr()          // 2^16=  65536/2 = 32768 * 1/32.768Hz <--- (1sec)                     
{
      bit_clear(T1CON,7);     //Enable access to the individual bytes of the timer register
      Bit_Set(TMR1H,7);      //Add 32768 to timer1 by setting high bit or timer register       
      Bit_Set(T1CON,7);      //Disable access to the individual bytes of the timer register
}

void do_1sec_event(void){
   if(tick<=59){
      tick++;
   }
}

#INT_RDA
void isr_gps(void){
unsigned char c;

      c = RCREG;

      switch (gps_state){
         case 0: if(gps_have_packet==0){
                     if(c == 0x24){
                        gps_index = 0;
                        gps_string[gps_index] = c;
                        gps_index = 1;
                        gps_state = 1;;
                     }
               }
               break;
         case 1: gps_string[gps_index] = c;

               if((c == 0x0A)||(c == 0x0D)){
                     gps_have_packet = 1;
                     gps_string[gps_index + 1] = 0;
                     gps_state = 0;
               }

            if(gps_index >= sizeof(gps_string)-1){
                     gps_string[gps_index + 1] = 0;
                     gps_have_packet = 1;
                     gps_state = 0;
               }else{
                     gps_index++;
               }

               break;

      default: gps_state = 0;
               break;
   }
}

void main() {
float32 testdeg;

   gps_have_packet=0;   // initialize uart
   high_i=HIGH_START_SLOW;
   setup_timer_0(RTCC_8_BIT|RTCC_DIV_128);
      setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1|T1_CLK_OUT);  // external TIMER1 with 32.768Khz ,clock out for oscillator,asynchronus mode
   enable_interrupts(INT_TIMER1);                   // enable Timer 1 interrupt
   enable_interrupts(INT_RTCC);                      // enable Timer0 interrupt
   enable_interrupts(INT_RDA);                   // enable INT_RDA to read GPS data
    enable_interrupts(GLOBAL);                      // enable all interrupts
   setup_uart(UART_AUTODETECT);

   while(1){

      testdeg = TO_DEG*asin(acos(atan(tan(cos(sin(9*TO_RAD))))));
      printf("%f9.7\r\n", testdeg);
      delay_ms(2000);

   }
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Dec 16, 2014 10:21 pm     Reply with quote

Quote:
setup_uart(UART_AUTODETECT);

Why does your 2nd program have this line, but your first program doesn't ?
vafonkin



Joined: 20 Mar 2012
Posts: 16

View user's profile Send private message

PostPosted: Tue Dec 16, 2014 10:44 pm     Reply with quote

Just to clarify, I understand RX is rate coming from other device, but I am setting baud on PIC to 19200 and I do not see it happening. Same code works compiled with 4.057 but not with 5.xxx Something messed up on uart

I spent all day digging problem and can't figure it out. Usually I am good with debugging, but not today Shocked

Auto detect does not help. I tried both - with and without auto detect.

I can't roll back to v 4.x because what was not working there compiles and works now with 5.xxx , except UART Smile
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Dec 16, 2014 10:56 pm     Reply with quote

Quote:
static char GPS_ARRAY[17];

Based on the way you use GPS_ARRAY, I reckon it's supposed to be
an array of pointers. But pointers in 18F PICs take 2 bytes.
If you want an array of pointers to strings, you should declare it like this:
Code:
static char *GPS_ARRAY[17];

Then the compiler will allocate 2 bytes per pointer.


Here it seems that you're trying to make two uninitialized pointers:
Quote:

static char sLat[];
static char sLon[];

But the compiler only allocates one byte of ram to each one.
From the .SYM file:
Quote:
138 sLat
139 sLon

Whereas, if I declare a pointer to a char in the standard way,
Quote:
static char *my_ptr;

the .SYM file shows 2 bytes are allocated to the pointer, as required:
Quote:
13A-13B my_ptr
vafonkin



Joined: 20 Mar 2012
Posts: 16

View user's profile Send private message

PostPosted: Tue Dec 16, 2014 11:14 pm     Reply with quote

You have a valid point but it does not explain why UART is not getting set properly. This was working with 4.057 .....

BTW what happened with strcpy in between 4.057 and 5.xxx ? I dont see it anymore and it will not compile.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Dec 17, 2014 12:21 am     Reply with quote

Quote:
what happened with strcpy in between 4.057 and 5.xxx ?

It works for me in vs. 5.019. I got this in the output window when I ran it
in MPLAB v8.92 simulator:
Quote:

Hello 2
Hello Hello

Test program:
Code:
#include <18F26K20.h>
#fuses INTRC_IO, NOWDT
#use delay(clock=8M)
#use rs232(baud=9600, UART1, ERRORS)

//==================================
void main()
{
char s1[10] = "1";
char s2[10] = "2";

// Copy Hello into the first string.
strcpy(s1, "Hello");
printf("%s %s \r", s1, s2);

// Copy the 1st string into the 2nd string.
strcpy(s2, s1);
printf("%s %s \r", s1, s2);

while(TRUE);
}


Last edited by PCM programmer on Wed Dec 17, 2014 12:56 am; edited 1 time in total
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Dec 17, 2014 12:55 am     Reply with quote

Quote:
while checking baud rate with oscilloscope, I see it sends out data with 9600

I think you are interpreting your scope readings incorrectly. If I look
at pin C6 (Tx) on my scope while running the test program shown below,
I see a continuous squarewave and the scope's built-in frequency counter
says 9.64 KHz. But that's the frequency of a full cycle. It takes two bit
cells to make a full cycle. So the actual baud rate is 2x that, or 19.2
Kbaud. So it's working OK.

I submit that the reason you're seeing garbage with vs. 5.019 is probably
because of your incorrect pointers, which are missing the MSB byte.
I then theorize that the earlier compiler version may have allocated
variables in low ram (0 to FF), which masked the problem of the missing
MSB. Then in 5.019, the compiler allocates ram beyond the 0xFF
boundary and the missing MSB of the address causes incorrect data to
be read from ram (the addresses are wrong), which appears as garbage
on the screen.

Test program:
Code:

#include <18F46K20.h>
#device adc=8
#fuses INTRC_IO,NOWDT,NOPROTECT,PUT,NOCPD,NOLVP,NOMCLR,BROWNOUT
#use delay(clock=8M)
#use rs232(BAUD=19200, parity=N, bits=8, UART1)   //used for GPS

//==================================
void main()
{

while(TRUE)
  {
   putc(0x55);
  }
 
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19350

View user's profile Send private message

PostPosted: Wed Dec 17, 2014 1:35 am     Reply with quote

There is one point that hasn't already been made, of the strange clock rate.
The internal oscillator can't generate 7995392Hz, so why try to set it to this?.
You will note PCM_programmer set the clock to 8Mhz, which is a legal setting for the internal oscillator.....
It may be as simple as a difference in the way the two compilers handle an impossible setting.
If you are using this clock setting to simplify the divisions done by the UART settings etc., then tell the compiler this is what you want:
Code:

   #use delay(clock=7995392,internal=8MHz)

Which says 'set the internal oscillator to 8MHz, but treat it as if it is running at 7995392Hz.
temtronic



Joined: 01 Jul 2010
Posts: 9165
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Dec 17, 2014 7:00 am     Reply with quote

re: 'odd' clock setting..... from the comments in the program, it appears you want a 1 Hz interrupt.

One suggestion is to look at the SW RTC program in the code library here. It works fine and may be better than your current code.

While using the internal RC OSC saves a few pennies, it's not accurate for timers that need precision.Depending on the purpose of the project, you may want to upgrade to a real crystal and 2 caps,though you lose 2 I/O pins. Compromise, it's always a compromise...

Another option might be to add an external HW RTC like the DS1307. Gives you a 1Hz interrupt, battery backed,accurate...

something you might consider....

Jay
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