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

INT_RDA2 wont work

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



Joined: 11 Mar 2016
Posts: 62
Location: izmir / Turkey

View user's profile Send private message

INT_RDA2 wont work
PostPosted: Thu Mar 26, 2020 10:53 pm     Reply with quote

18f25J50 , 5.081
Hi guys, I search the forum and find similar problems but couldn't find a proper solution to situation. So I'm asking for your help again =)

I'm trying to communicate an esp-01 module with my 18f25j50 and I want to use uart2 interrupt but I couldn't make it work. I use A0 and A1 as TX2 and RX2. I did many controls and tried many changes but couldn't make it work. RDA2 interrupt never fires.

If I connect esp to uart1 pins and change RDA2 names to RDA then everything works perfect without problem, but again, I want to use UART2. I don't know if it is a compiler error or am I missing something from datasheet but I checked and got sure that there isn't any hardware problem.

Can you guys take a look and guide me please?

Here is the simple code, just sending a message to esp and reads the reply
I cut off some of the code like pin defines and SFR defines to make it short.

main.c
Code:

#include <main.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "PCF8574_LCD.h"

#INT_RDA2
void RDA2_isr()
{
   output_bit(buzzer_cont,1);
   static int8 ctr2=0;
   int8 chr2=getc();
   if (chr2==13)
   {
      //If we have an end of line
      EspRcvBuff[ctr2]='\0'; //null terminate string
      ctr2=0; //clear the counter
      incoming_message2=1;
   }
   else
   {
      EspRcvBuff[ctr2++]=chr2; //add character to string
      if (ctr2>=ESPBUFFER_LENGHT-1)
         ctr2--; //ensure buffer can not overflow
   }
}

void clear_usart2_receiver(void)
{
char c;
c = RCREG2;
c = RCREG2;
c = RCREG2;
}

void chk_start_connection(){
   char srch1[]="Connection_Established_Warning";
   char srch2[]="Connection_Error";
   if(strstr(EspRcvBuff,srch1)!=NULL){
      fprintf(UART_CH1,"Connection Established\r\n");
      EspRcvBuff="";
      esp_response_acknowledged=1;
   }
   else if(strstr(EspRcvBuff,srch2)!=NULL){
      fprintf(UART_CH1,"Connection Failed\r\n");
      EspRcvBuff="";
      esp_response_acknowledged=1;
   }
   else {
      fprintf(UART_CH1,EspRcvBuff);
      EspRcvBuff="";
   }
}

void main()
{
   OSCTUNE = 0b11000000;   // select low frequency source and enable pll
   OSCCON |= 0b01110000;
   OSCCON &= 0b11111100;   // set internal oscillator frequency and system clock
   ADCON0 &= 0b11111110;   // disable A / D converter
   ANCON0 = 0xFF;
   ANCON1 |= 0b00011111;   // all pins are digital

   output_bit(ESP_EN,0);   
   output_bit(buzzer_cont,0);
     
   i2c_init(I2C_LCD,100000);
   lcd_begin(0x4E);
   lcd_cmd(LCD_CLEAR);
   lcd_goto(1,1);
   lcd_out("Test");
   lcd_goto(1,2);
   lcd_out("Print");
   fprintf(UART_CH1,"LCD Write Done\r\n");
   
   output_bit(ESP_EN,1);
   delay_ms(250);   
   clear_usart2_receiver();
   clear_interrupt(INT_RDA2);
   enable_interrupts(INT_RDA2); 
   enable_interrupts( GLOBAL ); //Enable interrupts
   fprintf(UART_CH1,"Interrupts Enabled\r\n");
   delay_ms(250);
   fprintf(UART_CH1,"Setup Done\r\n");
   EspRcvBuff="";
   fprintf(UART_CH1,"Buffer Cleared\r\n");
   fprintf(UART_CH2,"Start_Connection\r\n");
   fprintf(UART_CH1,"Connection Request Sent\r\n");
   while(esp_response_acknowledged==0)
   {
      if(incoming_message2){
         chk_start_connection();
         incoming_message2=0;
      }
   }
   fprintf(UART_CH1,"Reply Received\r\n");
   
   WHILE (TRUE)
   {
      delay_cycles(1);
   }
}


main.h
Code:

#include <18F25J50.h>
#device ADC=10

