Shop OBEX P1 Docs P2 Docs Learn Events
SX/B includes / arrays — Parallax Forums

SX/B includes / arrays

threepointonethreepointone Posts: 10
edited 2008-02-01 03:57 in General Discussion
I've been working on a relatively big SX/B program the past week, and I encountered a couple of problems:
a) Is there any way to include code snippets into sx/b? I wrote a sort of library for an LCD and a couple of other components, and the file is a bit unmanageable at the moment. "INCLUDE" will only include stuff directly in assembly, without compiling it.

b) Of course, with a program this big, I need arrays. I've started using them, but I've noticed that there's a couple of places where they just don't work. I know that you can't use them as loop variables in for loops, but they seem to also not work if you're making a "custom" for loop (i.e. do, if var = 0 then exit, inc var, loop) without any compiler errors. The behavior becomes really, really strange (my program works, but it does some really strange things with the LCD--this was in a loop for writing characters). I assume that for some reason banking isn't done properly in loops with arrays without returning any compiler errors? Does this also happen with "goto" loops, and does it only apply for counter variables?

Thanks for the help, and sorry if I'm asking anything stupid--I just started working with the SX this week.

Comments

  • BeanBean Posts: 8,129
    edited 2008-01-31 15:18
    Welcome to the forums !

    a) Use LOAD for SX/B files, INCLUDE for ASM files.

    b) Array elements cannot be used for certain things. For example as a FOR...NEXT control variable, or as an index to another array. If you post your code we could probably figure out what you need to do. Banking is all handled by the compiler and you should be able to make a loop using an array element as you describe. Again please post your code and we can help you out.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    www.iElectronicDesigns.com

    ·
  • threepointonethreepointone Posts: 10
    edited 2008-01-31 17:34
    I don't have access to my setup at the moment--I'd rather double check to give a better diagnosis of what works and what doesn't before I post the code (it's really, really long).

    However, I did notice something interesting going on in the assembly listing.
    [noparse][[/noparse]code]
    · 1378· =00000019······ LCD_TempStr·· EQU· 0x19········· ;LCD_TempStr·· Var···· Word
    · 1379· =00000019······ LCD_TempStr_LSB· EQU· LCD_TempStr
    · 1380· =0000001A······ LCD_TempStr_MSB· EQU· LCD_TempStr+1
    · 1381·················
    · 1382· =0000002C······ LCDVars······ EQU· 0x2C········· ;LCDVars·············· Var···· Byte(5)
    · 1383·················
    · 1384· =0000002C······ LCD_Temp1···· EQU· LCDVars+0···· ;LCD_Temp1···· Var···· LCDVars(0)
    · 1385·················
    · 1386· =0000002D······ LCD_TempHex·· EQU· LCDVars+1···· ;LCD_TempHex·· Var···· LCDVars(1)
    · 1387·················
    · 1388· =0000002E······ LCD_TempHexChar· EQU· LCDVars+2· ;LCD_TempHexChar······ Var···· LCDVars(2)
    · 1389·················
    · 1390· =00000030······ LCD_TempCharCnt· EQU· LCDVars+4· ;LCD_TempCharCnt······ Var···· LCDVars(4)
    · 1391·················
    · 1392· =0000002F······ LCD_TempChar· EQU· LCDVars+3···· ;LCD_TempChar· Var···· LCDVars(3)
    · 1393·················
    [noparse][[/noparse]/code]
    The variable that was causing problems, LCD_TempCharCnt, happens to overflow to the next bank in the array. I'm not really sure how that'd mess up with indirect addressing, but it's something interesting to note.

    By the way, I'm running on an SX48.


    here's the actual code that appears to be causing the problem. The problem that occurs is too consistent to describe without all of the code. It might have to do with the I2C bus commands somewhere, as putting pauses in certain places in the main code magically made everything work again (a whole lot slower, of course). Again, changing LCD_TempCharCnt to a global variable fixed everything in the code. Unfortunately, my SX-Key is a bit defective and won't debug anything (I'm doing an RMA after this project is done), so that makes things a bit more difficult to figure out. A lot of the functions require an actual I2C device to be connected, so I can't really do this in SXSim

    [noparse][[/noparse]code]
    ' parameters: character (Byte), # of characters (Byte)
    ' LCD_I2Cxxxx commands are elsewhere in the code
    LCD_DispChar:
    ·LCD_TempChar = __Param1
    ·If __ParamCnt = 1 then
    ··LCD_TempCharCnt = 1
    ·else
    ··LCD_TempCharCnt = __Param2
    ·endif
    ·LCD_I2CStart LCD_DataMode
    ·Do
    ··LCD_I2CSend LCD_TempChar
    ··LCD_TempCharCnt = LCD_TempCharCnt - 1
    ··if LCD_TempCharCnt = 0 then exit
    ·Loop
    ·LCD_I2CStop
    ·Return
    [noparse][[/noparse]/code]
  • threepointonethreepointone Posts: 10
    edited 2008-01-31 21:39
    (edit) Other ideas: could this be some sort of banking issue with the gotos? I wish I had a working debugger! In the main program loop, there's a line that checks the "ready" input that's supposed to go high when the sensor is ready with a measurement. For some reason this line is actually pulled high (changed to an output) somewhere in the code even though it's not referenced anywhere else in the code. Actually, several of the RB port pins are pulled high and set as outputs even though nothing else in the code says it's supposed to. I'm truly stumped--is it something in the I2C code?
    (/edit)
    Alright, I've trimmed down on everything extraneous (there is a lot of code in here that's specific to how the sensor and LCD I use respond using the I2C protocol, just ignore that). I tested it again, and it's completely noticable--when the character count is a byte in an array, the program starts doing strange things (specifically, the measured capacitance will never update even though it's clearly not stuck in some outside loop and will still respond to button presses)



    I've attached a heavily condensed version of the code, and I'm pasting the specific code regions which seem to be the culprits.

    LCD_TempStr Var Word
    LCDVars  Var Byte(5)
    LCD_Temp1 Var LCDVars(0)
    LCD_TempHex Var LCDVars(1)
    LCD_TempHexChar Var LCDVars(2)
    LCD_TempCharCnt Var LCDVars(3) '***** when this is a byte, everything works out fine!
    LCD_TempChar Var LCDVars(4)
    
     
    
    . . .
    
     
    
    LCD_DispChar:
     LCD_TempChar = __Param1
     If __ParamCnt = 1 then
      LCD_TempCharCnt = 1
     else
      LCD_TempCharCnt = __Param2
     endif
     LCD_I2CStart LCD_DataMode
     Do
      LCD_I2CSend LCD_TempChar
      LCD_TempCharCnt = LCD_TempCharCnt - 1
      if LCD_TempCharCnt = 0 then exit
     Loop
     LCD_I2CStop
     Return
    
    



    Sorry if the code's messy/unoptimized; I actually discovered this problem while I was trying to tidy it up and stuff everything I could into the array variable space, as I was running low on RAM before.



    A condensed form of the code is attached--basically, this dispChar subroutine is called by two other high level routines, RetHome (which basically writes spaces to the LCD and returns the cursor) and DispHex, which converts a variable into hex ascii.



    I'm completely stumped at the moment. Although I've been able to fix it, I really want to know why array variables won't work here--I don't see any obvious reasons. I've messed around with the order of the variables (since the variable causing problems just happens to be at the edge of a bank) and it didn't do anything. For some odd reason, adding pauses in the main code that calls all of the LCD writes makes it work (in a really strange manner)--this leads me to think that I've messed something up with my LCD_I2CSend routine and the acknowledgement bit, but I've been looking through the assembly and I can't seem to find anything wrong.



    Thanks for your assistance!

    Post Edited (threepointone) : 1/31/2008 10:32:09 PM GMT
  • threepointonethreepointone Posts: 10
    edited 2008-02-01 03:57
    I've figured out why the code was freezing! I still haven't figured out why using a byte variable for the counter also works, but it seems (at least on the SX48) that the compiler code will change TRIS for the entire port and mess up the directions of some of the pins (in particular, the pin I poll to update the LCD). Putting an "INPUT RDY" in the main program loop fixes it. I'm suspecting something funny with that array variable floating around·and the builtin·I2C routines·(but as far as I can tell none of the built-in I2C commands actually access that built-in array variable directly--it's in an entirely different routine). In some of my tests, I also found some timing inconsistencies, which could have to do with some subtle Read-modify-write problem, but I'm still investigating.

    I've been trying to convert my sensor code to use arrays, and I'm having similar problems. Is there some sort of conflict with using the I2C commands and array variables?

    Post Edited (threepointone) : 2/1/2008 5:56:58 AM GMT
Sign In or Register to comment.