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

Serial problem
Goto page 1, 2, 3, 4, 5  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
BLL



Joined: 11 Nov 2006
Posts: 181
Location: Birmingham, UK

View user's profile Send private message

Serial problem
PostPosted: Thu Aug 29, 2013 3:17 pm     Reply with quote

Hi, I have an 18F2620 at 40MHz (10MHz H4). The h/w uart on C6 and C7 is set at 9600Bd. I have set it to display text on a serial LCD (PHAnderson LCD117) if the text is preceded by an exclamation mark, eg. !This is text, with the following code:
Code:

if(kbhit())
  {
     id = fgetc(rpi);
if(id == '!') //setup params to follow
      {
       fgets(dataString, rpi); //get the text
       fprintf(lcd, "?y2%s", dataString); //display on serial LCD
       continue;
      }
  }

(char dataString[30]; is defined as a global variable)
and
Code:
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7, stream=rpi)

in the header file.

If I use Hyperterm on my PC or Minicom on my Raspberry Pi, it works fine.
However, I have written 2 programs, one in C++ on the PC and the other in Lazarus on the RPi and in both cases, when I send the string, all I get on the LCD is the ! and it just sits, I presume in fgets? If I send only a !, it displays it and the program continues down main. I am sending a return (13) as gets wants at the end of the text.

I am at a loss to understand why the code works with data from 2 different terminal programs but not otherwise. Can anyone help, please? I have spent all day on it and got nowhere! It must be something obvious, just not to me!! Any help most appreciated.

CCS PCWH 3.249
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Aug 29, 2013 5:04 pm     Reply with quote

Quote:
fprintf(lcd, "?y2%s", dataString);

While you're sending this to the LCD, you're not reading the UART.
If you send data to the UART without reading it, you will fill up the
hardware receive fifo (only 2-deep) and after that, the UART will be
locked up. It won't work anymore.

To automatically detect and clear this situation, add the parameter
shown in bold below. You should always do this.
Quote:
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7, ERRORS, stream=rpi)
Ttelmah



Joined: 11 Mar 2010
Posts: 19469

View user's profile Send private message

PostPosted: Thu Aug 29, 2013 11:22 pm     Reply with quote

and (of course), 'long term', if you want to receive data, use interrupt driven receive - ex_sisr.c, which will receive the data while the transmission is being done.

Best Wishes
BLL



Joined: 11 Nov 2006
Posts: 181
Location: Birmingham, UK

View user's profile Send private message

Serial woes
PostPosted: Fri Aug 30, 2013 2:14 am     Reply with quote

Hi, Thanks for that. I hadn't seen 'ERRORS' documented at all. However, what I don't follow is that surely fgets will continue to call fgetc until it has collected all the sent characters and placed them in the string. Only then am I sending that data to the LCD, so why should there be the clash? I will look at ex_sisr.c as well to see if that would be better. I am also still at a loss as to why Hyperterm and Minicom do the job flawlessly. What do they have that others don't??

Thanks for your help.
Ttelmah



Joined: 11 Mar 2010
Posts: 19469

View user's profile Send private message

PostPosted: Fri Aug 30, 2013 3:30 am     Reply with quote

The key point is that the PIC only has just under two characters of hardware buffering. _One_ held received character, and the one currently arriving. As soon as more than this is received, anything else that arrives is lost.