/* Device fuses programmed to work with 48Mhz internal osc settings */
#fuses NOCPUDIV                 //System Clock by 1
#fuses INTRC_PLL_IO             //Internal RC Osc with 4X PLL, no CLKOUT
#fuses PLL2                     //Divide By 2(8MHz oscillator input)
/*------------------------------------------------------------------*/
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES STVREN                   //Stack full/underflow will cause reset
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES NOPROTECT                //Code not protected from reading
#FUSES T1DIG                    //Secondary Oscillator Source may be select regardless of T1CON.3 state
#FUSES NOLPT1OSC                //Timer1 configured for higher power operation
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES DSWDTOSC_INT             //DSWDT uses INTRC as reference clock
#FUSES RTCOSC_INT               //RTCC uses Internal 31KHz Oscillator as reference source
#FUSES DSBOR                    //BOR enabled in Deep Sleep
#FUSES DSWDT                    //Deep Sleep Watchdog Timer enabled
#fuses NOIOL1WAY                //Allows multiple reconfigurations of peripheral pins
#FUSES MSSPMSK7                 //MSSP uses 7 bit Masking mode
#FUSES WPFP                     //Write/Erase Protect Page Start/End Location, set to last page or use WPFP=x to set page
#FUSES WPEND                    //Flash pages WPFP to Configuration Words page are write/erase protected
#FUSES NOWPCFG                  //Configuration Words page is not erase/write-protected
#FUSES WPDIS                    //All Flash memory may be erased or written

#use delay(internal=48MHz)


#use rs232(baud=9600,UART1,parity=N,bits=8,ERRORS,stream=UART_CH1)

#pin_select RX2=PIN_A1
#pin_select TX2=PIN_A0
#use rs232(baud=9600,UART2,parity=N,bits=8,ERRORS,stream=UART_CH2)

#use i2c(MASTER, I2C1, FAST=100000, FORCE_HW, NOINIT,STREAM=I2C_LCD)

#pin_select SDI2=PIN_C0
#pin_select SDO2=PIN_C1
#pin_select SCK2OUT=PIN_C2
#use spi(MASTER, SPI2, ENABLE=PIN_C6, MODE=0, BITS=8, stream=SPI_CH2)

#define ESPBUFFER_LENGHT 50
volatile char EspRcvBuff[ESPBUFFER_LENGHT],RDARcvBuff[ESPBUFFER_LENGHT];
volatile int1 incoming_message2=0,incoming_message=0,esp_response_acknowledged=0;



I can get "Connection Request Sent" message but cannot get "Reply Received" message while trying uart2 but I'm able to get both ESP's responses and Reply Received message if I try uart1.
_________________
There is nothing you can't do if you try
elcrcp



Joined: 11 Mar 2016
Posts: 62
Location: izmir / Turkey

View user's profile Send private message

PostPosted: Thu Mar 26, 2020 11:56 pm     Reply with quote

I also tried same code with dsPIC30F6012A and got exact same result, perfectly working on UART1 and INT_RDA but not interrupting on UART2 and INT_RDA2 Rolling Eyes
_________________
There is nothing you can't do if you try
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Fri Mar 27, 2020 1:57 am     Reply with quote

Use the compiler. All the settings you are doing directly are
better done using compiler functions:
Code:

   setup_adc(ADC_OFF);
   setup_adc_ports(NO_ANALOGS);

Since you don't post the register values used, there is no guarantee
that the existing code is talking to the right registers.... Sad

The oscillator should already be setup. Unless you have a very old
compiler the internal=48MHz should have done everything needed.

Now the receive code should be using the stream name. Otherwise
if the wrong UART is read, it'll hang forever in the receive interrupt.

There is an issue with how you clear the UART. Problem is that you do not
clear any error bits. If an error has become set, this will not be cleared
by reading the receive buffer, and since you clear the interrupt bit
the interrupt won't be called. Result if this has happened, the UART
will be completely hung....

The correct code to clear the UART is:
Code:

void clear_usart2_receiver(void)
{
char c;
  while (kbhit(UART_CH2))
     c = getc(UART_CH2);
}

Which then includes the compiler's code to clear the framing and
overrun errors if they occur.
Framing errors in particular will occur on boot, so this is necessary....

I suspect this is the problem. As you switch on a framing error occurs.
Then without any error clearing code in the clear routine, the UART
is stuck....
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Mar 27, 2020 2:25 am     Reply with quote

To amplify Ttelmah's comment:
Also, my very first thought as I started scanning your code, is "how's it
know where to get it from ?", regarding the getc() shown in bold below.
There's no stream specified. Also, according to CCS, you're supposed to use fgetc() here.

