Darrel Taylor Interrupts I2C Problem


Closed Thread
Results 1 to 12 of 12
  1. #1
    Join Date
    Mar 2008
    Posts
    9

    Exclamation Darrel Taylor Interrupts I2C Problem

    Hello all:

    First of all, thanks for that really good software Mr Taylor have developed , it is helping me a lot for developing my software.

    The question is my interrupts routines are using PBP code (I2CREAD), but I started defining my interrupts as ASM type. All seems to work fine, but have some issues on HSEROUT calls so I realize that I have to use PBP type interrupts to solve it. But the question is that when I started to use PBP ones all stop working.

    During some days I have been investigating this strange situation, and I have found a pseudo workaround that don't explain the issue.

    My interrupt handler is that:

    INT_READER:
    I2CREAD i2c_rdr_SDA, i2c_rdr_SCL, rdr_I2C_DIR_SLAVE , [str RDR_I2C_BUFFER\RDR_I2C_BUFFER_SIZE], INT_READER_ERR
    INT_READER_ERR:
    @ INT_RETURN

    The errors come when i use PBP interrupt. When i use it the I2CREAD routine don't read anything.

    The Workaround: I have been making some tests, and the problem disappear if I comment a line in ReEnterPBP-18.bas
    The line is at RestorePBP_H routine:

    FLAGS = FLAGS_SaveH

    When I comment this line all start working. WHY?

    As I can see in Mr Taylor's code, this routine is executed once the interrupt routine is finished, so I don't understand why this affect the I2CREAD routine. Maybe this line makes the I2C routines to go "disabled"???? (the FLAGS var is used to control PBP I2C MASTER routines)

    Any suggestions will be welcome, thanks in advance...

    dcorraliza

  2. #2
    Join Date
    Mar 2008
    Posts
    9


    Did you find this post helpful? Yes | No

    Default More starnge workaround

    Hi all:

    Today I have found a different workaround for this issue, but this workaround don't let me to understand what is happening...

    The workaround is to add a byte variable to ReEnterPBP-18.bas like that:
    HP_Vars VAR WORD[34] ; group vars together for less banking
    R0_SaveH VAR HP_Vars[0]
    ......
    ......
    TBLPTRH_SaveH VAR TBLPTR_H.highbyte
    TBLPTRL_SaveH VAR TBLPTR_H.lowbyte
    Product_H VAR HP_Vars[33]
    nothing VAR byte

    With this new variable called "nothing" i can re-enable the at RestorePBP_H routine:

    FLAGS = FLAGS_SaveH

    And the code keep working properly. Why???????????????

    I don't know the reason, but the last time an issue was fixed with a dummy variable definition, was because of banking errors.

    Any suggestion???????

    The mystery continues.....

    dcorraliza

  3. #3
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Answered in the other forum.
    <br>
    DT

  4. #4
    Join Date
    Mar 2008
    Posts
    9


    Did you find this post helpful? Yes | No

    Default Darrel Taylor replay (2008/3/19 22:09) from the other forum (pbpgroup)

    DT said:
    e: ASM vs PBP interrupts
    Do you have other I2C statements in the Main program?

    If you attempt to execute I2C statements in the interrupt handler, it's possible that another I2C command is already being executed from the main loop.

    In which case, everything gets confused.

    By commenting the line that you did. When it returns to the main loop, the currently executing I2C statement suddenly thinks it's done with what it was doing, but in actuality, it was the I2C in the interrupt handler that finished, not the one that got interrupted.

  5. #5
    Join Date
    Mar 2008
    Posts
    9


    Did you find this post helpful? Yes | No

    Default Re: ASM vs PBP interrupts

    Hi Mr Taylor:

    Thanks for your response. No, I'm not using i2c out of interrupts routine, but I'm planning to. So I think (the same way yo do) is not a good idea to comment any line in your code. Because of that, here I post you a new "strange workaround" I have found making some tests:

    The workaround is to add a byte variable to ReEnterPBP-18.bas like that:
    HP_Vars VAR WORD[34] ; group vars together for less banking
    R0_SaveH VAR HP_Vars[0]
    ......
    ......
    TBLPTRH_SaveH VAR TBLPTR_H.highbyte
    TBLPTRL_SaveH VAR TBLPTR_H.lowbyte
    Product_H VAR HP_Vars[33]
    nothing VAR byte

    With this new variable called "nothing" I can re-enable the commented line at RestorePBP_H routine:

    FLAGS = FLAGS_SaveH

    And the code keep working properly. Why???????????????

    I don't know the reason, but the last time an issue was fixed with a dummy variable definition, was because of banking errors.

    Any suggestion???????

    The mystery continues.....

    dcorraliza

  6. #6
    Join Date
    Mar 2008
    Posts
    9


    Did you find this post helpful? Yes | No

    Default Darrel Taylor replay (2008/3/20 6:34) from the other forum (pbpgroup)

    dcorraliza,

    The things you are saying make no sense.

    I'm sure you are just seeing the symptoms of the problem, and when they change, you feel that what you changed fixed it. But, more than likely the problem just moved somewhere else.

    Only seeing 5 or 6 lines of your 64k code gives me no way of knowing what's going wrong.

    Attempting to convert an already existing (very large) program to use Instant Interrupts, almost never works.

    When the program was written to begin with. No attention was paid to what can happen with interrupts. The program has already been debugged and known to be working.

    Then when you suddenly try to add interrupts, and nothing works anymore. Since you already know the program worked before, it must be Darrel's program that's causing the problem. And any other possibilities are ignored because again. It already works. (on it's own)

    DT_INTS is a starting point. If you start writing your program with it. You'll end up with a really cool program in the end.

    If you want to apply it to an existing program that wasn't written for interrupts. It's not likely to work.

    Sorry,
    Darrel Taylor

  7. #7
    Join Date
    Mar 2008
    Posts
    9


    Did you find this post helpful? Yes | No

    Default

    Hi Mr Taylor:

    I agree with you about the difficult task of introducing interrupts on a big program, but I think the problem isn't there.

    Following your recommendations I have extract the core lines of my program, just to test the interrupts, so my lite-version is that:

    DEFINE LOADER_USED 1
    iNCLUDE "cfgvtol-MIXER_18f2685_40mhz.bas"
    INCLUDE "DT_INTS-18.bas"
    INCLUDE "ReEnterPBP-18.bas"


    DEC_MICRO:
    DEFINE I2C_HOLD 1

    ADCON1 = %00001111

    PORTA = 0
    TRISA = %111101
    PORTB = 0
    TRISB = %00000001
    PORTC = 0
    TRISC = %10000100
    PORTE = 0

    I2C_RDR_SCL VAR PORTC.3 ' I2C Reader clock
    I2C_RDR_SDA VAR PORTC.4 ' I2C Reader data

    RDR_I2C_DIR_SLAVE con $24
    RDR_I2C_BUFFER_SIZE con 32
    RDR_I2C_BUFFER var byte[RDR_I2C_BUFFER_SIZE]
    RDR_FLAG VAR BIT
    RDR_AUX VAR Byte
    RDR_VALUE VAR WORD

    ASM
    INT_LIST macro ; IntSource, Label, Type, ResetFlag?
    INT_Handler INT0_INT, _INT_READER, PBP, yes
    endm
    INT_CREATE ; Creates the interrupt processor
    ENDASM
    @ INT_ENABLE INT0_INT ; enable external (INT) interrupts

    RDR_FLAG=0

    LOOP:
    if rdr_flag then
    for RDR_AUX=0 to RDR_I2C_BUFFER_SIZE-1 step 2
    RDR_VALUE.lowbyte = RDR_I2C_BUFFER[RDR_AUX]
    RDR_VALUE.highbyte = RDR_I2C_BUFFER[RDR_AUX+1]
    hserout[dec RDR_VALUE, tab]
    next RDR_AUX
    hserout [cr, lf]
    rdr_flag=0
    endif
    GOTO LOOP

    INT_READER:
    I2CREAD i2c_rdr_SDA, i2c_rdr_SCL, rdr_I2C_DIR_SLAVE , [str RDR_I2C_BUFFER\RDR_I2C_BUFFER_SIZE], INT_READER_ERR
    RDR_FLAG = 1
    INT_READER_ERR:
    @ INT_RETURN

    This program only waits for an interrupt in the RB0 port and then performs an I2CREAD. If the I2CREAD has success a flag is activated.

    In the main loop, we just look for the flag to change, and then the data received is sent through the serial port.

    As you said, defining a new variable on your code, makes no changes (my mistake), but restoring FLAG var still is the clue. If FLAG var is restored, the i2cread is only executed properly the first time, and if I delete that line (I know that isn't right, but is used to investigate) I2CREAD is executed every 20ms (the right frame)

    Following that trail, I have introduced some dummy vars to obtain FLAGS var status in different moments of the interrupt:
    FLAGS=00100000 When being saved for the first time.
    FLAGS=01100000 After I2CREAD has being executed.
    FLAGS_SaveH=00000100 Line before restoring FLAG, is a little strange because FLAGS was 00100000 when was saved (When was FLAGS_SaveH modified?????)
    FLAGS=00000100 After restoring
    If that value is restored, I2CREAD don't work any more.

    As I have said, if we don't restore the FLAGS var I2CREAD keeps working, leaving FLAGS=01100000

    I hope you can help me with this reduced program that shows something strange happening.

    Maybe is a nonsense, but value of FLAGS_SaveH when saved (00100000) and when restored (00000100) is the same value with inverted alignment, ?????

    Thanks in advance,

    dcorraliza

  8. #8
    Join Date
    Mar 2008
    Posts
    9


    Did you find this post helpful? Yes | No

    Default Solution found

    Hi all:

    Finally the problem has an explanation, and I feel I have found it. Has been a lot of hours trying to understand this strange behaviour, but at least I caught it.

    The question was easier that it seems, it was an "initial" condition, the one that makes all go bad. The first time an interrupt was handled disable the I2CREAD routine. The clue was in the values tracked by me of:

    FLAGS=00100000 When being saved for the first time.
    FLAGS=01100000 After I2CREAD has being executed.
    FLAGS_SaveH=00000100 Line before restoring FLAG, is a little strange because FLAGS was 00100000 when was saved (When was FLAGS_SaveH modified?????)
    FLAGS=00000100 After restoring

    In this previous paragraph I take notice that the value that was saved on FLAGS_SaveH wasn't the same when we tray to restore it, and I said: When was FLAGS_SaveH modified?????
    This is a wrong question, the question is: Was FLAGS saved on FLAGS_SaveH? And the answer is NO. This flag var was not saved, because on top of "SavePBP_H:" routine we only save vars if VarsSaved_H = 0. And this is the reason, VarsSaved_H wasn't initialized at the beginning of the program so depending on the compilation it could have a "0" (Like when I added de "nothing" var) and make all work properly, or a "1" that makes the first interrupt handling not to save previous values, and then restoring rubbish ones.

    My workaround is to add a initialization line under variable definition:
    DEFINE ReEnterHPused 1
    VarsSaved_H VAR BIT
    VarsSaved_H=0 <-------ADDED

    But maybe Mr Taylor, can help me to know if this initialization should be done on INT_ENABLE routine, to ensure its value every time we enable interrupts. What do you think Mr Taylor?

    That's all for now, I hope all of you have enjoyed the mystery resolution, as I do...

    Greetings,
    dcorraliza

  9. #9
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Still looking at my program for your problem I see.

    VarsSaved_H is a flag that gets set when ever the Instant Interrupt system saves PBP's System variables in a High Priority interrupt.

    With complex programs using both ASM and PBP type handlers, it allows the system to only save and restore the system variables when it needs to.

    You are only using a single PBP type interrupt. That bit will always be set on entry to the interrupt handler, And is cleared after the handler has finished. Initializing it to 0 will not do anything.

    The only way it could possibly have an affect on your program, is if you have enabled Interrupts that do not have an associated handler.

    So anyhow, what are you reading with the I2C statement. (what chip)
    <br>
    DT

  10. #10
    Join Date
    Mar 2008
    Posts
    9


    Did you find this post helpful? Yes | No

    Default

    Hi Mr Taylor:

    Please, don't think I'm trying to put my problems on your program, be sure I'm not looking for a guilty, I'm just trying to find a workaround to my problem. Your software is great, and that's what I'm using it, but I have an issue I need to fix. Maybe I need to change the post subject, because I'm not sure where the problem is.

    If you are asking me for the I2C slave, is an specific purpose pic, reading analog inputs and sending it digitalized by I2C protocol, every 20ms.

    Talking about my previous post, I know that VarsSaved_H is set every time you start the handle of an PBP High Priority interrupt. But I can see in your code that you only save the variables "if VarsSaved_H = 0 then" so if VarsSaved_H=1 when you enter the "SavePBP_H" routine you don't save then and VarsSaved_H keeps its value to 1. At the interrupt handling exiting the program again look for VarsSaved_H state to know if it needs to restore variables, as the system see VarsSaved_H=1 it restores some value that nobody has set.
    As long as I can see VarsSaved_H is not initialized anywhere before entering "SavePBP_H" for the first time, so we can't know what value it has. If it is 1 then the problem appears. Are you agree?

    I don't have any doubt that maybe my program has another problems, or maybe the I2C slave is generating me other issues, but I think that VarsSaved_H initialization should be done for a right execution.

    To end, please accept my apologies if my English isn't good enough and you misunderstood my intentions. I'm just trying to find a solution to my problems, and making it public to maybe help other people

    Greetings,
    dcorraliza

  11. #11
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    OK, I see what you're saying dcorraliza.

    I always have a CLEAR statement at the beginning of the program, so it's never been a problem for me.

    I should add your suggestion, for the people that don't use Clear.

    Sorry for the thick head.
    Thanks for the persistence.

    Darrel

    Added:
    &nbsp; I'll also be adding INT_Flags = 0 to the DT_INTS.bas file.
    &nbsp; Thanks again.
    Last edited by Darrel Taylor; - 24th March 2008 at 18:01. Reason: .

  12. #12
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    I imagine there are a lot of people that don't have CLEAR in their programs, so I'm glad you found that dcorraliza.

    I've updated the DT_INTS-18 files to version 3.3

    You can find the new version here ...
    http://darreltaylor.com/DT_INTS-18/downloads.html

    Thanks again,
    DT

Similar Threads

  1. I2C Master/Slave 16F88/16F767 working code
    By DanPBP in forum Code Examples
    Replies: 2
    Last Post: - 23rd October 2012, 22:31
  2. HARDWARE I2C SAMPLE CODE question
    By Michael Wakileh in forum Code Examples
    Replies: 2
    Last Post: - 16th June 2009, 21:07
  3. Another I2C Slave Routine Problem
    By DanPBP in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 19th February 2009, 05:50
  4. I2C Master Slave issues.
    By cpayne in forum mel PIC BASIC Pro
    Replies: 9
    Last Post: - 29th March 2008, 19:33
  5. I2C eeprom and DS1307 @40MHz problem
    By ius01 in forum mel PIC BASIC Pro
    Replies: 9
    Last Post: - 20th July 2007, 07:41

Members who have read this thread : 1

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