LaoMa
Starting Member
- Total Posts : 38
- Reward points : 0
- Joined: 2017/08/01 21:39:42
- Location: 0
- Status: offline
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
|
Aussie Susan
Super Member
- Total Posts : 3810
- 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)
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
|
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)
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"
|
NKurzman
A Guy on the Net
- Total Posts : 19115
- 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)
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.
|
LaoMa
Starting Member
- Total Posts : 38
- 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)
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?
|
LaoMa
Starting Member
- Total Posts : 38
- 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)
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:  , then that was not a problem from the beginning... Thanks again
|
1and0
Access is Denied
- Total Posts : 11770
- 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)
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
|
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)
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"
|
1and0
Access is Denied
- Total Posts : 11770
- 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)
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. ;)
|
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)
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"
|
1and0
Access is Denied
- Total Posts : 11770
- 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)
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.
|
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)
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"
|
1and0
Access is Denied
- Total Posts : 11770
- 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)
Amnesia ;) Nice workaround with the "do nothing" statement.
|
mbrowning
USNA79
- Total Posts : 1857
- 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)
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
|
1and0
Access is Denied
- Total Posts : 11770
- 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)
No more cumbersome than reading from the internal EEPROM. I think the point is to save flash memory, by 50%.
|
Aussie Susan
Super Member
- Total Posts : 3810
- 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)
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
|
1and0
Access is Denied
- Total Posts : 11770
- 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)
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.
|
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)
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"
|
1and0
Access is Denied
- Total Posts : 11770
- 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)
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?
|
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)
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"
|