Asm sleep - pbp sleep


Closed Thread
Results 1 to 32 of 32

Hybrid View

  1. #1
    Join Date
    May 2013
    Location
    australia
    Posts
    2,664


    Did you find this post helpful? Yes | No

    Default Re: Asm sleep - pbp sleep

    a 2 sec reset looks very likely to be wdt



    after disabling wdt i would try something like this

    Code:
    SleepMode:
        PortA.1=0     ;Indicator LED out on entering SLEEP
    ASM
        BANKSEL BAUDCON  ;bank 3
        BTFSS   BAUDCON,RCIDL  ;Check for High, no receive in progress
        GOTO $-1                
        BSF BAUDCON,WUE        ;Wake on Rx from Master 
        BANKSEL 0  ;bank 0
        BSF  PORTC,1   ;LED 
        BCF INTCON ,7
        SLEEP
        nop
        BSF INTCON ,7
    ENDASM
        PortA.1=1                   ;Indicator LED ON  at exit SLEEP
        return
        end
    Warning I'm not a teacher

  2. #2
    Join Date
    Jan 2006
    Location
    Istanbul
    Posts
    1,185


    Did you find this post helpful? Yes | No

    Default Re: Asm sleep - pbp sleep

    Quote Originally Posted by richard View Post
    .....

    Code:
      SLEEP
        nop
        BSF INTCON ,7
    

    Wayne,
    Pay attention to Rihard's code there. The first ting after SLEEP must be NOP.
    You did not have NOP as the first thing atfer SLEEP in your code.

    and WDT is OFF in config; how can it be an issue?
    "If the Earth were a single state, Istanbul would be its capital." Napoleon Bonaparte

  3. #3
    Join Date
    Jan 2009
    Location
    Alabama,USA
    Posts
    232


    Did you find this post helpful? Yes | No

    Default Re: Asm sleep - pbp sleep

    Success at last, well kind of. New questions are raised as the problem is solved.
    Alain's code dimnstrates the purpose of the sleep state, low power, all ports off. This is not required but is good practice.

    I followed richards ASM modifications of my poor attempt (years since I wrote ASM. I was trying to brush up)

    WDT was always off in Configs so it was never WDT event. Will later read Config addresses to confirm I got what I wanted in memory.

    As I enter the ASM code blockk, no LED can be executed after the test for RCIDL and before SLEEP.
    Place BSF Portx.x before RCIDL test and SLEEP works.
    Place BSF Portx.x after RCIDL test and SLEEP dies not works.
    Place BSF Portx.x after BSF BAUDCON, WUE and SLEEP dies not works.
    Place BSF Portx.x after BSF INTCON.7 t and SLEEP dies not works.

    Before entering the ASM block i can turn on as many LED's as I like and Sleep works as it should.

    OK so this is a strange behavure that does not fit any RESET format I can find in the data sheet.

    Regarding the data sheet section memtioned by Ioannis.
    Wake up will occure regardless of state of GIE bit.
    PC SLEEP +1 is prefeched durring SLEEP.

    SLEEP with GIE set: NOP may be needed in this case!
    Test RCIDL
    Set WUE
    SLEEP
    Wake and exicute next instruction
    Call ISR
    return to Sleep +2
    continue program

    SLEEP with GIE clear: no NOP needed but it can't hurt!
    Test RCIDL
    Set WUE
    SLEEP
    Wake and exicute next instruction
    No ISR called
    continue program

    In my case I will WAKE on EUSART single byte %00000000. I need the ISR to read RCREG and clear RCIF, then discard Break character. Single NOP will be needed.

    So now the adventure of the WAKEUP routine. Thank you for alll your help.
    Wayne

  4. #4
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    4,159


    Did you find this post helpful? Yes | No

    Default Re: Asm sleep - pbp sleep

    Glad you did it! Similar cases we faced I guess too.

    But that makes me wonder, if we try so hard to solve such things on a PIC, what would happen on a more complex MCU? Would then take years to find what is wrong???

    Ioannis

  5. #5
    Join Date
    May 2013
    Location
    australia
    Posts
    2,664


    Did you find this post helpful? Yes | No

    Default Re: Asm sleep - pbp sleep

    As I enter the ASM code blockk, no LED can be executed after the test for RCIDL and before SLEEP.
    Place BSF Portx.x before RCIDL test and SLEEP works.
    Place BSF Portx.x after RCIDL test and SLEEP dies not works.
    Place BSF Portx.x after BSF BAUDCON, WUE and SLEEP dies not works.
    Place BSF Portx.x after BSF INTCON.7 t and SLEEP dies not works.

    Before entering the ASM block i can turn on as many LED's as I like and Sleep works as it should.

    OK so this is a strange behavure that does not fit any RESET format I can find in the data sheet.
    you are still not getting it right evidently.

    i can do pretty much anything in the asm block before or after sleep, you really should post your code for any meaningful discussion.




    Code:
    #CONFIG
      __config  _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_ON & _FCMEN_ON
      __config  _CONFIG2, _WRT_OFF & _VCAPEN_OFF & _PLLEN_OFF & _STVREN_ON & _BORV_19 & _LVP_OFF
    #ENDCONFIG
    
    include "dt_ints-14.bas"
    Include "REENTERPBP.bas"
    
    
    DEFINE DEBUG_REG PORTB
    DEFINE DEBUG_BIT 7
    DEFINE DEBUG_BAUD 9600
    DEFINE DEBUG_MODE 1
    
     asm      
    INT_LIST macro       
          INT_HANDLER RX_INT , getrx, asm ,yes 
          INT_HANDLER TMR1_INT , _FLASH, PBP,yes      
          endm
           INT_CREATE
    ENDASM 
    
    index_in         VAR  BYTE bank0         ' Pointer - next empty location in buffer
    index_out        VAR  BYTE bank0         ' Pointer - location of oldest character in buffer
    errflag          VAR  BYTE bank0         ' Error flag
    UartFlag         VAR  errflag.0
    BufferFlag       VAR  errflag.1
    buffer_size      CON  16                              ' Sets the size of the ring buffer  
    buffer           VAR  BYTE[buffer_size]     ' Array variable for holding received characters 
    BufChar          VAR  BYTE          ' Stores the character retrieved from the buffer
    Buffrdy          VAR  BYTE  bank0
    buff             var  byte[16]
    inx              var  byte
    led              var  portc.5
    led2             var  portc.4
    
    
    RCSTA     = $90   ' Enable serial port & continuous receive
    SP1BRGL   = 51    ;' 9600 Baud @ 8MHz, 0.16%
    SP1BRGH   = 0     ;
    BAUDCON.3 = 1 ' Enable 16 bit baudrate generator
    
     
    define OSC 8
    OSCCON=%01110000   ;8Mhz                                                 
    ANSELA=$0   
    ANSELB=$0    
    ADCON0=$0
    PortA=0
    PortB=0                                      
    PortC=0 
    TrisA=%00000001                                                                                
    TrisB=%00001001        
    TrisC=%10001111
    Avar    var byte
    Bvar    var byte
    Cvar    var byte 
    '    rx portc.7
    PAUSE 1000                           
    Debug "Start",13 ,13
     
    index_in = 0                    ' Initialize ringbuffer variables
    index_out = 0  
    GOSUB error  ;CLR AND RESET EUART
    
     T1CON=$31
    @   INT_ENABLE  RX_INT     ; Enable USART RX Interrupts  
    @   INT_ENABLE  TMR1_INT 
      
    loopy:              
        IF errflag Then GOSUB error ' Goto error routine if needed
        if Buffrdy then
            pie1.4=0
            inx=0
            while index_in != index_out 
                GoSub getbuf         ' Get a character from buffer   
                debug bufchar        ' Send the character to terminal
                buff[inx]= bufchar
                inx=inx+1
            wend
            Buffrdy=0
            pie1.4=1
            ARRAYREAD buff, 15, loopy,[wait ("sleep")]  
            gosub SleepMode
        endif
    GoTo loopy 
      
    FLASH:
     LED2=!LED2
    @  INT_RETURN
    
    
    
    
    
    SleepMode:
    ASM
        bcf INTCON   ,7
        BANKSEL BAUDCON     
        BTFSS   BAUDCON,RCIDL  ;Check for High, no receive in progress - tried with and without
        GOTO $-1                         ;return to previous line
        BSF BAUDCON,WUE           ;Set to Wake on Rx from Master 
        BANKSEL 0
        BSF PORTC, 5               ;sleep led on
        SLEEP 
        nop
        BCF PORTC, 5             ;sleep led off
        bsf INTCON ,7     
        BANKSEL 0  
        return         
    ENDASM
    
     
    
     ' Get a character from the buffer
    getbuf:                                 ' Move the next character in buffer to bufchar
       intcon = 0                          ' Disable interrupts while reading buffer
       index_out = index_out + 1     ' Increment index_out pointer 
       IF index_out => buffer_size Then index_out = 0 ' Reset pointer if outside buffer
       bufchar = buffer[index_out]  ' Read buffer location(index_out)
       INTCON = %11000000           ' Enable interrupts
       Return
    
    ' Display an error
    error:                          ' Display error message
       INTCON = 0                   ' Disable interrupts while in the error routine
       IF errflag.1 Then            ' Determine the error
          debug "over run",13,13 '
       Else
          debug "rx err",13,13  
       EndIF
       PIR1.4=0      
       errflag = 0          ' Reset the error flag
       RCSTA.4=0           'CREN = 0 Disable continuous receive to clear hardware error
       RCSTA.4=1           'CREN = 1 Enable continuous receive
       INTCON = %11000000   ' Enable interrupts
      RETURN         ' repeat
    
     
    
    
    Asm
    getrx
    ; Check for hardware overrun error
       banksel RCSTA
       btfsc   RCSTA,OERR   ; Check for usart overrun
       goto   usart_err    ; jump to assembly error routine
    ; Test for buffer overrun  
       BANKSEL 0 
       incf   _index_in,W   ; Increment index_in to W
       subwf  _index_out,W  ; Subtract indexes to test for buffer overrun
       btfsc  STATUS,Z      ; check for zero (index_in = index_out)
       goto   buffer_err    ; jump to error routine if zero
    ; Increment the index_in pointer and reset it if it's outside the ring buffer
       incf   _index_in,F   ; Increment index_in to index_in
       movf   _index_in,W   ; Move new index_in to W
       sublw  _buffer_size-1; Subtract index_in from buffer_size-1
       btfss  STATUS, C     ; If index_in => buffer_size
       clrf   _index_in     ; Clear index_in
    ; Set FSR with the location of the next empty location in buffer
       movlw   High _buffer  ;Store the High byte of buffer to FSR0H
       movwf   FSR0H
       movlw   Low _buffer  ; Get the Low byte of buffer[0]
       addwf   _index_in,W  ; Add index_in to point to next empty slot
       movwf   FSR0L        ; Store Low byte of pointer in FSR0
    ; Read and store the character from the USART 
       BANKSEL RCREG
       movf   RCREG,W       ; Read the received character
       movwf  INDF0          ; Put the received character in FSR0 location
       BANKSEL 0
       SUBLW 13
       BTFSC STATUS,Z
       BSF   _Buffrdy ,0
       BTFSC  PIR1,TXIF      ;ANY MORE ?
       goto   getrx
       
    finished 
       BANKSEL 0
       INT_RETURN
     
    ; Error routines        
    buffer_err              ; Jump here on buffer error
       bsf   _errflag,1     ; Set the buffer flag
    usart_err               ; Jump here on USART error
       bsf   _errflag,0     ; Set the USART flag
       BANKSEL RCREG
       movf  RCREG, W       ; Trash the received character
       goto  finished       ; Restore state and return to program
    EndAsm
    Warning I'm not a teacher

  6. #6
    Join Date
    Aug 2011
    Posts
    457


    Did you find this post helpful? Yes | No

    Default Re: Asm sleep - pbp sleep

    Wake up will occure regardless of state of GIE bit
    That part is true. All GIE determines is if you'll wake up and go to the ISR vs just continuing on where you left off.

    What wakes you up is the RCIF that occurs when the 00 "break byte" comes in. If RCIE isn't set, then RCIF won't wake you up.

  7. #7
    Join Date
    Jan 2009
    Location
    Alabama,USA
    Posts
    232


    Did you find this post helpful? Yes | No

    Default Re: Asm sleep - pbp sleep

    So things now work but I still didn’t understand why some things were acting as they were. As Richard said “You are still not getting it right evidently”. I could finish the project at this point however I was still interested in Configurations which seem to be acting very strange for the Configs I had called for. Richard had used very similar configs to the ones I was using so I started to review the differences. There were no significant differences.

    I checked to make sure I had all item in the right Config, 1 or 2. All was fine.
    I checked my programmer, melbas Programmer 4.50 list of Config settings and they were different than listed in my program. OOPS! Looking back at the programmer under Options I had checked “Erase before Programming”, Verify after Programming”, and “Update Configurations from file”. So this should take care of everything needed in the Configurations, right?…………WRONG!!!

    The second time I looked back at the programmer Options I notice at the bottom of the menu, “More Options”. In most cases this would contain non-essential items that may or may not mater. At the bottom of that menu was “Program” and in that menu the word “Configurations”. Wait a minute; The MAIN menu already set “Update Configurations from File”. Out of curiosity I then checked “Configurations" under the submenus More Options- Program-” and reprogrammed the 1936. To my shock and surprise, all the weird things were gone. LED could be placed inside the ASM block, my PORTA.7 was now a digital I/O. Everything was working correctly. After a couple of weeks of trying to solve bizarre software behavior I find the problem was hardware not software and I would never have gone looking for this if so many of you had not said things like “ not getting it right evidently”. I may have written many programs without being effected by this problem. At this point I can’t be sure that any of my config directive were being programmed into my micros and Configs my have always been defalt. I fell pretty bad that many of you have given of your time. I also have some regret that the programmer menus were written in this manor on some important points. Lesson Learned, don’t take anything for granted! I will however say it was a great exercise in detail study of ASM SLEEP. Thank you again for all your assistance!
    Wayne

Similar Threads

  1. Can't @sleep
    By MOUNTAIN747 in forum General
    Replies: 3
    Last Post: - 30th December 2010, 17:29
  2. Trying to add a sleep function or pretend to sleep
    By lilimike in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 9th May 2010, 19:10
  3. Help with PBP 'SLEEP' command
    By dreadmaul in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 18th November 2006, 07:40
  4. How to go to sleep
    By savnik in forum mel PIC BASIC Pro
    Replies: 9
    Last Post: - 22nd September 2006, 18:38
  5. Sleep Mode in PBP
    By Keith in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 4th March 2005, 20:58

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts