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

Another INT_RDA problem. PIC wakes up just once...

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



Joined: 16 May 2006
Posts: 65
Location: Ankara/Turkey

View user's profile Send private message Send e-mail

Another INT_RDA problem. PIC wakes up just once...
PostPosted: Wed Feb 28, 2007 3:29 am     Reply with quote

Hi everyone,

I really don't know how many INT_RDA topic I've read, but couldn't find a proper answer for my problem. Situation is like this:

My Aim:
Trying to get 16 character block which will be send via a PC or a service equipment. These components will be programmed also by us therefore we do not have any restrictions over the communication. PC will send 16 characters and it will include some commands and info.

Problem is:
I can use INT_RDA with ascyncronous transfer, and PIC can wake up from sleep. I usually miss the first character because of the program construction I think. Anyway, as you can see in the code below I get the INT_RDA signal and just activate a process in while(1) loop. With using timed_getc I can check time outs etc. Everything is fine except getting the first character. It's also OK , I'm using a start character and PC can send 1 additional character to make it work right.

But the main problem is I can not make the PIC wake up "again". Maybe RX Buffer, maybe clear_interrupt does not work I don't know.

So, how can I solve this problem. Any suggestions any ideas are welcome. I appreciate your help.

Additional Info:
PIC: 18F4620
CCS version: 3.212
RS232 test program: DockLight 1.6

PS: Could be an errata like in the situations of MSSP module?


Code:


#use RS232 (BAUD=9600, STREAM=CPORT, XMIT=PIN_C6, RCV=PIN_C7, PARITY=N, BITS=8, ERRORS)

#INT_RDA
void rs232_isr()
{
   disable_interrupts(INT_RDA);   /// Without this line, interrupt is called infinitely and never switches to main branch
   SignalEvent(EVENT_CPORT_CONNECTION);
}

/// in main.c

   setup_adc(ADC_CLOCK_INTERNAL);
   setup_adc_ports(AN0_TO_AN1 | VSS_VREF);
   set_adc_channel(1);
   setup_spi(FALSE);
   setup_psp(PSP_DISABLED);
   setup_timer_0(RTCC_OFF);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_ccp1(CCP_OFF);
   setup_ccp2(CCP_OFF);
   ext_int_edge(0, H_TO_L);               
   ext_int_edge(1, H_TO_L);               // Set up PIC18 EXT2
   ext_int_edge(2, H_TO_L);                // Set up PIC18 EXT2
   setup_wdt(WDT_OFF);


/// in While Loop

if(CheckEvent(EVENT_CPORT_CONNECTION))
{
   ProcessCPortConnection();

   clear_interrupt(INT_RDA);
   enable_interrupts(INT_RDA);
   ClearEvent(EVENT_CPORT_CONNECTION);
   DebugMessage("\n\nCport Event Processed");
}



/// Secondary Functions

/// RS232 interrupt process function
void ProcessCPortConnection()
{
   if(CPWaitValidStart())
   {
      Display("READY");
      
      if(CPReceiveBlock())      ProcessServiceCommand();            
              else                                          {   
         Display("FAILED");
         SmartDelay(1000);      /// Just a NOP loop for not disabling the interrupts
         ErrorCode = 0;         /// Communication Error
      }
      
   }
   else   
   {
      Display("TIME OUT");
      SmartDelay(1000);
   }
}


/// Receive 1 Block (Page) Data from RS232 port.
short CPReceiveBlock()
{
   unsigned int cpc;
   
   for(cpc=0;cpc<16;cpc++)                     /// Receive Data
   {
      TempBuffer[cpc] = timed_getc();
   }
   
   if(cport_timeout)    return 0;
   
   
///   CryptoDecryptBlock(TempBuffer);               /// Decrypt block
   
/*   if(generate_8bit_crc(TempBuffer, 15, CRC_CCITT) != TempBuffer[15])   return 0;      /// Compare Actual CRC with received CRC, if fails return unsuccessful
   else                                                            /// if CRC is OK, send transfer verified character to other side
   {
*/      putc(0xDD);
      return 1;
///   }
}