Quote:
#INT_RDA2
void RDA2_isr()
{
output_bit(buzzer_cont,1);
static int8 ctr2=0;
int8 chr2=getc();
if (chr2==13)
{
//If we have an end of line
EspRcvBuff[ctr2]='\0'; //null terminate string
ctr2=0; //clear the counter
incoming_message2=1;
}
else
{
EspRcvBuff[ctr2++]=chr2; //add character to string
if (ctr2>=ESPBUFFER_LENGHT-1)
ctr2--; //ensure buffer can not overflow
}
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Fri Mar 27, 2020 2:29 am     Reply with quote

and of course, I am relying on the fact that getc, is overloaded, and if
given a stream name behaves just like fgetc...
temtronic



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

View user's profile Send private message

PostPosted: Fri Mar 27, 2020 5:37 am     Reply with quote

hmm.. before trying to use interrupts...

...have you done a simple 'loopback' program using UART2 to confirm that the PIC does use UART2 ?

I don't use that PIC, and see it has programmable pins, maybe there's a compiler bug ?

OR.... maybe a hardware error ? TX swapped for RX, solder bridge,???

I always start with the simple stuff first, confirm then move on.

Jay
elcrcp



Joined: 11 Mar 2016
Posts: 62
Location: izmir / Turkey

View user's profile Send private message

PostPosted: Fri Mar 27, 2020 10:30 am     Reply with quote

Solved,

Thank you Jay, I always do these simple checks first, whenever there is a problem I start with checking if power is connected and go on checking step by step.

I corrected the buffer cleaner routine as Ttelmah said. I must say I had many problems with ccs's built in functions in the past so I make a habit of to do bit bang config.

You both are completely right Ttelmah and PCM, thank you. I totally overlooked getc(), as you say; how could it know where to read?

Since uart1 is the default of every uart command, it works fine fine getc without any stream name, but uart2 needed stream name.
_________________
There is nothing you can't do if you try
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Fri Mar 27, 2020 10:40 am     Reply with quote

So actually the interrupt was being called, but could never exit... Sad

INT_RDA, and RDA2, both have the feature that they stay 'set' if data
isn't read. Explains what you were seeing...
elcrcp



Joined: 11 Mar 2016
Posts: 62
Location: izmir / Turkey

View user's profile Send private message

PostPosted: Fri Mar 27, 2020 11:41 am     Reply with quote

Quote:
So actually the interrupt was being called, but could never exit... Sad

INT_RDA, and RDA2, both have the feature that they stay 'set' if data
isn't read. Explains what you were seeing...


Actually I'm not sure about it, I think it wasn't entering into routine but hanging when called. I did set a pin for check to see if it was entering to routine but it never got set on interrupt calls. Rolling Eyes
_________________
There is nothing you can't do if you try
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Fri Mar 27, 2020 11:47 am     Reply with quote

OK. It might have been the UART clear then. If an error was set, then
the interrupt would never get called...
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Mar 27, 2020 12:02 pm     Reply with quote

In the code below, it jumps to the UART1 receiver routine. But there is
most likely nothing in the receiver, so it loops forever. This is the hang.
Quote:

.... #use rs232(baud=9600,UART1,parity=N,bits=8,ERRORS,stream=UART_CH1)
00AE: BTFSS PIR1.RCIF // Do we have a char in UART1 receiver ?
00B0: BRA 00AE // If not, loop until we do (ie., hang)
00B2: MOVFF RCSTA1,rs232_errors
00B6: MOVFF RCREG1,01 // If yes, get char from UART1 receiver
00BA: BTFSS rs232_errors.1 // Skip next BRA if we got an error
00BC: BRA 00C2 // If no error, exit
00BE: BCF RCSTA1.CREN1
00C0: BSF RCSTA1.CREN1
00C2: GOTO 00C8 (RETURN)
....................
.... #pin_select RX2=PIN_A1
.... #pin_select TX2=PIN_A0
.... #use rs232(baud=9600,UART2,parity=N,bits=8,ERRORS,stream=UART_CH2)
*** Note no UART2 receiver code is generated. Only UART1 above ***



.... //-------------------------------
.... #INT_RDA2
.... void RDA2_isr()
00C6: BRA 00AE // Jump to the UART1 getc() routine
00C8: MOVFF 01,chr2 // Return to here from that (except, not...)
.... {
.... int8 chr2 = getc();
....
00CC: BCF PIR3.RC2IF // Clear UART2 receive interrupt flag
00CE: GOTO 0060 // Go to CCS interrupt exit code
.... }
.....
.... //====================================
..... void main()
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Fri Mar 27, 2020 12:08 pm     Reply with quote

Yes, because his serial read is right at the start of the code, it won't
reach any code to signal it has reached the routine....
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