• AVR Freaks

PIC16F1704 - write 14 bit table constants into ROM

Page: 12 > Showing page 1 of 2
Author
LaoMa
New Member
  • Total Posts : 16
  • Reward points : 0
  • Joined: 2017/08/01 21:39:42
  • Location: 0
  • Status: offline
2018/01/02 20:23:42 (permalink)
0

PIC16F1704 - write 14 bit table constants into ROM

Hello,
I would like to use the full 14 bit capability of the ROM locations to define a lookup table of values to be used in the code.
The value of each data is in the range 0x0000 - 0x3fff (14 bit).
using 2 char or an integer the compiler assigns  2 x 8-bit locations, double space and double read .......
There is a way to instruct the XC8 to save each value in only one location?
Thanks a lot
 
#1

20 Replies Related Threads

    Aussie Susan
    Super Member
    • Total Posts : 3649
    • Reward points : 0
    • Joined: 2008/08/18 22:20:40
    • Location: Melbourne, Australia
    • Status: offline
    Re: PIC16F1704 - write 14 bit table constants into ROM 2018/01/03 18:44:53 (permalink)
    0
    1) What information in Section 10 of the MCU's data sheet (the part that tells you how to read/write/erase the FLASH memory) do you not understand?
    2) I've not used that chip but I would have thought that "Note 1" under Table 3-1 and the references to 128-byes of 'high endurance' ROM (especially in Section 3.2) would tell me that there are 128 locations and you can only access the lower byte
    3) what is the underlying problem that you have that makes you think this is the solution? (I must admit I don't understand exactly what you are talking about with 'double space and double read' but, again, that is not the description of your problem.)
    Susan
    #2
    qɥb
    Monolothic Member
    • Total Posts : 3332
    • Reward points : 0
    • Joined: 2017/09/09 05:07:30
    • Location: Jupiter
    • Status: offline
    Re: PIC16F1704 - write 14 bit table constants into ROM 2018/01/03 19:06:43 (permalink)
    0
    You have to use inline assembly code to do it.
     
    extern const char bitmap[]; //required to access ASM data

    #asm
    PSECT strings,class=CODE,local,delta=2
    GLOBAL _bitmap
    _bitmap
        DW      0x3FFF  ; first entry
        DW      0x1234  ; second entry
    #endasm



    And you can use something like this to fetch each word
    WORD getbits(BYTE chr)
    {
        EEADR = (WORD)bitmap;   //get address of table, suppress warning
        EEADR += chr;   //add in offset. This way generates smallest code
        EECON1 = 0b00000000;    //clear CFGS bit
        EECON1bits.RD=1;    //start read
        EECON1bits.RD=0;    //dummy instruction (avoid NOP))
        EECON1bits.RD=0;    //dummy instruction (avoid NOP))
        return EEDAT;   //read data
    }



     Edit: There's a small bug in the getbits() function for some PICs. See post#18.
    post edited by qɥb - 2018/02/13 22:51:01

    This forum is mis-configured so it only works correctly if you access it via https protocol.
    The Microchip website links to it using http protocol. Will they ever catch on?
    PicForum "it just works"
    #3
    NKurzman
    A Guy on the Net
    • Total Posts : 18179
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: offline
    Re: PIC16F1704 - write 14 bit table constants into ROM 2018/01/03 19:09:51 (permalink)
    0
    C will not do it for you automaticly.  You need to it using the Flash API.
    If you want it in your code as a table, you may need some ASM to do it.
    #4
    LaoMa
    New Member
    • Total Posts : 16
    • Reward points : 0
    • Joined: 2017/08/01 21:39:42
    • Location: 0
    • Status: offline
    Re: PIC16F1704 - write 14 bit table constants into ROM 2018/01/03 19:10:04 (permalink)
    0
    Thank Susan for reply.
     
    I have to admit that my problem could have not been explained fully, I will do now, I hope.
     
    The ROM memory is organized in 14-bit words, like stated into the DS of 1704.
    The FLASH_WriteWord and FLASH_ReadWord functions from MCC library do exactly that, then by that is possible to write and read the full 14 bits of every ROM location.
    My program needs a lookup table with 101 couple of values than when I declare "const char MyTable [] = { 0. 1, ... 201, 202};" the compiler allocates 202 14-bit locations in ROM. Similar if I compact the couple values in one uint16_t and declare "const uint16_t MyTable [] = { 0. 1, ... 100, 101};" the compiler allocates the same 202 14-bit locations.
    I suppose this is clear now.
    The values I use in each couple have different accuracy, 1st-char is 8-bit length, 2nd-char just 5-bit length then I can use a 16-bit word "uint16_t i=((1st-char <<6) | (2nd-char & 0x3f));" to save all necessary bits into the 14-bit ROM word.
    The question is now:
    how can I declare a constant table of words like above in a way the compiler save only one 14-bit word?
    Maybe using #asm directive and ASM instruction "DW" (?) it can be done, but what is the correct way to do it?
    #5
    LaoMa
    New Member
    • Total Posts : 16
    • Reward points : 0
    • Joined: 2017/08/01 21:39:42
    • Location: 0
    • Status: offline
    Re: PIC16F1704 - write 14 bit table constants into ROM 2018/01/03 19:20:18 (permalink)
    0
    Thanks to both qɥb and NKurzman, I knew that I have to use assembly and DW, but I have not known how to address correctly the ROM in this chip.
     
    To read and, possibly, to save the values during runtime, I use the FLASH_WriteWord (and .. ReadWord) supplied by the MCC ....Smile: Smile, then that was not a problem from the beginning...
    Thanks again
     
    #6
    1and0
    Access is Denied
    • Total Posts : 10219
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: PIC16F1704 - write 14 bit table constants into ROM 2018/01/03 23:45:33 (permalink)
    0
    qɥb

        EECON1bits.RD=0;    //dummy instruction (avoid NOP))
        EECON1bits.RD=0;    //dummy instruction (avoid NOP))


    Please elaborate on this.  Why avoid NOP?
     
    By the way, OP PIC device uses PMCONx, PMDATx, and PMADRx.
     
    post edited by 1and0 - 2018/01/03 23:48:07
    #7
    qɥb
    Monolothic Member
    • Total Posts : 3332
    • Reward points : 0
    • Joined: 2017/09/09 05:07:30
    • Location: Jupiter
    • Status: offline
    Re: PIC16F1704 - write 14 bit table constants into ROM 2018/01/04 01:40:14 (permalink)
    0
    1and0
    Please elaborate on this.  Why avoid NOP?

    NOP() destroys the optimiser's knowledge of the current bank, so even in PRO mode it will always put a bank select operation, even if the correct bank is already selected.
    Replacing the NOPs with "do nothing" instructions in the correct bank avoids this. :)
     

    By the way, OP PIC device uses PMCONx, PMDATx, and PMADRx.

    The original code was written for a PIC16F1518, which also uses PMCONx etc.
    I had only just converted the code to run on a PIC16F1829, which uses the older EECONx style names.
     
    FYI, here is the disassembly in the LST file compiling the original code for a PIC16F1518 in PRO mode
      2588                           ;psect for function _getbits
      2589  02B2                     _getbits:    
      2590                           
      2591                           ;incstack = 0
      2592                           ; Regs used in _getbits: [wreg+status,2]
      2593                           ;getbits@chr stored from wreg
      2594  02B2  00F7                   movwf    getbits@chr
      2595                           
      2596                           ;stdisp.c: 238: PMADR = (unsigned int)bitmap;
      2597  02B3  3085                   movlw    high (_bitmap| (0+32768))
      2598  02B4  0023                   movlb    3    ; select bank3
      2599  02B5  0092                   movwf    18    ;volatile
      2600  02B6  30B0                   movlw    low (_bitmap| (0+32768))
      2601  02B7  0091                   movwf    17    ;volatile
      2602                           
      2603                           ;stdisp.c: 239: PMADR += chr;
      2604  02B8  0877                   movf    getbits@chr,w
      2605  02B9  0791                   addwf    17,f    ;volatile
      2606  02BA  1803                   skipnc
      2607  02BB  0A92                   incf    18,f    ;volatile
      2608                           
      2609                           ;stdisp.c: 240: PMCON1 = 0b00000000;
      2610  02BC  0195                   clrf    21    ;volatile
      2611                           
      2612                           ;stdisp.c: 241: PMCON1bits.RD=1;
      2613  02BD  1415                   bsf    21,0    ;volatile
      2614                           
      2615                           ;stdisp.c: 242: PMCON1bits.RD=0;
      2616  02BE  1015                   bcf    21,0    ;volatile
      2617                           
      2618                           ;stdisp.c: 243: PMCON1bits.RD=0;
      2619  02BF  1015                   bcf    21,0    ;volatile
      2620                           
      2621                           ;stdisp.c: 244: return PMDAT;
      Unnecessary "MOVLB 3" here if NOPs used
      2622  02C0  0814                   movf    20,w    ;volatile
      2623  02C1  00F5                   movwf    ?_getbits+1
      2624  02C2  0813                   movf    19,w    ;volatile
      2625  02C3  00F4                   movwf    ?_getbits
      2626  02C4  0008                   return

    post edited by qɥb - 2018/01/04 01:41:44

    This forum is mis-configured so it only works correctly if you access it via https protocol.
    The Microchip website links to it using http protocol. Will they ever catch on?
    PicForum "it just works"
    #8
    1and0
    Access is Denied
    • Total Posts : 10219
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: PIC16F1704 - write 14 bit table constants into ROM 2018/01/04 03:13:44 (permalink)
    0
    qɥb
    1and0
    Please elaborate on this.  Why avoid NOP?

    NOP() destroys the optimiser's knowledge of the current bank, so even in PRO mode it will always put a bank select operation, even if the correct bank is already selected.
    Replacing the NOPs with "do nothing" instructions in the correct bank avoids this. :)

    Thanks.  That's interesting; so assembly destroys the optimizer. ;)
    #9
    qɥb
    Monolothic Member
    • Total Posts : 3332
    • Reward points : 0
    • Joined: 2017/09/09 05:07:30
    • Location: Jupiter
    • Status: offline
    Re: PIC16F1704 - write 14 bit table constants into ROM 2018/01/04 03:22:36 (permalink)
    0
    Presumably NOP() is treated the same as inline assembly.
    The user guide states:

    When using in-line assembler code, it is extremely important that you do not interact
    with compiler-generated code. The code generator cannot scan the assembler code for
    register usage; so, it will remain unaware if registers are clobbered or used by the
    assembly code. However, the compiler will reset all bank tracking once it encounters
    in-line assembly, so any SFRs or bits within SFRs that specify the current bank do not
    need to be preserved by in-line assembly.

    A direct consequence of that is that it will force a Banks Select instruction straight after the inline assembly, even if the correct bank is still selected. It doesn't treat NOP differently to any other assembly code.

    This forum is mis-configured so it only works correctly if you access it via https protocol.
    The Microchip website links to it using http protocol. Will they ever catch on?
    PicForum "it just works"
    #10
    1and0
    Access is Denied
    • Total Posts : 10219
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: PIC16F1704 - write 14 bit table constants into ROM 2018/01/04 04:51:41 (permalink)
    0
    I somehow recall NOP() to be
    #define NOP() asm("nop")

    but in the pic.h file it actually is a function inlined intrinsically by the compiler:
    // function version of nop
    #pragma intrinsic(__nop)
    extern void __nop(void);
    #define NOP() __nop()

    That is, this function has no corresponding source code and is expanded by the code generator during compilation.
    #11
    qɥb
    Monolothic Member
    • Total Posts : 3332
    • Reward points : 0
    • Joined: 2017/09/09 05:07:30
    • Location: Jupiter
    • Status: offline
    Re: PIC16F1704 - write 14 bit table constants into ROM 2018/01/04 04:57:34 (permalink)
    0
    I found the same.
    Nevertheless, it still makes the optimiser forget what bank is selected.

    This forum is mis-configured so it only works correctly if you access it via https protocol.
    The Microchip website links to it using http protocol. Will they ever catch on?
    PicForum "it just works"
    #12
    1and0
    Access is Denied
    • Total Posts : 10219
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: PIC16F1704 - write 14 bit table constants into ROM 2018/01/04 05:19:34 (permalink)
    0
    Amnesia ;)  Nice workaround with the "do nothing" statement.
     
    #13
    mbrowning
    USNA79
    • Total Posts : 1582
    • Reward points : 0
    • Joined: 2005/03/16 14:32:56
    • Location: Melbourne, FL
    • Status: offline
    Re: PIC16F1704 - write 14 bit table constants into ROM 2018/01/04 05:51:27 (permalink)
    0
    All program flash (lower 8b) is readable through indirect addressing just like RAM. Cumbersome code to access 14b words may add more code and time than is being saved. This seems pointless
    #14
    1and0
    Access is Denied
    • Total Posts : 10219
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: PIC16F1704 - write 14 bit table constants into ROM 2018/01/04 06:02:04 (permalink)
    0
    No more cumbersome than reading from the internal EEPROM.  I think the point is to save flash memory, by 50%.
    #15
    Aussie Susan
    Super Member
    • Total Posts : 3649
    • Reward points : 0
    • Joined: 2008/08/18 22:20:40
    • Location: Melbourne, Australia
    • Status: offline
    Re: PIC16F1704 - write 14 bit table constants into ROM 2018/01/04 18:34:20 (permalink)
    0
    LaoMa
    I have to admit that my problem could have not been explained fully, I will do now, I hope.

    You have missed the point of my question: "3) what is the underlying problem that you have that makes you think this is the solution?".
    As others have shown you above, this is a very difficult thing to do so why are you even trying!
    I suspect that you are wanting to use some constants that are larger than 1 byte but, for some reason, you are not happy with simply declaring them as "const" and letting the compiler do all the work for you.
    Basically this seems to be to be an "X-Y" problem (http://xyproblem.info/) and I'm trying to find out what you are really trying to do as I suspect there is a much easier way.
    Susna
    #16
    1and0
    Access is Denied
    • Total Posts : 10219
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: PIC16F1704 - write 14 bit table constants into ROM 2018/01/05 08:21:49 (permalink)
    +1 (1)
    Com'on lady and gent. How is this "a very difficult thing"? Because it's assembly? Qub has already posted all the code that is necessary to accomplish this task in Post #3.
     
    Qub's code performs the same task as the following C code:
    const uint16_t bitmap[] = { 0x3FFF, 0x1234 };

    and reading this array normally like this
    uint16_t foo = bitmap[i];

    is by calling the function given also by Qub
    uint16_t foo = getbits(i);

     
    Now, how difficult is that? Frankly, I think it takes about the same amount of time and code to read an array of 16-bit data from flash memory via FSR/MOVIW. But OP needs only 14-bit wide data, which can fit in one word of flash memory; whereas the const int array takes two flash memory words for each data. For large array, such as LUT, that adds up to a lot of flash memory comparing to the assembly DW method.
    #17
    qɥb
    Monolothic Member
    • Total Posts : 3332
    • Reward points : 0
    • Joined: 2017/09/09 05:07:30
    • Location: Jupiter
    • Status: offline
    Re: PIC16F1704 - write 14 bit table constants into ROM 2018/01/05 17:01:09 (permalink)
    0
    There's a bug in my conversion from PMCON1 to EECON1.
    There's no bit 7 implemented in PMCON1, and I set it to zero.
    Bit 7 of EECON1 is "EEPGD", which must be "1" to select FLASH, otherwise it accesses EEPROM in PICs that have it.
    So:
    WORD getbits(BYTE chr)
    {
        EEADR = (WORD)bitmap;   //get address of table, suppress warning
        EEADR += chr;   //add in offset. This way generates smallest code
        EECON1 = 0b10000000;    //clear CFGS bit, set EEPGD bit to access FLASH
        EECON1bits.RD=1;    //start read
        EECON1bits.RD=0;    //dummy instruction (avoid NOP))
        EECON1bits.RD=0;    //dummy instruction (avoid NOP))
        return EEDAT;   //read data
    }

    It doesn't hurt to set that bit in PMCON1 too.

    This forum is mis-configured so it only works correctly if you access it via https protocol.
    The Microchip website links to it using http protocol. Will they ever catch on?
    PicForum "it just works"
    #18
    1and0
    Access is Denied
    • Total Posts : 10219
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: PIC16F1704 - write 14 bit table constants into ROM 2018/01/05 18:04:42 (permalink)
    0
    Regarding the EEPGD:CFGS bits,
     
    00 accesses the data EEPROM memory
    01 accesses ???
    10 accesses the Flash memory
    11 accesses the Config, User ID, and DevID
     
    but what does 01 access? or is it accessed the same as 11?
    #19
    qɥb
    Monolothic Member
    • Total Posts : 3332
    • Reward points : 0
    • Joined: 2017/09/09 05:07:30
    • Location: Jupiter
    • Status: offline
    Re: PIC16F1704 - write 14 bit table constants into ROM 2018/01/05 18:19:53 (permalink)
    0
    I suspect if CFGS is 1 then EEPGD is don't care.
    The comments on the LWLO and FREE bits seems to support this.
    (I'm looking at the PIC1F1829 datasheet.)

    This forum is mis-configured so it only works correctly if you access it via https protocol.
    The Microchip website links to it using http protocol. Will they ever catch on?
    PicForum "it just works"
    #20
    Page: 12 > Showing page 1 of 2
    Jump to:
    © 2020 APG vNext Commercial Version 4.5