char timed_getc()
{
   long timeout;
   
   cport_timeout=FALSE;
   timeout=0;
   
   while(!kbhit()&&(++timeout<60000)) 
      delay_us(10);

   if(kbhit())
      return(getc());
   else {
      cport_timeout=TRUE;
      return(0);
   }
}


short CPWaitValidStart()
{
   char karakter;

   Display("WAITING");            
   
   karakter = timed_getc();         /// Try to get the character in about 1 second
   
   if(!cport_timeout)               /// Check the timeout condition
   {
      if(karakter ==   0xDD)   return 1;   /// if received within 1 seconds check for valid character
      else                     
      {                           /// if its not valid try to get it again.
         karakter = timed_getc();
         if(!cport_timeout)
         {
            if(karakter ==   0xDD)   return 1;
         }
         
      }
         
   }

   cport_timeout = FALSE;            /// reset the timeout variable for further operations (remember it's global)
      
   return 0;                     /// If both attempts fail then return as failed
}


_________________
/// KMT
/// www.muratursavas.com


Last edited by KaraMuraT on Thu Mar 08, 2007 9:13 am; edited 2 times in total
KaraMuraT



Joined: 16 May 2006
Posts: 65
Location: Ankara/Turkey

View user's profile Send private message Send e-mail

PostPosted: Wed Feb 28, 2007 5:15 am     Reply with quote

I found this section in the Errata document of the 4620 revision A4 (test PIC is revision A4)

Quote:
36. Module: EUSART
With the auto-wake-up option enabled by setting
the WUE (BAUDCON<1>) bit, the RCIF
(PIR1<5>) bit will become set on a high-to-low
transition on the RX pin. However, the WUE bit
CY of a low-to-high transi-
may not clear within 1 T
tion on RX. While the WUE bit is set, reading the
receive buffer, RCREG, will not clear the RCIF
interrupt flag. Therefore, the first opportunity to
automatically clear RCIF by reading RCREG may
take longer than expected.
Note: RCIF can only be cleared by reading
RCREG
Work around
There are two workarounds available:
1. Clear the WUE bit in software after the wake-
up event has occurred prior to reading the
receive buffer, RCREG.
2. Poll the WUE bit and read RCREG after the
WUE bit is automatically cleared.
Date Codes that pertain to this issue:
All engineering and production devices.


Do you think that errata can cause this?
_________________
/// KMT
/// www.muratursavas.com
Ttelmah
Guest







PostPosted: Wed Feb 28, 2007 9:04 am     Reply with quote

Get rid of the disable interrupt in INT_RDA, and _read the received character_. INT_RDA, is called whenever there is a character waiting. If you don't read the character, it'll keep being called. If you don't want the character, just do a dummy 'getc'. If you don't read the character, the interrupt flag is still set, which with the interrupt disabled, means this interrupt event can no longer wake you up.
Missing the first character, is down to what oscillator you are running. The internal crystal oscillator takes time to start. The problem then is that the UART 'sees' the falling edge of the first character, but can't clock the data in properly, because it doesn't have a working clock. The answer to this, is to leave the master oscillator running. You can change the sleep 'level' used by the processor, to allow this. Do a search here, where how to do this has been posted before.

Best Wishes
KaraMuraT



Joined: 16 May 2006
Posts: 65
Location: Ankara/Turkey

View user's profile Send private message Send e-mail

PostPosted: Wed Feb 28, 2007 9:55 am     Reply with quote

Thank you Ttelmah.. I'll try it tomorrow and let you know.

This level sleep mode is a requirement due to power consumption and I think sending a dummy character is a better solution.
_________________
/// KMT
/// www.muratursavas.com
KaraMuraT



Joined: 16 May 2006
Posts: 65
Location: Ankara/Turkey

View user's profile Send private message Send e-mail

PostPosted: Thu Mar 01, 2007 1:05 am     Reply with quote

Thank you again Ttelmah. This solution helped... It's wroking now as intented .
_________________
/// KMT
/// www.muratursavas.com
KaraMuraT



