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

Wake Up time high when timer1 enabled in sleep
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
gabirelms



Joined: 28 Jun 2014
Posts: 38

View user's profile Send private message

Wake Up time high when timer1 enabled in sleep
PostPosted: Fri Jul 04, 2014 5:10 am     Reply with quote

Hi all,

PIC16LF1459 wake up time from sleep mode is high.

During sleep mode timer1 is clocked from external 32.768KHz crystal.

PORTB change on interrupt is used for wake up MCU.

For working timer1, timer1 interrupt enabled.

If I disable timer1, then the device wake up very fast.

I think all interrupt has the same priority and there is a big interrupt latency.

What can I do ?

Any help would be appreciated

Thanks
temtronic



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

View user's profile Send private message

PostPosted: Fri Jul 04, 2014 5:34 am     Reply with quote

Here are some options to consider

1)depending on compiler and PIC versions, you may be able to set the 'priority' of the interrupts

2) you might be able to 'trim' the INT handler( there's an 'option')

3) cut your own INT handler, as the CCS one saves a lot or registers which takes time( see #2)).You can make a very 'tight' (aka FAST ) handler.

4) read the CCS manual section on ISRs...more details there.

...others may chime in with more details...


hth
jay
gabirelms



Joined: 28 Jun 2014
Posts: 38

View user's profile Send private message

PostPosted: Fri Jul 04, 2014 6:17 am     Reply with quote

The problem is that PIC16LF1459 cannot set the 'priority' of the interrupts.
temtronic



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

View user's profile Send private message

PostPosted: Fri Jul 04, 2014 6:38 am     Reply with quote

from my memory....

It's not the PIC rather the compiler that sets 'priority',The PIC hardware just sets bits to say 'there is an interrupt', it's up to software to decide how to handle them.

option #3 is then probably the best choice.

You can dump the listing, see how CCS does the handler and create your own. How you do it( which registers to save, order of ISRs, etc.) is up to you as you know what you need in the code.

hth
jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19466

View user's profile Send private message

PostPosted: Fri Jul 04, 2014 7:25 am     Reply with quote

What clocks the chip when it is awake?.

Have a look at this thread:

<http://www.ccsinfo.com/forum/viewtopic.php?t=52568>

See how I wake the system, but don't use an interrupt 'handler' as such.

Thing is that if the chip is running off a crystal when awake, it takes a long time to wake the clock. While waking, it'll clock off the slow clock. It takes typically 30 instructions to get into an interrupt handler. If the chip is clocking at 32KHz, it takes over 122uSec/instruction, so depending on how quickly the fast clock wakes and stabilises, this could easily be 3+mSec.

If you are testing the response by looking at how quickly the code immediately after the sleep is executed, then with a handler enabled, it'll call this before going to this code, result _long_ delay.....

If you have things that need to be done immediately, then the other approach, is to disable the global interrupt before you sleep, execute the 'immediate' code, and then enable the global interrupt. The handlers will then be called (and by now the clock may well be awake).

Best Wishes
gabirelms



Joined: 28 Jun 2014
Posts: 38

View user's profile Send private message

PostPosted: Fri Jul 04, 2014 7:58 am     Reply with quote

timer1 always from external 32khz, during sleep and during awake.

HFINTOSC is set at 8Mhz when awake.
Ttelmah



Joined: 11 Mar 2010
Posts: 19466

View user's profile Send private message

PostPosted: Fri Jul 04, 2014 11:40 am     Reply with quote

The HFINTOSC should wake quickly.

It sounds simply as if your timer interrupt handler is rather slow.

