• AVR Freaks

Hot!Placing *.inc files to main file create strange problem

Page: 12 > Showing page 1 of 2
Author
_pike
Senior Member
  • Total Posts : 138
  • Reward points : 0
  • Joined: 2012/12/02 11:34:43
  • Location: 0
  • Status: offline
2019/11/09 13:13:42 (permalink)
0

Placing *.inc files to main file create strange problem

Hello experts!!! I am struggling to understand a problem that it is created when i place *.inc files to different order on my main.asm
This period i am building some libraries for different modules i use, and usually (dont know if is is the right way to do) i create an *.inc file where i oftently call some functions to be executed on my main.(i would also like to hear your opinion to that) So yesterday i noticed a strange behaviour when i "seperated" the code that it is reffering to the module from the main.asm to the *.inc file. The module that i play is a mechanical rotary encoder. I tried to debug and understand why the program does nothing when i place the inc file above on another but with no success. (i suspect that it has to do with the linker of how it places the code) Here is an example:
#INCLUDE "ROTARY_ENCODER_MECH.INC"  <<< When i place it here above all.., the main never reaches to start where it blinks a led.
#INCLUDE "MSECDELAYGENERATOR16MHZ.INC"    
#INCLUDE "LCD_I2C_18F27K42.INC"
 
The ROTARY_ENCODER_MECH.INC has a lookup table in it....when i move it from the *.inc file to the main everything works fine....!!!!!  
 
Before placing any code does anyone might understand why is this happening?
 
Thank you all !!!
 
 
 
 
post edited by _pike - 2019/11/09 13:16:26
#1

