Menu

Detecting SAF or EeProm Programmatically

2025-06-17
2025-06-19
  • c-conversion

    c-conversion - 2025-06-17

    I was trying to use a cheaper device for a design I'm making 50 of. I thought I would replace a 16F18xx with a 16F152xx. It's only a small program so I don't need much program storage.

    I get an error that there is no EeProm capability on the 152xx devices, which is correct, there isn't. I changed all references to SAFRead/SAFWrite and the program compiled. No problem.

    I thought I'd get clever and use some 'IfDef' statements to conditionally compile for devices with either SAF or EeProm but I can't get any of them to work other than specifying the exact chip I'm using.

    I tried:

    #IfDef CHIP_16F15244
        SAFRead (HiAddr+1, EePromWVal)
        SAFRead (HiAddr,   EePromWVal_H)
    #EndIf
    Works as expected, compiling the SAFRead/SAFWrite section
    
    #IfDef Bit(SAFEN) (fails to compile the SAFRead/SAFWrite section)
    #IfDef OPTION(SAFEN) (fails to compile the SAFRead/SAFWrite section)
    #IfDef VAR(SAFEN) (fails to compile the SAFRead/SAFWrite section)
    #IfDef Var(SAF_ROWSIZE_BYTES) (fails to compile the SAFRead/SAFWrite section)
    

    I don't doubt I'm missing something rather obvious, but can't see what I could do to select programmatically to compile either EpRead/EpWrite or SAFRead/SAFWrite.

     

    Last edit: c-conversion 2025-06-17
  • Anobium

    Anobium - 2025-06-17

    Hi,

    Look at PICINFO for the available constants for the chip(s). The ChipData tab in PICInfo show the exposed chip specific constants.

    Here is an analysis and recommendation to resolve.

    /*
                GCBASIC source generated by BLOCKLY.  An Open source code generator.
    
               A GCBASIC source program
    
    */
    // Date:    06/14/2025
    // Version: 0.9b
    // Author:  Evan
    
    #chip 16F15244
    #option explicit
    
    
    Dim EePromWVal, HiAddr as Word
    
    // #IfDef CHIP_16F15244  // GOOD
    // #IfDef Bit(SAFEN) // SAFEN is CONFIG BIT and not exposed.
    // #IfDef OPTION(SAFEN) // OPTION.. maybe this is something we could implement, but not exposed/
    // #IfDef VAR(SAFEN) (fails to compile the SAFRead/SAFWrite section) // VAR is register inspection. So, not valid. May be there is a REGISTER than does have the SAF state
    // #IfDef Var(SAF_ROWSIZE_BYTES) // SAF_ROWSIZE_BYTES is CONSTANT, see next line
    #IF SAF_ROWSIZE_BYTES <> 0
        SAFRead (HiAddr+1, EePromWVal)
        SAFRead (HiAddr,   EePromWVal_H)
    #EndIf
    
    // OR, using PICINFO information which is a lot smarter as this exposed as a PUBLIC constant
    
    #IF ChipSAFMemWords  <> 0
        SAFRead (HiAddr+1, EePromWVal)
        SAFRead (HiAddr,   EePromWVal_H)
    #EndIf
    
     
  • c-conversion

    c-conversion - 2025-06-17

    Many thanks.
    I'd looked in PicInfo, and I'd seen SAFEN (and tried it) I then found SAF_ROWSIZE_BYTES (and tried it too) but hadn't spotted ChipSAFMemWords and so hadn't tried it. Mind you, by then I'd thought I was going in the wrong direction.

    This seems to be working:

    #IfDef ChipSAFMemWords
        SAFRead (HiAddr+1, EePromWVal)
        SAFRead (HiAddr,   EePromWVal_H)
    #EndIf
    

    As is the case with "#IfDef" if the "<> 0" is present at the end of the line, the comparison will always fail.

     
    • Anobium

      Anobium - 2025-06-18

      I have just looked at this again.

      Have a look in the CDF file. This is created by the compiler if you have turned this on in the Preferences.

      This does show the conditional compilation outcome.

      As you correctly say the the CDF shows that #ifdef ChipSAFMemWords <> 0 does fail, where #if ChipSAFMemWords <> 0 does work.

      I think the CDF file has the debug we require.

       
      • c-conversion

        c-conversion - 2025-06-18

        To clarify what you are saying.
        Does #If work as a conditional compile option with additional parameters, as an alternative form of IfDef which has no parameters?

        I had thought your:

        #IF ChipSAFMemWords  <> 0
            SAFRead (HiAddr+1, EePromWVal)
            SAFRead (HiAddr,   EePromWVal_H)
        #EndIf
        

        was a typo, and you'd intended to write:

        #IfDef ChipSAFMemWords
            SAFRead (HiAddr+1, EePromWVal)
            SAFRead (HiAddr,   EePromWVal_H)
        #EndIf
        
         

        Last edit: c-conversion 2025-06-18
        • Anobium

          Anobium - 2025-06-18

          They are different conditional tests. #IFDEF() ( or #IF DEF()) .. does something exist. #IF CONSTANT} =|>|<|<> {value} tests a value.

          These are high level summaries, and, the Help has more tests like OneOf() etc.

           
          • c-conversion

            c-conversion - 2025-06-19

            Thanks for the clarification. I'll read up on #If.

             
  • Anobium

    Anobium - 2025-06-17

    Well done. I really should add a lot more debug to conditional compilation. I will if I find time later this year.

     
  • c-conversion

    c-conversion - 2025-06-19

    To remind me when I'm searching for answers in the future, I'm currently using this code to select automagically use of either SAF or EeProm in the appropriate devices:

    Sub GetWEeprom (HiAddr As Byte, Out EePromWVal As Word)
    'Takes the address of the High Byte and returns
    'a Word made from the HiAddr and the adjacent
    'byte in Eeprom
    
    #If ChipSAFMemWords <> 0
        SAFRead (HiAddr+1, EePromWVal)
        SAFRead (HiAddr,   EePromWVal_H)
    #EndIf
    #If ChipSAFMemWords = 0
        EpRead (HiAddr+1, EePromWVal)
        EpRead (HiAddr,   EePromWVal_H)
    #EndIf
    End Sub
    
     
  • Anobium

    Anobium - 2025-06-19

    Very nice. :-)

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.