Do what I suggested, and leave the global interrupt disabled when you sleep (this doesn't stop interrupts from waking the chip), do what is required to be serviced quickly, and _then_ turn on the global bit. The timer will then be serviced.
gabirelms



Joined: 28 Jun 2014
Posts: 38

View user's profile Send private message

PostPosted: Mon Jul 07, 2014 5:43 am     Reply with quote

Hi Ttelmah,

I did as you said, but timer1 stopped working inside sleep mode when disabled global interrupt. Any idea ?
Ttelmah



Joined: 11 Mar 2010
Posts: 19466

View user's profile Send private message

PostPosted: Mon Jul 07, 2014 5:49 am     Reply with quote

GLOBAL does not need to be on to wake the chip.

However if you want the timer routine to update, the timer routine needs to be called sometime.

Sounds as if it is not reaching the point where GLOBAL is turned back on.
The layout needs to be like I showed in the thread I referred to earlier.
gabirelms



Joined: 28 Jun 2014
Posts: 38

View user's profile Send private message

PostPosted: Mon Jul 07, 2014 5:52 am     Reply with quote

Quote:
The timer will then be serviced.

I don't understand this. Now timer1 stops during sleep.

Quote:
However if you want the timer routine to update, the timer routine needs to be called sometime.

It is in sleep mode, not called any routine that time
temtronic



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

View user's profile Send private message

PostPosted: Mon Jul 07, 2014 6:11 am     Reply with quote

You really need to post your code! A small, compilable version of 'what doesn't work'. Also say compiler version and what type of hardware (pcb, breadboard, commercial kit, etc.).
We can guess all day long and NOT find the REAL problem, let alone a workable solution.
The more details you supply, especially the program, the faster we can help.

hth
jay
gabirelms



Joined: 28 Jun 2014
Posts: 38

View user's profile Send private message

PostPosted: Mon Jul 07, 2014 11:04 am     Reply with quote

CCS compiler 5.015

timer1 is working from external crystal,32.768k, 2 seconds the interrupt works.

Please see the Sleep area code.

This is what I made first:

Code:
if(time_sleep>=2)
{

INTCONRABIE=1;
INTCONRABIF=0;

disable_interrupt(GLOBAL);
   enable_interrupt(INT_TIMER1);
   enable_interrupt(INT_RB7);
flag_wake_up_button=0;
above345:
SLEEP();          // if wake by timer1 interrupt goes to sleep again
if(flag_wake_up_button==0)
{
goto above345;
}

}


The issue is Timer1 not worked after I call the sleep mode, so once it triggered from the button, then the device always in sleep. The time_sleep is counter which works inside the timer ISR code.


Now I tried this code:

Code:
if(time_sleep>=2)
{

INTCONRABIE=1;
INTCONRABIF=0;

disable_interrupt(GLOBAL);
   enable_interrupt(INT_TIMER1);
   enable_interrupt(INT_RB7);
do
   {
       sleep();
       delay_cycles(1); //the instruction after a sleep should always be
       //a 'NOP'. This instruction is 'prefetched' when you sleep, and can
       //give unexpected results.
       if (INTERRUPT_ACTIVE(INT_RB))
       {
       
       RB_ISR();
       break;
           //Handle your RB7 changed interrupt here
           // - remember must read the port and should clear the changed
           //latch as well as clearing the interrupt.

       }
       if (interrupt_active(INT_TIMER1))
       {
          //timer1_interrupt(); //call the handler for the timer
          TIMER1_isr();
           clear_interrupt(INT_TIMER1);
           //and go back to sleep ASAP
       }
    } while (TRUE); //unless you want to exit the loop
enable_interrupts(GLOBAL);

}

Now timer1 is not working inside sleep mode, when wake up the timer1 is working...
temtronic



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

View user's profile Send private message

PostPosted: Mon Jul 07, 2014 12:24 pm     Reply with quote

You MUST post a COMPLETE program, not just random segments of code that doesn't work.

There are several potential issues and some "C coding problems" with the 'code' your show but no one here can possible decode why it doesn't work.

Normally posters with problems supply the complete program so we can 'cut/paste/compile/run/debug'. We can't do that with what you've supplied.

Enabling an ISR without a handler is disastrous !

hth
jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19466

View user's profile Send private message

PostPosted: Mon Jul 07, 2014 1:11 pm     Reply with quote

The glaring thing is you cannot/must not call an ISR from inside the main code. This will result in the interrupt being disabled in this code....

Duplicate the code if you want to call it in the main.

Other thing is that calling the RB_ISR routine from the main, does not clear this interrupt. So once this triggers the code will not exit, since it'll keep calling the RB code, and looping back.
gabirelms



Joined: 28 Jun 2014
Posts: 38

View user's profile Send private message

PostPosted: Mon Jul 14, 2014 5:50 am     Reply with quote

Hi, I've been working on it since last week, and I don't find a solution yet.

This code is working, the only issue is the delay for detecting the interrupt when the timer1 is working. If timer1 is disabled seems good.

When I press button without timer, led ON inmediately.
But when I press button with timer, led ON with 1 second delay.

Any suggestions ?

Code:

#define USB_HW_CCS_16F1459
#include <16LF1459.h>
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
 #fuses MCLR
   #fuses PUT
   #fuses NOWDT
#use delay(int=8MHz)
#include <usb_cdc.h> // USB library

//#use rs232(baud=9600,parity=N,xmit=PIN_A4,rcv=PIN_A1,bits=8,stream=PORT2,errors)

//#use rs232(baud=9600,parity=N,xmit=PIN_C0,rcv=PIN_C1,bits=8,stream=PORT2,errors)

#byte ANSELC=0x18E
#bit ANSELC0=ANSELC.0
#bit ANSELC1=ANSELC.1

   #define HW_ADC_PORTS    sAN11

#define HW_INIT() setup_adc_ports(HW_ADC_PORTS); setup_comparator(NC_NC_NC_NC)




#include <stdlib.h>
#define CS PIN_C2
#define LED1 PIN_C5


#word SSPCON1=0x215
#bit SSPEN=SSPCON1.5


#word OSCCON=0x99
#bit SPLLEN=OSCCON.7

#word IOCAF=0x393
#bit IOCAFA0=IOCAF.0
#bit IOCAFA1=IOCAF.1

#word IOCAN=0x392
#word IOCAP=0x391
#word UCFG=0xE91
#word UCON=0xE8E
#word IOCBP=0x394
#word IOCBN=0x395
#word INTCON=0x8B
#word PORTA=0x0C
#word PORTB= 0x0D
#word PORTC =0x0C
#bit INTCONGIE=INTCON.7
#bit INTCONRABIE=INTCON.3
#bit INTCONRABIF=INTCON.0
#bit USBEN=UCON.3

#bit IOCAN0=IOCAN.0
#bit IOCAN1=IOCAN.1
#bit IOCAP0=IOCAP.0
#bit IOCAP1=IOCAP.1

#bit IOCB7=IOCBN.7
#bit IOCBP7=IOCBP.7

#word UCFG=0xE91

#bit UPUEN=UCFG.4


// SPI memory operations

#word TRISC=0x8E
#word TRISB=0x8D


#bit TRISB6=TRISB.6
#bit TRISB4=TRISB.4
#bit TRISC7=TRISC.7
#define SDO_TRIS TRISC7
#define SDI_TRIS TRISB4
#define SCK_TRIS TRISB6

#word PORTB=0x0D
#word PORTC=0x0E

#bit PORTC7=PORTC.7
#bit PORTB6=PORTB.6
#bit PORTB4=PORTB.4

#define SPI_DO PORTC7
#define SPI_DI PORTB4
#define SPI_SCK PORTB6

#WORD ANSELA =0x18C

#bit timer1_osc_en = 0x18.3
#bit timer1_on = 0x18.0

#WORD T1CON=0x18
#WORD TMR1H =0x17
#WORD TMR1L=0x16
#WORD PIR1=0x11
#WORD PIE1=0x91

#bit TMR1CS1 =T1CON.7
#bit TMR1CS0 =T1CON.6
#bit T1CKPS1 =T1CON.5
#bit T1CKPS0 =T1CON.4
#bit T1OSCEN =T1CON.3
#bit T1SYNC =T1CON.2
#bit TMR1ON =T1CON.0

#bit TMR1IF=PIR1.0
#bit TMR1IE=PIE1.0


#bit ANSELA4=ANSELA.4


//timer1 works on every 2 seconds
#int_TIMER1
void  TIMER1_isr(void)
{
second=second+2;
if(input(BUTTON_PIN)==1)
{
time_sleep++;
time_sleep++;
if(second>=60)
{
second=second-60;
minute++;
if(minute>59)
{
minute=0;
hour++;
if(hour>23)
{
hour=0;
day++;
}
}

}


}

//set_timer1(32768);
}

#int_rb
void RB_ISR(void)
{


kll=PORTB;
INTCONRABIE=0;
flag_button_press=1;


}



void main() {


output_bit(LED1,1);
delay_ms(10);
output_bit(LED1,0);
set_tris_a(0x07);
SDO_TRIS=0;
SDI_TRIS=0;
SCK_TRIS=0;
output_bit(CS,0);
setup_spi(SPI_MASTER|SPI_MODE_0_0|SPI_CLK_DIV_16); //SPI_CLK_DIV_64
SPIFlashInit();
init_main();
ANSELC0=0;
ANSELC1=0;
output_bit(LED1,0);
setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1);       //2.0 s overflow
//   set_timer1(32768);
timer1_osc_en = 1;
timer1_on = 1;
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
TMR1CS1=1;
TMR1CS0=0;
T1CKPS1=0;
T1CKPS0=0;
T1OSCEN=1;  //1
T1SYNC=1;
TMR1ON=1;

output_bit(LED1,0);
setup_adc( ADC_OFF );
// for power reducing
SDO_TRIS=0;
SCK_TRIS=0;
SPI_DO = 0;
SPI_SCK = 0;
output_bit(PIN_B4,0);
output_bit(PIN_B6,0);
output_c(0x00);
//sleep();
output_bit(CS,1);
while(1)
{



while(input(BUTTON)==1)
{


 
  if(time_sleep>=2) //30
  {
 
  USBEN=0; // disable USB
output_bit(LED1,0);
//setup_oscillator(OSC_2MHZ|OSC_INTRC);
 flag_osc_switch=1;
SDO_TRIS=0;
SCK_TRIS=0;
SPI_DO = 0;
SPI_SCK = 0;
output_bit(PIN_B4,0);
output_bit(PIN_B6,0);
output_c(0x00);
output_bit(CS,1);
IOCBN=0x00;
IOCB7=1;
IOCBP7=1;
INTCONRABIE=1;
INTCONRABIF=0;
flag_button_press=0;
//TMR1ON=0;
//disable_interrupts(GLOBAL);
//enable_interrupts(INT_TIMER1);
above345:
SLEEP();
if(flag_button_press==0)   // if wake up from timer1 goes back to sleep again
{
goto above345;
}


 time_sleep=0;
count_ms=0;
 IOCBN=0x00;
IOCB7=0;
IOCBP7=0;
INTCONRABIE=0;
INTCONRABIF=0;

  }
}



if(input(BUTTON)==0)
{
output_bit(LED1,1);
// add time here
arr_value[0]=day;
arr_value[1]=hour;
arr_value[2]=minute;
arr_value[3]=second;

log_time_fn ();
output_bit(LED1,0);

  time_sleep=10;
}
}




}
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