Joined: 16 May 2006
Posts: 65
Location: Ankara/Turkey

View user's profile Send private message Send e-mail

PostPosted: Thu Mar 08, 2007 9:12 am     Reply with quote

I had just checked exiting from the RDA isr, but I saw that the main problem still exists...

I'm just trying this:


Code:

#INT_RDA
void rs232_isr()
{
CPCommand = getc();
SignalEvent(EVENT_CPORT_CONNECTION);
}


/// in while(1) loop

if(CheckEvent(EVENT_CPORT_CONNECTION))
{
fprintf(CPORT,"\nCPCommand = %2X", CPCommand);

DebugMessage("\nReady To Receive ");    /// Simple fprintf definiton

debug_code = getc();

fprintf(CPORT,"\nReceived Character = %Lx", debug_code);

}



I firstly tried to use timed_getc() function but it does not work. then to simplfy everything switched to getc() to make it wait for a char.

My process is like this. I'm sending a dummy character to wake up the system. ie sending 0x01 and system wakes up and gets it as "0xC0". Doesn't matter its dummy.

OK, event signal tirggered and entered to "if" branch. I'm making everthing manually to keep away from "fast process" errors. Systems sends me the ready string.

Then I send again a character. Sould be got by the "getc()" but no it does not. I have to try 6-15 times to make it work. Then the process ends and system goes to sleep again. And of course never wakes up again by the RDA isr.

So, is this a common problem or am I stuck again in a hardware errata?
_________________
/// KMT
/// www.muratursavas.com
KaraMuraT



Joined: 16 May 2006
Posts: 65
Location: Ankara/Turkey

View user's profile Send private message Send e-mail

PostPosted: Fri Mar 09, 2007 2:41 am     Reply with quote

I've run some additional tests. Let me explain it on the blackboard Cool

Code sections are all RS232 Communication.

Code:

PIC type: PIC18F4620
Revision: 0x04

Gone to sleep


starts, reports PIC: 18F4620, revision A4 and goes to sleep.

Code:

09.03.2007 09:38:20 [TX] - X
09.03.2007 09:38:20 [RX] -

EVENT: Cport


I'm sending 'X' character (0x58) as dummy char to wake up the system. This triggers the CPort event in the while (1) loop.

Code:

CPCommand = 0xFD


Anlyzing the first char, it has been received false as expected (should be 0x58 but received 0xFD)

Code:

Clearing RX Buffer
Clear kbhit() count:    0


Now trying to find out whether a character is waiting or not. This may cause INT_RDA not waking up.

function is this: (didn't use "code" style to not confuse)

void CPClearReceiveBuffer()
{
unsigned int16 duration = 0;
DebugMessage("\Clearing RX Buffer");

while(kbhit() && duration < 50000)
{
getc();
delay_us(10);
duration++;
}

clear_interrupt(INT_RDA);

fprintf(CPORT, "\nClear kbhit() count: %4Lu", duration);

}

Code:

CPort Event Processed
CPort Event signal cleared
Gone to sleep


Reports CPort event is processed the signal bit cleared and main loop gone to sleep.

Code:

09.03.2007 09:38:22 [TX] - X
09.03.2007 09:38:22 [TX] - X
09.03.2007 09:38:22 [TX] - X
.
.
.
.
.
09.03.2007 09:38:24 [TX] - X
09.03.2007 09:38:25 [TX] - X
09.03.2007 09:38:25 [TX] - X


I'm trying to wake up system countless times. But not waking up. Then try to wake up system with an another interrupt. Here it's func event.

Code:

09.03.2007 09:38:28 [RX] -

EVENT: Cport
CPCommand = FD
ProcessCPortConnectionClearing RX Buffer
Clear kbhit() count:    0
CPort Event Processed
CPort Event signal cleared


Because Cport is checked first, you can see if system wakes up, RDA isr had set the event bit. But couldn't wake up the PIC.

Code:

EVENT: Function Button Press
Gone to sleep


Other interrupt signal can be seen here, and system goes to sleep again...

So I'm open for any ideas...
_________________
/// KMT
/// www.muratursavas.com
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