Announcement

Collapse
No announcement yet.

Assembler Interrupt on PIC182550

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Assembler Interrupt on PIC182550

    Hi,

    I have asm interrupt running based on the SERBUFAX.pbp code sample, but I think its more luck than anything else.

    I have a few question:

    1. The 18F2550 have FSR0L and FSR0H. I have changes the FSR to FSR0L, but what must be done with the FSR0H?

    2. Can FSR1 and FSR2 be used as well?

    3. What about the saving of STATUS and PCLATH. Must it be 'commented out' on 8K devices? According to the PBP manual page 187 PIC 18Xxxxx devices must also be saved.

    4. How do I select the correct bank? There are something like 16 banks and no IRP resgister. I have commented it out in my code but don't know if I will encounter problems later.

    Code:
    ; Find in which bank the compiler put buffer, and set IRP               
       IF (_buffer > 0FFh)  ; Find the bank where buffer is located
          bsf   STATUS,IRP  ; If bank 2 or 3 set IRP
       Else
          bcf   STATUS,IRP  ; If bank 0 or 1 clear IRP
       EndIF

    Code:
    ' Assembly language INTERRUPT handler
    Asm
    myint
    ; Uncomment the following if the device has less than 2k of code space
       ;movwf  wsave         ; Save W
       ;swapf  STATUS,W      ; Swap STATUS to W (swap avoids changing STATUS)
       ;clrf   STATUS        ; Clear STATUS
       ;movwf  ssave         ; Save swapped STATUS
       ;movf   PCLATH,W      ; Move PCLATH to W
       ;movwf  psave         ; Save PCLATH
    
    ; Save the FSR value for later  
       movf    FSR0L,W       ; Move FSR to W
       movwf   fsave        ; Save FSR
                    
    ; Check for hardware overrun error
       btfsc   RCSTA,OERR   ; Check for usart overrun
       GoTo    usart_err    ; jump to assembly error routine
    
    ; Find in which bank the compiler put buffer, and set IRP 
    ;   IF (_buffer > 0FFh)  ; Find the bank where buffer is located
    ;      bsf   STATUS,IRP  ; If bank 2 or 3 set IRP
    ;   Else
    ;      bcf   STATUS,IRP  ; If bank 0 or 1 clear IRP
    ;   EndIF
                    
    ; Test for buffer overrun               
       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   Low _buffer  ; Get the location of buffer[0]
       addwf   _index_in,W  ; Add index_in to point to next empty slot
       movwf   FSR0L         ; Store pointer in FSR
    
    ; Read and store the character from the USART           
       movf   RCREG,W       ; Read the received character
       movwf  INDF0         ; Put the received character in FSR location
                    
    ; Restore FSR, PCLATH, STATUS and W registers
    finished
       movf   fsave,W       ; retrieve FSR value
       movwf  FSR0L          ; Restore it to FSR
       movf   psave,W       ; Retrieve PCLATH value
       movwf  PCLATH        ; Restore it to PCLATH
       swapf  ssave,W       ; Retrieve the swapped STATUS value (swap to avoid changing STATUS)
       movwf  STATUS        ; Restore it to STATUS
       swapf  wsave,F       ; Swap the stored W value
       swapf  wsave,W       ; Restore it to W (swap to avoid changing STATUS)
       retfie               ; Return from the interrupt
    
    ; 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
       movf  RCREG, W       ; Trash the received character
       GoTo  finished       ; Restore state and return to program
    EndAsm

    Thank you

    Francois Robbertze

  • #2
    simple answer use dt_ints-18.


    for a pic18 there are 16 bit regs that need saving and the potential for high and low priority interrupts.

    a snippet from dt ints for the registers you mention and their isr save vars
    Code:
    psaveUH     VAR BYTE  BANK0  SYSTEM   ' PCLATU Hi Pri.
    psaveUL     VAR BYTE  BANK0  SYSTEM   '        Lo Pri.
    psaveH      VAR BYTE  BANK0  SYSTEM   ' PCLATH Hi Pri.
    psaveL      VAR BYTE  BANK0  SYSTEM   '        Lo Pri.
    fsave0H     var WORD  BANK0  SYSTEM   ' locations for FSR registers
    fsave1H     var WORD  BANK0  SYSTEM
    fsave2H     var WORD  BANK0  SYSTEM
    fsave0L     var WORD  BANK0  SYSTEM   ' low priority FSR locations
    fsave1L     var WORD  BANK0  SYSTEM
    fsave2L     var WORD  BANK0  SYSTEM
    your asm code snippet to save fsr0 in a high priority interrupt

    Code:
    ASM
    ; Save the FSR value for later  
       movf    FSR0L,W       ; Move FSR to W
       movwf   fsave0H        ; Save FSR
       movf    FSR0H,W       ; Move FSR to W
       movwf   fsave0H+1     ; Save FSR
    ENDASM
    THAT needs to be emulated for the other 16 bit registers

    don't forget the BSR reg needs saving too , before exiting isr everything needs to be restored

    why reinvent wheel when dt_ints works so well







    2. Can FSR1 and FSR2 be used as well?
    yes

    Comment


    • #3
      Hi Richard,

      Thanks for the quick reply.

      Can you please direct me to a download link for the dt_ints-18 (latest version) as well as the ReEnterPBP file locations.

      I currently have dt_ints-18 (version 3.4 Nov 2009) and dt_ints-14 (version 1.1 Aug 2010)

      I will definitely give these a try.

      Since I haven't implemented Sir Darrel Taylor's code yet ..

      How can I adapt the following code to set the correct bank of "buffer"?

      Code:
      ; Find in which bank the compiler put buffer, and set IRP 
      ;   IF (_buffer > 0FFh)  ; Find the bank where buffer is located
      ;      bsf   STATUS,IRP  ; If bank 2 or 3 set IRP
      ;   Else
      ;      bcf   STATUS,IRP  ; If bank 0 or 1 clear IRP
      ;   EndIF
      Can I use something like:
      BANKSEL _buffer instead?

      Regards

      Francois

      Comment


      • #4
        most of dt works can be found here
        http://www.picbasic.co.uk/forum/showthread.php?t=19638


        How can I adapt the following code to set the correct bank of "buffer"?
        I'm not sure how you have defined buffer but lets assume

        Code:
        buffer var byte[32]
        the simplest way to get the bank is Using pbp's macros

        Code:
        asm
              CHK?RP _buffer   
              do asm stuff
              RST?RP  
        ENDASM
        alternative is with a bank 'modifier' to the declaration

        Code:
        buffer var byte[32]  bank0

        which would force buffer to bank0

        Comment


        • #5
          I have now implemented the DT_INTS-18 and it work perfectly on the PBP Interrupt but I would prefer the ASM option because of timing. Apparantly the ReEnterPBP takes some time to save the registers...

          I have use it on asm the first time, but the first byte is always wrong. I had the same problem in my origional ASM Interrupt without Darrel's Includes. It must be something in my ASM Int routine then?

          The mainloop enter with a value of "168" in the buffer[1] wich is the second byte of the IP Address of the wifi module. When a client connect it will output:
          ¿,CONNECTED but it should read 0,CONNECTED where (0 to 5) is the channel number.

          Low Priority Interrupst is not enabled.

          It must be a simple, but I cant spot the fault


          Code:
          INCLUDE "DT_INTS-18.bas"            ' Include Darrels interrupt engine.
          'INCLUDE "ReEnterPBP-18.bas"         ' And the stub needed for interrupts in PBP 
          
          
          ASM                                 ; Set up the USART transmit interrupt.
          INT_LIST  macro                     ; IntSource,   Label,    Type, ResetFlag?
                  INT_Handler    RX_INT,   myint,   ASM,    yes
              endm
              INT_CREATE                      ; Creates the interrupt processor
          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  32            ' 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  
          
          
             GoTo start                       ' Skip around interrupt handler
          
          ' Assembly language INTERRUPT handler
          Asm
          myint
                          
          ; Check for hardware overrun error
             btfsc   RCSTA,OERR   ; Check for usart overrun
             GoTo    usart_err    ; jump to assembly error routine
          
          ; Find in which bank the compiler put buffer
              banksel _buffer 
                        
          ; Test for buffer overrun               
             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   Low _buffer  ; Get the location of buffer[0]
             addwf   _index_in,W  ; Add index_in to point to next empty slot
             movwf   FSR0L        ; Store pointer in FSR
          
          ; Read and store the character from the USART           
             movf   RCREG,W       ; Read the received character
             movwf  INDF0         ; Put the received character in FSR location
          
          finished                
              banksel 0               ;go to bank0 before exit int
              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
             movf  RCREG, W    ; Trash the received character
             GoTo  finished       ; Restore state and return to program
          EndAsm
          
          start:
              PAUSE 123                              ' Let the PIC settle down
          
              Debug "Start",13 ,13
            
          Start_Interrupt: 
              debug "Init Interrupt",13 ,13
               
              index_in = 0                    ' Initialize ringbuffer variables
              index_out = 0  
          
              i = 0  
              connectedlog = 0
              newdataflag = 0
              errflag = 0
          
          @   INT_ENABLE  RX_INT     ; Enable USART RX Interrupts  
          Main:
             DEBUG "Main", 13 ,13
          
          MainLoop:   
           
          display:              ' dump the buffer to the terminal
             IF errflag Then error ' Goto error routine if needed
             IF index_in = index_out Then mainloop ' loop if nothing in buffer     
             GoSub getbuf         ' Get a character from buffer   
             debug bufchar        ' Send the character to terminal
             GoTo display         ' Check for more characters in buffer
          
          ' 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 (0 to 63)
             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 "B!",13,13 ' Display buffer error on line-2
             Else
                debug "U!",13,13  ' Display usart error on line_2
             EndIF
                  
             errflag = 0          ' Reset the error flag
             CREN = 0             ' Disable continuous receive to clear hardware error
             CREN = 1             ' Enable continuous receive
             INTCON = %11000000   ' Enable interrupts
             GoTo display         ' repeat
          Thanks

          Francois

          Comment


          • #6
            ReEnterPBP.BAS is not required for asm interrupts
            I can't see that RCSTA has been setup or spbrg either




            Code:
            Asm
            myint
                            
            ; Check for hardware overrun error
               btfsc   RCSTA,OERR   ; Check for usart overrun
               GoTo    usart_err    ; jump to assembly error routine
            
            ; Find in which bank the compiler put buffer
                banksel _buffer  ?  WHY HERE  WHY AT ALL?
            YOU WILL ACCESS buffer indirectly using fsr0
            if _buffer is not in bank0 then the wrong bank is selected for everything else
            
            
             Test for buffer overrun  
            
                         
               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   Low _buffer  ; Get the location of buffer[0]
               addwf   _index_in,W  ; Add index_in to point to next empty slot
               movwf   FSR0L        ; Store pointer in FSR
            what about the high byte of _buffer's address ?
            whats in FSR0H ?
            
            ; Read and store the character from the USART           
               movf   RCREG,W       ; Read the received character
               movwf  INDF0         ; Put the received character in FSR location
            
            finished                
                banksel 0               ;go to bank0 before exit int
             
               RST?RP 
               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
               movf  RCREG, W    ; Trash the received character
               GoTo  finished       ; Restore state and return to program
            EndAsm

            Comment


            • #7
              had some further thoughts , bit difficult not knowing baud rate

              with a buffer size less than 256 bytes and the inability to preserve the fsr registers between interrupts it seems rather pointless to use indirect addressing to fill the buffer

              its often worthwhile to check for a second received byte before leaving isr


              this link about halfway in, explains indirect addressing a little with some example code
              http://www.picbasic.co.uk/forum/showthread.php?t=19937

              Comment


              • #8
                Hi Richard,

                I use the following in my setup..(The above code is just a sniplet)

                Here is my RCSTA and SPBRG:

                Code:
                DEFINE HSER_RCSTA 90h  'Receive enabled
                DEFINE HSER_TXSTA 20h  'Transmit enabled    20h FOR LOWSPEED AND 24h FOR hIGH SPEED
                BAUDCON = %00001000    'baudcon<3> default 8 bit...set to one for 16 bit to use spbrgH
                'DEFINE HSER_BAUD 115200 
                DEFINE HSER_SPBRG 55  'spbrg vir 9600bps =   311...actial = 9615bps...0.16% error            
                SPBRGH = %00000001    'spbrgh - highbyte & spbrg   311 = %00000001(1) 00110111(55)
                At this stage I am running at 9600baud, but want to go up as fast as possible. The ESP8266 modules that I have is default 115200 baud. The faster the better.

                The ReEnterPBP is commented out...I left it there because I was experimenting between ASM and the PBP Int.

                I will check link on indirect addressing. Thanks

                Francois

                Comment


                • #9
                  Thanks for all the help. It is running OK now with a 256 byte ringbuffer.

                  I have change the following:

                  1. I have put buffer in Bank1 (also worked with 128 byte buffer in bank0)

                  Code:
                  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
                   
                  RCIF            VAR  PIR1.5       ' Alias RCIF (USART Receive Interrupt Flag)  
                  OERR           VAR  RCSTA.1      ' Alias OERR (USART Overrun Error Flag)  
                  CREN           VAR  RCSTA.4      ' Alias CREN (USART Continuous Receive Enable)
                   
                  buffer_size   CON  256                               ' Sets the size of the ring buffer  
                  buffer          VAR  BYTE[buffer_size] bank1    ' Array variable for holding received characters  
                   
                  BufChar         VAR  BYTE          ' Stores the character retrieved from the buffer
                  2. I have fixed the FSR0H problem so that it can point to the correct bank. (This was the culpret for the odd first caracter)

                  This is how it looks now:

                  Code:
                  ' Assembly language INTERRUPT handler
                  Asm
                  myint
                   
                  ; Check for hardware overrun error
                     btfsc   RCSTA,OERR   ; Check for usart overrun
                     GoTo    usart_err    ; jump to assembly error routine
                   
                  ; Test for buffer overrun               
                     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           
                     movf   RCREG,W       ; Read the received character
                     movwf  INDF0          ; Put the received character in FSR0 location
                   
                  ;    RST?RP               ;I read a post that suggest banksel might have less complications?
                      banksel 0              
                  ;I dont think this is even neccessary because we stay in Bank0. The FSR0 is a 12 bit register and can address all memory without the need to Bank. But I keep it here for safety...
                      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
                     movf  RCREG, W       ; Trash the received character
                     GoTo  finished       ; Restore state and return to program
                  EndAsm
                  No Usart or Buffer overrun errors at 9600baud. Ill stick to this for now.

                  I still need a current sensor (20Amps) before the fun part begin by putting all the bits and pieces together.

                  Regards

                  Francois

                  Comment


                  • #10
                    I have another puzzle.........SOLVED


                    After I parse the serial data, my code GOTO the webserver routine to serve the page.

                    Rx Interrupt is ON up to here.

                    Here is 'n snippet of my code:

                    Code:
                    'WEBSERVER ROUTINE
                     
                    Serve_HTTP:
                        Hits = Hits + 1
                        'INTCON = 0                   ' Disable interrupts (this was my first try)
                    @   INT_DISABLE RX_INT
                        
                        HSEROUT["AT+CIPSEND=",dec Activechannel,",17", 13, 10]
                        HSERIN 1000, timeout,[WAIT (">"), Dummy]
                        ' Send the actual data
                        HSEROUT["<!DOCTYPE HTML>", 13,10] '17
                        HSERIN 1000, timeout,[WAIT ("SEND OK"), Dummy]
                    
                        'I  use fixed code now for testing
                        ' Prepare to send bytes
                        HSEROUT["AT+CIPSEND=",dec Activechannel,",375", 13, 10]                 
                        HSERIN 1000, timeout,[WAIT (">"), Dummy]
                        ' Send the actual data
                        HSEROUT["<html lang=",34,"en",34,">", 13,"<head>",13,_ '24
                                "<TITLE>MULTI GEYSER CONTROLLER</TITLE>",13, 13,_ '40
                                "<style>",13,"body {",13, "background-color: yellow;",13, "}",13,"</style>",13,_ '52
                                "</head>",13,"<body>",13,_ '15
                                "<h1>GEYSER CONTROLLER:</h1>",13,"<hr>",13,"<h2>-WiFi Edition-</h2>",13, "<hr>", 13,_ '62       
                                "<H3>Patent: F Robbertze</H3>", 13, "<hr>",13,_       '34
                                "<H3>Page visits: ",dec3 Hits,"<H3>",13, "<hr>",13,_  '30
                                "<H3>Temp1: ",DEC2 (temperature1 / 100), ".", DEC2 temperature1,deg, "C</H3>", 13,_ '24 WITH DEG
                                "<H3>Temp2: ",DEC2 (temperature2 / 100), ".", DEC2 temperature2,deg, "C</H3>", 13,"<hr>",13,_  '29 with deg symbol
                                "<H3>Time: ",dec2 hours, ":",dec2 minutes, ":",dec2 seconds, "<H3>",13,_  '23
                                "<H3>Date: 20",dec2 year, "/",dec2 month, "/",dec2 date, "</H3>",13,_  '26
                                "</body>", 13,"</html>",13]       '16  
                     
                        HSERIN 1000, timeout,[WAIT ("SEND OK"), Dummy]
                                  
                        ' Now close channel?     
                         HSEROUT["AT+CIPCLOSE=",dec ActiveChannel, 13, 10]
                    
                        ' Close the connection (Sometimes channel is closed by the client and then responce is not OK and it GOTO timeout)
                        HSERIN 1000, timeout,[WAIT ("OK"), Dummy] 
                    
                        connectedlog[activechannel] = 0   'Flag the channel as closed
                    
                    @   INT_ENABLE RX_INT     ' Enable interrupts  here to prevent USART overrun
                    
                              
                        debug "HTTP Served: ",dec activechannel,13,10
                        httpreqlog[activechannel] = 0
                        keepalivereqlog[activechannel] = 0
                        low rxtxled
                    
                        goto MainLoop
                    
                    timeout:   
                    
                    @   INT_ENABLE RX_INT 
                        DEBUG "Timeout:http", 13 
                     
                    ' Now disconnect
                        HSEROUT["AT+CIPCLOSE=",dec ACTIVECHANNEL, 13, 10]
                        RxTxLed = 0
                        connectedlog[activechannel] = 0  
                    
                       goto Mainloop

                    This code work fine as long as the client don't close the connection prematurely.

                    When this happen the HSEROUT writes to a closed channel and it returns an error in stead of OK.

                    When this happen the HSERIN timeout and GOTO timeout. After that the INTERRUPT is enabled and then it GOTO MainLoop...

                    My problem is that the RX INTERRUPT stay OFF from here. I can send what I want to the USART it just dont trigger the INT.

                    I do not disable the interrups in my INT ROUTINE either.

                    What am I missing?

                    Regards

                    Francois
                    Last edited by eskulaap; 03-07-2016, 03:23 AM. Reason: Problem Solved

                    Comment


                    • #11
                      Regarding my previous post:

                      I forgot to clear the int flag (PIR1.5) before I re-enable the INT.

                      The server can be viewed here: http://robbertze.bounceme.net:8080
                      It wil be on for the rest of the day as I attend to some other stuff.
                      There are still a lot of bugs. The esp8266 is very slow to respond the firs time connection but thereafter it is better. New firmware on the esp8266 might do the job.

                      Next step is to change the thermostat's regulating temperature from the web interface. GET/POST is also 'n new teritory.

                      Regards

                      Francois
                      Last edited by eskulaap; 03-07-2016, 03:42 AM.

                      Comment


                      • #12
                        tried you link - very good it works

                        This code work fine as long as the client don't close the connection prematurely.
                        true, I also had problems if the client refreshed the page when the request was still pending and when a new client request popped up in the middle of serving an existing client request. both of these instances could lock the esp8266 up completely (needs power off restart).
                        also had issues with android clients.
                        I gave up on esp8266's and went back to raspberry pi's

                        have you seen this
                        http://www.picbasic.co.uk/forum/showthread.php?t=20957


                        I also worked you code into a small trial pgm to play with
                        I made a couple of small changes you might like to experiment with. might be a little faster




                        Code:
                        '****************************************************************
                        '*  Name    : ringbuffer.BAS                                      *
                        '*  Author  : [select VIEW...EDITOR OPTIONS]                    *
                        '*  Notice  : Copyright (c) 2016 [select VIEW...EDITOR OPTIONS] *
                        '*          : All Rights Reserved                               *
                        '*  Date    : 3/6/2016                                          *
                        '*  Version : 1.0                                               *
                        '*  Notes   :                                                   *
                        '*          :  PIF18F87J11                                                 *
                        '****************************************************************
                        
                        
                        
                         INCLUDE "DT_INTS-18.bas"            
                        'INCLUDE "ReEnterPBP-18.bas"         
                        
                        
                        ASM                                 ; 
                        INT_LIST  macro                     ; IntSource,   Label,    Type, ResetFlag?
                                INT_Handler    RX1_INT,   myint,   ASM,    yes
                            endm
                            INT_CREATE                      ; Creates the interrupt processor
                        ENDASM
                        
                        
                           DEFINE DEBUG_REG PORTB
                           DEFINE DEBUG_BIT 7
                           DEFINE DEBUG_BAUD 9600
                           DEFINE DEBUG_MODE 0
                        
                        TRISB.7=0  ;DEBUG
                        LATB.7=1   ;DEBUG
                        
                        
                        
                        
                        
                        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  256                               ' 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
                        
                        
                        '    trisC.6=0    ;tx1
                            RCSTA1 = $90   ' Enable serial port & continuous receive
                        '   TXSTA1 = $24   ' Enable transmit, BRGH = 1
                            SPBRG1 = 56    ' 38400 Baud @ 48MHz, -0.16%
                            SPBRGH1 = 1
                            BAUDCON1.3 = 1 ' Enable 16 bit baudrate generator
                        
                        
                        
                        
                        
                         GoTo start                       ' Skip around interrupt handler
                        
                        Asm
                        myint
                        ; Check for hardware overrun error
                           btfsc   RCSTA1,OERR   ; Check for usart overrun
                           bra    usart_err    ; jump to assembly error routine
                        ; Test for buffer overrun               
                           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)
                           bra   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           
                           movf   RCREG1,W       ; Read the received character
                           movwf  INDF0          ; Put the received character in FSR0 location
                           BTFSC  PIR1,TX1IF      ;ANY MORE ?
                           BRA    myint
                           
                        finished 
                           RST?RP
                           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
                           movf  RCREG1, W       ; Trash the received character
                           bra  finished       ; Restore state and return to program
                        EndAsm
                        
                        
                        
                        
                        
                        
                        
                        
                        start:
                            PAUSE 3000                              ' Let ME CONNECT PICKIT UART MODULE
                            Debug "Start",13 ,13
                          
                            index_in = 0                    ' Initialize ringbuffer variables
                            index_out = 0  
                            GOSUB error  ;CLR AND RESET EUART
                            PIR1.4=0  ;CLR RX IF
                        
                        @   INT_ENABLE  RX_INT     ; Enable USART RX Interrupts  
                        Main:
                           DEBUG "Main", 13 ,13
                        
                        MainLoop:   
                         
                        display:              ' dump the buffer to the terminal
                           IF errflag Then GOSUB error ' Goto error routine if needed
                           IF index_in = index_out Then mainloop ' loop if nothing in buffer     
                           GoSub getbuf         ' Get a character from buffer   
                           debug bufchar        ' Send the character to terminal
                           GoTo display         ' Check for more characters in buffer
                        
                        ' 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 (0 to 63)
                           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 "B!",13,13 ' Display buffer error on line-2
                           Else
                              debug "U!",13,13  ' Display usart error on line_2
                           EndIF
                           PIR1.4=0 ;rx int flg     
                           errflag = 0          ' Reset the error flag
                           RCSTA1.4=0           'CREN = 0 Disable continuous receive to clear hardware error
                           RCSTA1.4=1           'CREN = 1 Enable continuous receive
                           INTCON = %11000000   ' Enable interrupts
                           GoTo RETURN         ' repeat
                        
                            ;clear any rcsta error

                        Comment


                        • #13
                          Next step is to change the thermostat's regulating temperature from the web interface. GET/POST is also 'n new teritory.
                          http://www.picbasic.co.uk/forum/showthread.php?t=20957

                          post #21

                          Comment


                          • #14
                            Thanks Richard,

                            PIR1.5 is the TXIF in the 18F2550 and unfortuanately is READ ONLY. It seems the only way to clear it is by reading the RXREG.

                            Thanks for the link. I have seen the ESBBasic thing. It looks very easy to use. Wil try it some time. Can you please resend the last link (GET POST). It seem to be the same as the first.

                            Regards

                            Francois

                            Comment


                            • #15
                              Thanks for the link. I have seen the ESBBasic thing. It looks very easy to use. Wil try it some time. Can you please resend the last link (GET POST). It seem to be the same as the first.
                              sorry bout that
                              http://www.picbasic.co.uk/forum/showthread.php?t=20889

                              PIR1.5 is the TXIF in the 18F2550 and unfortuanately is READ ONLY. It seems the only way to clear it is by reading the RXREG.
                              correct TXIF and RXIF are ro so trying to clear them is a waste of time , I will go back and check some of my other code too

                              Comment

                              Working...
                              X