The CCS compiler for mid-range PICs seems to fail with constant lookup tables that span more than 256 bytes. Here is an example for the PIC 16C73B: const int16 PTable[] = {1,2,3... //256 16-bit entries, compiles to: 0059: BCF 0A.0 005A: BCF 0A.1 005B: BCF 0A.2 ;clearing low 3 bits of PCLATH 005C: ADDLW 60 ;add index to table base address 005D: BTFSC 03.0 ;check for carry from previous addition 005E: INCF 0A,F ;handle crossing one page boundary 005F: MOVWF 02 ;computed goto by setting PC from PCL and PCLATH 0060: RETLW 01 0061: RETLW 00 ;PTable[0] = 0001 0062: RETLW 02 0063: RETLW 00 ;PTable[1] = 0002 0064: RETLW 03 0065: RETLW 00 ;PTable[2] = 0003 As you can see, the table access code only handles crossing one page boundary. But if PTable has more than 128 elements, there will be at least two page boundaries to cross. The code that calls this access function just loads the index times two into the w register and calls 0059. No provision is made for overflow in this shift, even if the index is an int16. I don't mind doing my own #ASM version of table lookup, but I can't find out how to take the code address as a literal in CCS in-line assembler, so I am sort of stumped. -Robert Scott Ypsilanti, Michigan (Reply through this forum, not by direct e-mail to me, as automatic reply address is fake.)
CCS Compiler and Const Lookup Table
Started by ●November 17, 2004
Reply by ●November 17, 20042004-11-17
Robert Scott <no-one@dont-mail-me.com> wrote: Robert, Post this to their forum on their pages, they tend to reply pretty quickly to error posts - You could also get solutions that other users have come up with there. It is a pretty active forum. DLC : The CCS compiler for mid-range PICs seems to fail with constant lookup : tables that span more than 256 bytes. Here is an example for the PIC : 16C73B: : const int16 PTable[] = {1,2,3... //256 16-bit entries, compiles to: : 0059: BCF 0A.0 : 005A: BCF 0A.1 : 005B: BCF 0A.2 ;clearing low 3 bits of PCLATH : 005C: ADDLW 60 ;add index to table base address : 005D: BTFSC 03.0 ;check for carry from previous addition : 005E: INCF 0A,F ;handle crossing one page boundary : 005F: MOVWF 02 ;computed goto by setting PC from PCL and PCLATH : 0060: RETLW 01 : 0061: RETLW 00 ;PTable[0] = 0001 : 0062: RETLW 02 : 0063: RETLW 00 ;PTable[1] = 0002 : 0064: RETLW 03 : 0065: RETLW 00 ;PTable[2] = 0003 : As you can see, the table access code only handles crossing one page : boundary. But if PTable has more than 128 elements, there will be at : least two page boundaries to cross. The code that calls this access : function just loads the index times two into the w register and calls : 0059. No provision is made for overflow in this shift, even if the : index is an int16. : I don't mind doing my own #ASM version of table lookup, but I can't : find out how to take the code address as a literal in CCS in-line : assembler, so I am sort of stumped. : -Robert Scott : Ypsilanti, Michigan : (Reply through this forum, not by direct e-mail to me, as automatic reply address is fake.) -- ============================================================================ * Dennis Clark dlc@frii.com www.techtoystoday.com * * "Programming and Customizing the OOPic Microcontroller" Mcgraw-Hill 2003 * ============================================================================
Reply by ●November 17, 20042004-11-17
On 17 Nov 2004 16:05:01 GMT, Dennis Clark <dlc@io.frii.com> wrote:> Post this to their forum on their pages, they tend to reply pretty >quickly to error posts - You could also get solutions that other users >have come up with there. It is a pretty active forum.Thanks. I didn't know there was such a forum. Now that I have looked at it, I see that my complaint is a known restriction of constant lookup tables in ROM. I will have to segment my table into smaller separate tables. -Robert Scott Ypsilanti, Michigan (Reply through this forum, not by direct e-mail to me, as automatic reply address is fake.)
Reply by ●November 17, 20042004-11-17
Robert Scott wrote:> > The CCS compiler for mid-range PICs seems to fail with constant lookup > tables that span more than 256 bytes.Hmmm, you've found an interesting inconsistency in the compiler. The current version restricts the declared dimension on a const array to 256 bytes (see Subscript Out Of Range error message in documentation). In your case, that would be const int16 PTable[128]. In that case there could only be a carry of 1 when calculating the jump address. In your case, since you omitted the explicit declaration and let the compiler count the entries, it lets you declare a larger array without error, which is a bug.> Here is an example for the PIC > 16C73B: > > const int16 PTable[] = {1,2,3... //256 16-bit entries, compiles to: > > 0059: BCF 0A.0 > 005A: BCF 0A.1 > 005B: BCF 0A.2 ;clearing low 3 bits of PCLATH > 005C: ADDLW 60 ;add index to table base address > 005D: BTFSC 03.0 ;check for carry from previous addition > 005E: INCF 0A,F ;handle crossing one page boundary > 005F: MOVWF 02 ;computed goto by setting PC from PCL and PCLATH > 0060: RETLW 01 > 0061: RETLW 00 ;PTable[0] = 0001 > 0062: RETLW 02 > 0063: RETLW 00 ;PTable[1] = 0002 > 0064: RETLW 03 > 0065: RETLW 00 ;PTable[2] = 0003 > > As you can see, the table access code only handles crossing one page > boundary.The 256 byte limit made more sense for the smaller parts, but probably should be eliminated now. As a work-around, you can split the const array unto multiple arrays, each 256 bytes or less and write an access function to choose the proper array. I am forwarding a copy of this response to CCS. Watch for an update soon, and hope that it is extending the range of const arrays rather than enforcing the current limit on implicit length declaration. Updates might add the error first, then raise the limit on a later release, though. Thad