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_RDA, 2 x RS232 connections, circular buffer not working

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



Joined: 22 Jun 2016
Posts: 5

View user's profile Send private message

INT_RDA, 2 x RS232 connections, circular buffer not working
PostPosted: Tue Apr 18, 2017 5:33 am     Reply with quote

I have a PIC18F248 connected to PC via a MAX232 (pins RC4, RC5) and a ESP8266 (pins RC6, RC7). The ESP8266 is connected to the hardware EUSART pins to enable highest baud rate (eventually). At the moment just trying to ensure can receive data stream OK so can then write the appropriate parser.

The code below is based upon the CCS ex_sisr.c

Communication between the PIC and the PC is working fine. Data to and from the ESP8266 is also working (the AT+GMR commands the ESP8266 to output a long stream of firmware version and SDK info, which is good for testing comms in this case).

Problem is the INT_RDA and the circular buffer doesn't appear to be working correctly.

If I include a delay_ms after sending the AT+GMR command to the ESP8266 (see the commented out line in the code listing) the expected information is displayed on the PC/terminal program received from the ESP8266 via the PIC/MAX232. If the delay_ms is commented out, the PC/terminal program output is "garbled" for the starting characters.

Appears that the circular buffer is not working and getting over written or similar???

I've stared at this heaps to no avail, any help greatly appreciated. (Oh, compiler version 4.14).

Code:

#include <18F248.h>
#device adc=10
#priority INT_RDA, INT_TIMER1
#zero_ram

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES NOBROWNOUT         //No brownout reset
#FUSES NOLVP                     //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES PUT                      //Power Up Timer

#use delay(clock=24000000)
#use rs232(stream=PC_IO, baud=9600,parity=N,xmit=PIN_C4,rcv=PIN_C5,bits=8, ERRORS) 
#use rs232(stream=PICinput, baud=38400,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8, ERRORS)

#define LED_BUFFER_OVERRUN PIN_C0
#define BUFFER_SIZE        64
#define BUFFER_kbhit       (next_in!=next_out)

int8 buffer[BUFFER_SIZE];
int8 next_in = 0;
int8 next_out = 0;
int8 bufferOverrunFlag = 0;
int8 tickCount = 0;
int8 timeOut = 0;
int8 timeOutFlag = false;
int8 cmdActiveFlag = false;

#INT_TIMER1
void timer1_interrupt() { //Freq 13.3hz, period=0.075sec
   tickCount++;
   if (tickCount > timeOut) {
      disable_interrupts(INT_TIMER1);
      timeOutFlag = true;
      tickCount = 0;
   } else {
      set_timer1(9285); //prescaler=8, 24Mhz, preload=9285 -> Freq 13.3hz, period=0.075sec
   }
}

#INT_RDA
void serial_isr() {
   int t;
 
   buffer[next_in]=fgetc(PICinput);
   t=next_in;
   next_in=(next_in+1) % BUFFER_SIZE; 
   if(next_in==next_out) { // Buffer full !!
     next_in=t;           
     bufferOverrunFlag = 1;
   }
}

char buffer_getc() {
   char c;

   while(!BUFFER_kbhit);
   c=buffer[next_out];
   next_out=(next_out+1) % BUFFER_SIZE;
   return(c);
}

void main() {
   char recChar;

   setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);     
   enable_interrupts(GLOBAL);   
   output_low(LED_BUFFER_OVERRUN);
   enable_interrupts(INT_RDA);
   delay_ms(1000);               
   next_in=next_out;           
   fprintf(PC_IO,"\n\rStart\n\r");
 
   while(TRUE){     
     if (cmdActiveFlag==1) {                   
        while (BUFFER_kbhit) {           
           recChar=buffer_getc();     
           fprintf(PC_IO,"%c",recChar);     
        }
        if (timeOutFlag == 1) {
           fprintf(PC_IO,"\n\r**** TIMED OUT ****\n\r");
           cmdActiveFlag=false;
           next_in=next_out; //empty buffer
        }
        if (bufferOverrunFlag==1) output_high(LED_BUFFER_OVERRUN);
     }                         
     if (kbhit(PC_IO) && cmdActiveFlag == false) { //command etc received from PC           
         recChar = fgetc(PC_IO);
         switch (recChar) {
            case 'G': fprintf(PC_IO,"\n\rSENT CMD\n\r");         
                      fprintf(PICinput,"AT+GMR\r\n"); //start input stream to PIC
                      cmdActiveFlag = true;
                      timeOut = 128; //128*0.075sec = 9.6sec
                      timeOutFlag = false;
                      tickCount = 0;
                      set_timer1(9285); enable_interrupts(INT_TIMER1);
//delay_ms(250); //**** DUMMY DELAY *********************************************                 
                      break;
            default:  fprintf(PC_IO,"Unknown cmd\n\r");
                      break;
         }
     }
   }
}
temtronic



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