22 Replies Related Threads

    ric
    Super Member
    • Total Posts : 24639
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: Placing *.inc files to main file create strange problem 2019/11/10 00:43:19 (permalink)
    0
    If you include files like that, the linker has nothing to do with it.
    What PIC family are you programming for?
    If you're having problems with a lookup table, and it's an old PIC16F family device, I can guess why you're having problems, but would need to see your table read code.
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #2
    teenix
    Starting Member
    • Total Posts : 32
    • Reward points : 0
    • Joined: 2017/12/21 13:47:21
    • Location: Australia, Melbourne
    • Status: offline
    Re: Placing *.inc files to main file create strange problem 2019/11/10 02:26:39 (permalink)
    0
    It may be because this file is included in the source file at the position the statement executes.
     
    #INCLUDE "ROTARY_ENCODER_MECH.INC" 
     
    If the file has code then the address of the start of this code may not be where you expect it.
     
    cheers
     
    Tony
    #3
    _pike
    Senior Member
    • Total Posts : 138
    • Reward points : 0
    • Joined: 2012/12/02 11:34:43
    • Location: 0
    • Status: offline
    Re: Placing *.inc files to main file create strange problem 2019/11/10 08:58:45 (permalink)
    0
    Well i use a pic18f27k42  and below is the table.... I use an interrupt on change to check if the encoder has changed position and with this look up table i compare the previous with the current values.
    When this table is placed on the main.asm everything works fine. But if i separate it from the main by placing it on the inc file, the program never goes to start. which is a simple led flashing routine.

     

    ENCODER_TABLE

    addwf PCL
    retlw .0 ; 0
    retlw .3 ; 1
    retlw .1 ; 2
    retlw .0 ; 3
    retlw .1 ; 4
    retlw .0 ; 5
    retlw .0 ; 6
    retlw .3 ; 7
    retlw .3 ; 8
    retlw .0 ; 9
    retlw .0 ; 10
    retlw .1 ; 11
    retlw .0 ; 12
    retlw .1 ; 13
    retlw .3 ; 14
    retlw .0 ; 15
     
     
     

     
     
    Thanks!!!
    post edited by _pike - 2019/11/10 09:05:40
    #4
    _pike
    Senior Member
    • Total Posts : 138
    • Reward points : 0
    • Joined: 2012/12/02 11:34:43
    • Location: 0
    • Status: offline
    Re: Placing *.inc files to main file create strange problem 2019/11/10 09:03:46 (permalink)
    0
    teenix
    It may be because this file is included in the source file at the position the statement executes.
     #INCLUDE "ROTARY_ENCODER_MECH.INC" 

    The assembler accepts these types of files at the end of the program before end statement
     
    teenix
    If the file has code then the address of the start of this code may not be where you expect it.

     
    That was my first assumption.... and thats why i reffered that it has to do with the linker. But ric says that this problem has nothing to do with the linker
    #5
    crosland
    Super Member
    • Total Posts : 1696
    • Reward points : 0
    • Joined: 2005/05/10 10:55:05
    • Location: Warks, UK
    • Status: offline
    Re: Placing *.inc files to main file create strange problem 2019/11/10 09:29:11 (permalink)
    0
    teenix
    It may be because this file is included in the source file at the position the statement executes.
     
    #INCLUDE "ROTARY_ENCODER_MECH.INC" 
     
    If the file has code then the address of the start of this code may not be where you expect it.

     
    Most importantly the encoder table may not be where you think it is.
     
    Think about what happens if 

    addwf PCL

     
    results in a carry.
    #6
    _pike
    Senior Member
    • Total Posts : 138
    • Reward points : 0
    • Joined: 2012/12/02 11:34:43
    • Location: 0
    • Status: offline
    Re: Placing *.inc files to main file create strange problem 2019/11/10 09:51:32 (permalink)
    0
    crosland
    Think about what happens if 

     
    addwf PCL
     
     
    results in a carry.




    I didn't understand this fact...   Can you please explain it to me in more detail ?   
     
    Thank you!!
    #7
    crosland
    Super Member
    • Total Posts : 1696
    • Reward points : 0
    • Joined: 2005/05/10 10:55:05
    • Location: Warks, UK
    • Status: offline
    Re: Placing *.inc files to main file create strange problem 2019/11/10 11:18:01 (permalink)
    0
     
    When you have something that is more than one byte, such as the PC, what happens if you add a byte to the low byte and the add generates a carry?
     
    E.g.
    PC = 0x01Fa
    Add 0xc to PCL
     
    What is the resulting value of PC?
    #8
    1and0
    Access is Denied
    • Total Posts : 10005
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Placing *.inc files to main file create strange problem 2019/11/10 11:41:44 (permalink)
    0
    _pike
    Hello experts!!! I am struggling to understand a problem that it is created when i place *.inc files to different order on my main.asm
    ...
    Here is an example:
    #INCLUDE "ROTARY_ENCODER_MECH.INC"  <<< When i place it here above all.., the main never reaches to start where it blinks a led.
    #INCLUDE "MSECDELAYGENERATOR16MHZ.INC"    
    #INCLUDE "LCD_I2C_18F27K42.INC"
     
    The ROTARY_ENCODER_MECH.INC has a lookup table in it....when i move it from the *.inc file to the main everything works fine....!!!!!  
     
    Before placing any code does anyone might understand why is this happening?


    But if i separate it from the main by placing it on the inc file, the program never goes to start. which is a simple led flashing routine.

    In assembly when you include a file inside another file, the entire content of that file is placed into that exact location of the including file. So, what you have done is basically this and your source code ended up as 
            org     0x0000
    ENCODER_TABLE
            addwf PCL
            retlw .0 ; 0
            retlw .3 ; 1
            retlw .1 ; 2
            retlw .0 ; 3
            ; snipped

    I cannot find the POR value of WREG in the latest datasheet (I much prefer the old format datasheet). So, let's assumed it is zero, then this code will be an infinite loop causing a stack underflow and executing the first two instructions.  If WREG has a value larger than the size of your lookup table, then the branch will go to neverneverland. ;) 
     
    Anyway, if you're going to include a file, place that #include line at wherever you want the content of that file to be located inside the including file (in your case the main file).
     
    post edited by 1and0 - 2019/11/10 12:01:35
    #9
    Ian.M
    Super Member
    • Total Posts : 13268
    • Reward points : 0
    • Joined: 2009/07/23 07:02:40
    • Location: UK
    • Status: offline
    Re: Placing *.inc files to main file create strange problem 2019/11/10 11:56:47 (permalink)
    0
    On anything except Baseline and Standard Midrange PIC12/16 devices RETLW tables accessed by directly modifying the program counter are insane.   For PIC18 devices you should be using the TBLRD instruction, and probably using the DATA directive for strings and 16 bit values and the DB directive for packed byte values to avoid  wasting memory with unnecessary RETLW opcodes in the high byte of each word of the table.
     
    See section 8 of the PIC18 MCU Family Reference manual* for a good overview and your specific PIC18's datasheet and errata for any differences and hardware bugs.
     
    Also its possible that your table may be getting placed in the wrong section, displacing your code that should be placed at the reset and interrupt vectors. Take the .map files output by MPASM for the working and bad builds, making sure the only difference between the source files is where in the source you create the table, and compare them paying specific attention to the address of the table and of your startup code.
     
    http://ww1.microchip.com/downloads/en/devicedoc/39500a.pdf 

    --
    NEW USERS: Posting images, links and code - workaround for restrictions.
    I also support http://picforum.ric323.com because this forum is sometimes too broken to use!
    #10
    1and0
    Access is Denied
    • Total Posts : 10005
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Placing *.inc files to main file create strange problem 2019/11/10 12:08:20 (permalink)
    0
    Ian.M
    On anything except Baseline and Standard Midrange PIC12/16 devices RETLW tables accessed by directly modifying the program counter are insane.   For PIC18 devices you should be using the TBLRD instruction, and probably using the DATA directive for strings and 16 bit values and the DB directive for packed byte values to avoid  wasting memory with unnecessary RETLW opcodes in the high byte of each word of the table.

    Agree there are much better methods to implement lookup tables on PIC18 devices.
     
    That said, there's also better method to read an encoder without "tracking" its previous state to compare with the current state.
    #11
    teenix
    Starting Member
    • Total Posts : 32
    • Reward points : 0
    • Joined: 2017/12/21 13:47:21
    • Location: Australia, Melbourne
    • Status: offline
    Re: Placing *.inc files to main file create strange problem 2019/11/10 12:48:02 (permalink)
    0
    The carry problem is because of the [addwf PCL] instruction. if the PC is at 0x01FC and Wreg was 0x08. the new PC will be 0x0104, not 0x0204.
     
    That's because the PCLATH register is responsible for the upper addressing bytes. (PCLATU too for larger ROMs)
     
    You have to make sure the PCLATH register is set to the ROM page where the table resides. If the table extends into another ROM page, then you need to either compute the PCLATH value based on the Wreg offset, or shift the table so it doesn't overlap 256 byte ROM page boundaries.
     
    Also, in the 18F, PC offsets must be a multiple of 2. The [retlw 0x??] instructions occupy 2 bytes. [goto ????] instructions use 4 bytes so in assembler, before the [addwf PCL] you have to multiply the Wreg offset by 2 for the retlw, or 4 in a jump table full of goto's.
     
    cheers
    Tony
    post edited by teenix - 2019/11/10 12:52:00
    #12
    crosland
    Super Member
    • Total Posts : 1696
    • Reward points : 0
    • Joined: 2005/05/10 10:55:05
    • Location: Warks, UK
    • Status: offline
    Re: Placing *.inc files to main file create strange problem 2019/11/10 12:51:06 (permalink)
    0
    teenix
    The carry problem is because of the [addwf PCL] instruction. if the PC is at 0x01FC and Wreg was 0x08. the new PC will be 0x0104, not 0x0204.

    It would have been more instructional to let him work it out for himself :)
    #13
    _pike
    Senior Member
    • Total Posts : 138
    • Reward points : 0
    • Joined: 2012/12/02 11:34:43
    • Location: 0
    • Status: offline
    Re: Placing *.inc files to main file create strange problem 2019/11/10 16:18:12 (permalink)
    0
    Thank you all for your replies !!!!!! You were all very informative!!!!
     
    1and0
    In assembly when you include a file inside another file, the entire content of that file is placed into that exact location of the including file.
    .............
    Anyway, if you're going to include a file, place that #include line at wherever you want the content of that file to be located inside the including file (in your case the main file).

     
    I see......!!!  So if you want to build a library, how you can accomplished that? And i mean to gather functions in it, for specific modules and when you call a routine, to be executed anywhere in the main. (Since 18f devices dont have page bountaries)
    I have seen in C and especially in arduino libraries that they include files at the beginning e.x <#include stdio> or <#include dht22> where this file can be used anywhere in their program.
     
    Ian.M
    On anything except Baseline and Standard Midrange PIC12/16 devices RETLW tables accessed by directly modifying the program counter are insane.   

    Why? I mean why is insane, since you restore the PC again after a call.....using return
     
    1and0
    For PIC18 devices you should be using the TBLRD instruction, and probably using the DATA directive for strings and 16 bit values and the DB directive for packed byte values to avoid  wasting memory with unnecessary RETLW opcodes in the high byte of each word of the table.

    Basically this is the way that i use tables..... That was an old lookup table technique i was using and to be honest each time i learn something new i didnt know about..!!!!
     
    1and0
    That said, there's also better method to read an encoder without "tracking" its previous state to compare with the current state.

    Can you share an idea?
     
    regards
     
     
     
    #14
    ric
    Super Member
    • Total Posts : 24639
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: Placing *.inc files to main file create strange problem 2019/11/10 16:33:28 (permalink)
    5 (1)
    _pike
    I see......!!!  So if you want to build a library, how you can accomplished that?

    You learn how to use the linker, and link files together.
    Using #include to insert the source itself is a very simplistic way of joining files together, that only works for very simple code.
     

    I have seen in C and especially in arduino libraries that they include files at the beginning e.x <#include stdio> or <#include dht22> where this file can be used anywhere in their program.

    That is linking object modules together. The include files are just headers that declare the functions that are being linked, so the compiler knows what parameters they accept, and what sort of argument they return.
     

    Ian.M
    On anything except Baseline and Standard Midrange PIC12/16 devices RETLW tables accessed by directly modifying the program counter are insane.   

    Why? I mean why is insane, since you restore the PC again after a call.....using return

    Because you have to do substantial work to set the PCLATH register to make it work, including handling carry from the lower 8 bits correctly, which is insane when the PIC18F chips (and newer PIC16F1xxx chips) have much easier mechanisms for reading program memory.
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #15
    teenix
    Starting Member
    • Total Posts : 32
    • Reward points : 0
    • Joined: 2017/12/21 13:47:21
    • Location: Australia, Melbourne
    • Status: offline
    Re: Placing *.inc files to main file create strange problem 2019/11/10 17:37:57 (permalink)
    0
    The complexity of your table code depends on the data types and table size you need.
     
    Here's a couple of simple examples for 18F. Both are easy to implement. If you understand the PCLATH mechanism properly there is usually no drama. Test code is easy to play with in MPLAB especially if you write small chunks of it to test how the data retrieval works.
     
         org 0x01FC   ; the table below will fail
    or
         org 0x0100   ; the table below will work
     
    Table movlw HIGH Table
     movwf PCLATH
     rlncf Offset,W   ; offset x 2 (retlw XX is a 2 byte instruction)
     addwf PCL
     retlw 0x09
     retlw 0x35
     ...
    vs
     
    Table movf Offset,W
     addlw LOW myData
     movwf TBLPTRL
     movlw HIGH myData
     movwf TBLPTRH          ; may need TBLPTRU in larger ROMs
     tblrd*+
     movf TABLAT,W
     return
     ...
    (myData can be anywhere in ROM)
    myData data 0x0935, 0xC1F9, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xB3FF
     
    Either approach is perfectly valid, but large tables are much better using the tblrd approach as the data table is more compact.
     
    Little trip ups for the 18F series, see what happens if you forget to double the offset value for retlw xx instructions, work out what value TABLAT returns in sequential reads with the different tblrd types.
     
    cheers
     
    Tony
    #16
    1and0
    Access is Denied
    • Total Posts : 10005
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Placing *.inc files to main file create strange problem 2019/11/10 18:13:08 (permalink)
    4 (1)
    teenix
    Table movf Offset,W
    addlw LOW myData
    movwf TBLPTRL
    movlw HIGH myData
    movwf TBLPTRH          ; may need TBLPTRU in larger ROMs
    tblrd*+
    movf TABLAT,W
     return

    That fails to handle any carry from the lower addition.
    #17
    1and0
    Access is Denied
    • Total Posts : 10005
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Placing *.inc files to main file create strange problem 2019/11/10 18:25:42 (permalink)
    0
    _pike
    I see......!!!  So if you want to build a library, how you can accomplished that? And i mean to gather functions in it, for specific modules and when you call a routine, to be executed anywhere in the main. (Since 18f devices dont have page bountaries)

    As I've said, #including a file in assembly is to insert the content of that file at that position in the including file. That is how files are joined together into one file as in absolute mode.  If you want to let the linker to allocate your files, then you'll have to use relocatable mode; and code each module to account for paging and banking, as you do not know where the linker will place the module.
     

    Why? I mean why is insane, since you restore the PC again after a call.....using return

    I wouldn't call it insane -- just there are better methods in PIC18 devices. RETLW can only store one byte per program memory word; whereas with other methods two bytes can be stored in one word, making efficient uses of the memory.
     

    Can you share an idea?

    Here's other way of reading the encoder without tracking its previous states: https://www.microchip.com/forums/m1096131.aspx
     
    #18
    Ian.M
    Super Member
    • Total Posts : 13268
    • Reward points : 0
    • Joined: 2009/07/23 07:02:40
    • Location: UK
    • Status: offline
    Re: Placing *.inc files to main file create strange problem 2019/11/11 00:12:03 (permalink)
    0
    If you *HAVE* to do a relative computed goto on a PIC18, probably the cleanest way of doing it is to write a subroutine that modifies its return address via the top of stack SFRs: TOSU, TOSH and TOSL.   You can do maths on the TOS SFRs without the immediate execution jump that writing to PCL causes, so its fairly simple to add W to the full return address correctly, (with full byte to byte carry, so absolutely no page boundary issues),  starting with its low byte, without needing any 'scratchpad' RAM, then execute the jump simply by RETURN.
    post edited by Ian.M - 2019/11/11 00:14:52

    --
    NEW USERS: Posting images, links and code - workaround for restrictions.
    I also support http://picforum.ric323.com because this forum is sometimes too broken to use!
    #19
    _pike
    Senior Member
    • Total Posts : 138
    • Reward points : 0
    • Joined: 2012/12/02 11:34:43
    • Location: 0
    • Status: offline
    Re: Placing *.inc files to main file create strange problem 2019/11/18 12:14:35 (permalink)
    0
    Sorry for my late reply.... I would like to thank all for your suggestions!!!
     
    1and0
    As I've said, #including a file in assembly is to insert the content of that file at that position in the including file. That is how files are joined together into one file as in absolute mode.  If you want to let the linker to allocate your files, then you'll have to use relocatable mode; and code each module to account for paging and banking, as you do not know where the linker will place the module.

     
    Pic18f27k42 hasnt pages. So if you are aware of banking issues then you wont face any problems including files that way (as far as i can understand) .  But honestly can we have in assembly libraries where can work on a specific type of mcu? My intentions are to create "libraries" that when i create a new project from scratch ,and want to include different modules, i wont have to re-write code for that module and just call some functions from the library to make it work. I would like an idea of how i can accomplish that.
     
    Regards
    #20
    Page: 12 > Showing page 1 of 2
    Jump to:
    © 2019 APG vNext Commercial Version 4.5