Now, while you are sending to the serial LCD, you are not calling fgets, hence anything beyond this 1.9x characters that arrives at this point is 'gone'. When the UART overflows, it goes into an 'errors' state, and stops receiving anything. The 'ERRORS' keyword, adds code, so that the compiler will recover from this (the data is still lost, but the UART won't be hung).

Now the difference between the 'terminal', and a 'program', is that the program will probably 'steam ahead' sending characters, while a person at the terminal only types at a limited speed, and stops to check what is happening...

Hence you need (ideally) to have a larger buffer at the PIC. This is what EX_SISR, shows you how to do. Implementing a bigger buffer (as is done on the PC), so that the PIC can be receiving characters _while_ also sending them to the LCD at the same time.

Best Wishes
BLL



Joined: 11 Nov 2006
Posts: 181
Location: Birmingham, UK

View user's profile Send private message

PostPosted: Fri Aug 30, 2013 8:49 am     Reply with quote

Hi, I had thought that gets called getc as many times as needed before continuing, rather than it going round the loop reading one char at a time. If that is what it's doing then I can quite see it overfilling the 2 byte buffer! I tried the ERROR addition to #use rs232 and you could quite easily then see what had been lost. I have now done similar to sisr and all is fine provided I keep the baud rate down to 9600, which is plenty as there is little data coming into the PIC and a data string every ten seconds going out.

Thank very much for your help - I have learnt some and my sanity is restored!!
Ttelmah



Joined: 11 Mar 2010
Posts: 19469

View user's profile Send private message

PostPosted: Fri Aug 30, 2013 8:55 am     Reply with quote

You are missing the point.

Yes, gets, gets what is needed. However as soon as this string completes, you go off and send it using another serial port to the LCD. As soon as you go off to do this, gets is no longer being called, and you are now dependant on the buffering. How long you are 'gone', depends on the serial speed to the LCD etc.. All the time this is sending, gets, is not being called....

Best Wishes
BLL



Joined: 11 Nov 2006
Posts: 181
Location: Birmingham, UK

View user's profile Send private message

PostPosted: Fri Aug 30, 2013 9:52 am     Reply with quote

OK, but since no string or characters follow what gets has got, it shouldn't matter. One data string is sent and that's it until the user next decides to alter the setup information, which would typically be some weeks or months later.
Anyway, with the interrupt routine it is working very well and has defied all my attempts to break it!
BLL



Joined: 11 Nov 2006
Posts: 181
Location: Birmingham, UK

View user's profile Send private message

More serial woes!!
PostPosted: Sun Sep 01, 2013 12:08 pm     Reply with quote

Having now sorted the hardware UART, I have now found a new problem, which defies solution! I have a second software uart using pins C0 and C1. It connects to a Cirrus CS5490 electricity chip. At power up, the CS5490 defaults to 600 baud for some reason! Cirrus recommend increasing this to a higher figure before doing anything else. To do this, it is necessary to send 5 bytes; the first is a page address, the second's top 2 bits tell the 5490 that a register write is required and the remaining 6 are the register address. Then 3 bytes of data need to follow, which are the contents of the 24 bit register. That should alter the baud rate. I follow that with a revised #'use rs232 command. After that there is an 8 bit instruction to tell it to get going. I have a function to do this and apart from any bytes arriving from the computer to the hw uart, nought else is happening. However, nothing happens at all ! I tried removing the 5490 and linking rcv and tx on the PIC and I can control and read the lines, but as soon as I try to use them as a uart, nothing. I have timer1 set to disabled as it can use one of the pins as an output. I have tried to loopback using the uart, but no joy. At this point, I have run out of ideas!

Any thoughts please?
Ttelmah



Joined: 11 Mar 2010
Posts: 19469

View user's profile Send private message

PostPosted: Sun Sep 01, 2013 12:35 pm     Reply with quote

Setup _two_ #use rs232 statements. One at each baud rate, with different stream names. Send the initial setup with the slow stream, then switch to the fast stream.
Switching baud rate on a software UART is best done this way.
Trying to use different #use rs232 statements in the code often will not work the way you expect.

Best Wishes
BLL



Joined: 11 Nov 2006
Posts: 181
Location: Birmingham, UK

View user's profile Send private message

more serial woes
PostPosted: Sun Sep 01, 2013 1:02 pm     Reply with quote

Thanks for that. Is it possible to get loopback to work with the s/w uart, so I can prove it is doing something? I have tried, but without success.

Also, if I moved the uart to say RB1 and RB2, could I then use the intext1 interrupt to allow me to have a buffer, like with the hw uart? This is all new to me!
Thanks for your advice.
temtronic



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

View user's profile Send private message

PostPosted: Sun Sep 01, 2013 1:19 pm     Reply with quote

If you only have 1 HW UART, I'd use it for the Cirrus chip and use a SW UART for the LCD interface.

hth
jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19469

View user's profile Send private message

PostPosted: Sun Sep 01, 2013 2:45 pm     Reply with quote

Buffering a software UART, is hard:

1) You can never receive while transmitting (with the code supplied).
2) If you use an interrupt based 'trigger' for receive, the code will stay in the interrupt for one character time. If this is longer than the service interval needed by any other interrupt (like hardware RS232), it'll cause loss of data on this.
3) Interrupts have to be disabled during transmit and receive (except at very slow baud rates), or the timing will fail.

Only use software RS232, for links that are 99.9% 'transmit only', or only ever reply to things when asked.

I have in the past posted the 'core' of a timer interrupt based buffered software RS232.

Best Wishes
BLL



Joined: 11 Nov 2006
Posts: 181
Location: Birmingham, UK

View user's profile Send private message

More serial woes!!
PostPosted: Sun Sep 01, 2013 3:40 pm     Reply with quote

Thanks for that. The CS5490 won't transmit anything unless I tell it to.

I have tried your suggestion about 2nd #use rs232 but absolutely nothing seems to be happening. After setting to 9600, I tell it to start running and to configure its digital output pin to pulse on electricity usage. It resolutely doesn't! I have treble checked the circuit for any errors and can't find any. It just seems that the software uart just isn't doing a thing. Its predecessor worked over SPI and was a doddle compared with this later chip! I now haven't a clue how to proceed! I don't really want to move ports unless I have to as it will mean butchering the circuit board. I suppose I could hang a MAX232 board on and see if the PC will talk to the PIC at all?
The joys(??) of electronics!!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Sep 01, 2013 5:04 pm     Reply with quote

1. Make a compilable test program that only sets up the CS5490 to 9600
baud and then tests that it's working. The test program should have the
#include for the PIC, #fuses, #use delay(), and #use rs232() statements,
as well as all necessary #define statements and variable declarations,
and it should have a main(). If you can make that program, test it,
post the results and post the program, then we can work on the problem.


2. Post a list of the connections between your PIC and the UART pins on the CS5490.

3. I assume the CS5490 is running at 3.3 volts. Tell us the Vdd voltage
of your PIC.

4. Did you buy the CS5490 board or did you build it yourself ?
If you bought it, post a link to the website for it.
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, 3, 4, 5  Next
Page 1 of 5

 
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