View user's profile Send private message

PostPosted: Tue Apr 18, 2017 6:19 am     Reply with quote

Basic question... that's a 5 volt PIC and a 3 volt peripheral, so do you have proper logic level interface between the two devices? I know you say it works...but it might be 'marginal'....

Jay
vlady_2009



Joined: 22 Jun 2016
Posts: 5

View user's profile Send private message

PostPosted: Tue Apr 18, 2017 6:41 am     Reply with quote

No that's taken into account, separate linear regulators supplying the appropriate voltages, with a resistor divider for the conversion on the PIC TX to ESP8266 RX.

When using a large enough buffer, no problems with getting the expected responses from the ESP8266, just a problem when trying to use a small buffer/interrupt etc.
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Tue Apr 18, 2017 7:21 am     Reply with quote

What compiler version are you using? There was a period, though I can't remember which versions were affected, where printf was incorrectly leaving serial interrupts turned off. That would give similar symptoms to those you are reporting.
vlady_2009



Joined: 22 Jun 2016
Posts: 5

View user's profile Send private message

PostPosted: Tue Apr 18, 2017 7:36 am     Reply with quote

RF Developer

I'm using compiler version 4.14 if that helps.
Regards
temtronic



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

View user's profile Send private message

PostPosted: Tue Apr 18, 2017 7:50 am     Reply with quote

It's not data TO the ESP rather FROM the ESP that may be marginal... you have to see what the PIC wants as a '1' for that input pin and then see IF the ESp can produce it. The ESp might give say 3.0 as a '1' and the PIC needs 4.2 as a '1'.
Usually (from my memory...) the PIC UART RCV pin is type ST ( D041...spec), so needs 80% VDD as a logical '1'. 5 *.8=4 volts. If this is true for your PIC (you'll have to check) then the ESP can never give a true '1'.
You might be lucky and it gives a 3.3 for a '1' and the PIC seems happy with that but really you need to check the datasheet.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Tue Apr 18, 2017 2:04 pm     Reply with quote

CCS compiler numbers are always X.XXX.

Look at the end of your listing file to get the number. 4.140?.
If it was 4.014, then 'give up'. This was before V4 became a usable compiler...

However I'd say that your problem is undoubtedly that the module does not produce enough voltage to drive the PIC serial input.
It _needs_ an input buffer.
vlady_2009



Joined: 22 Jun 2016
Posts: 5

View user's profile Send private message

PostPosted: Tue Apr 18, 2017 8:09 pm     Reply with quote

Guys

Used a buffer (from CD4050) to convert the ESP8266 TX to 5v for input to PIC - same problem observed.

Version 4.140 originally used, tried also compiling with version 5.008 - same problem observed.

Below is a annotated screen shot of the output on the serial monitor when running the code (includes using CD4050 buffer and version 5.008).

1. top portion shows output when delay_ms(250) is included to effectively allow sufficient time for ESP8266 to finish output into the PIC buffer without other portion of the main code running. This output is as per expected as confirmed from observing output from ESP8266 connected directly to PC via a USB-TTL converter (no PIC involved). This would indicate that the #INT_RDA routine and loading into the buffer etc is working correctly, and that subsequently, the buffer_getc() routine is working correctly outputting to the PC.

2. lower portion shows output when the delay_ms(250) is commented out. This shows the problem in that the circular buffer does not seem to be working correctly, outputting to PC when PIC cycles available and the interrupt storing chars when received.

Seems that I have something wrong in the code.

[img]
http://i.imgur.com/1fFrwdZ.jpg
[/img]
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Apr 18, 2017 9:53 pm     Reply with quote

You're running a soft UART for the PC_IO stream. If any interrupts
occur while the soft UART is transmitting or receiving, it will disrupt
the bit timing and you'll get garbled data.

You could add DISABLE_INTS to the #use rs232() statement for the
PC_IO stream. Ideally, you would make the baud rate for the PC_IO
stream be as fast as possible, to reduce the amount of time that interrupts
are disabled.

The CCS manual says (in the #use rs232 section):
Quote:

DISABLE_INTS -

Will cause interrupts to be disabled
when the routines get or put a
character. This prevents character
distortion for software implemented
I/O and prevents interaction between
I/O in interrupt handlers and the main
program when using the UART.
vlady_2009



Joined: 22 Jun 2016
Posts: 5

View user's profile Send private message

PostPosted: Wed Apr 19, 2017 1:02 am     Reply with quote

PCM programmer

Thanks, DISABLE_INTS in the #use rs232() statement for the PC_IO stream was the solution,
coupled with that the baud rate needed to be at least 19200 for the PC_IO stream to avoid missing input via INT_RDA when interrupts off during soft UART call.

Thanks to all that replied.
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