|
|
View previous topic :: View next topic |
Author |
Message |
thomasb
Joined: 12 Mar 2005 Posts: 7
|
PIC12x509 CONST Table Read Problems |
Posted: Sat Feb 23, 2008 7:23 pm |
|
|
I have a data table that I want to place near the top of ROM on a PIC12x509. This table will be edited during chip burning, so putting it at a known place is needed.
The table's code is as follows:
#ORG 0x3EF, 0x3F3
BYTE CONST DEF_TABLE[3]={1, 2, 3};
This part works great and the values are created as RETLW, which is what I want.
During run-time, the program needs to read these bytes. So, using the example found in the CCS manual, I do that like this:
pw_home= DEF_TABLE[0];
pw_min = DEF_TABLE[1];
pw_max = DEF_TABLE[2];
When the code is run, the values are not taken from the table. Instead, the optimizer creates these as inline MOVLW's. I tried turning off the optimizer to out-smart it, but that did not help.
So, I changed the code to this:
i = 0;
pw_home= DEF_TABLE[i++];
This creates code that seems to be consistent with the ROM based RETLW reads, but it does not work correctly. Looking at the assembly, it creates this:
022B: MOVF 13,W // Table offset value (i).
022C: INCF 13,F // Post Increment
022D: CALL 000 // RETLW table read, but address is crazy!
022E: MOVWF 08 //
022F: BSF 04.5 // High Ram
0230: MOVWF 11 // Save table read value.
The CALL to 000 causes the program to restart. It does not read the ROM based table.
What in the world am I doing wrong?
BTW, I have CCS PCB C Compiler, Version 3.234. It's an older PCW version.
Thanks! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Feb 23, 2008 7:33 pm |
|
|
Post a complete test program (short) that will compile.
It should have #include and #fuses statements, and a main() and show
all variable declarations. I'll test it later with PCB vs. 3.249. |
|
|
thomasb
Joined: 12 Mar 2005 Posts: 7
|
|
Posted: Sat Feb 23, 2008 10:14 pm |
|
|
Quote: | Post a complete test program (short) that will compile. |
Thanks for any help you can give.
Well, I created a tiny test program (see below) and looked at the list file. The code section that used the variable index into the table is now better, at least from looking at the listing. But the hard coded indexing still is victimized by the optimizer and uses inline code instead of reading the ROM table.
I was surprised to see that it compiled differently in the short test program. I soon found out why. The short program does not cross a code page. A larger program that uses upper ROM causes the problem. I verifed this by #ORG'ing the main function to upper PAGE 1. The code then compiles incorrectly and calls address 000h, just like what I see in my real program.
I tried to use assembly to get around the bug in the compiler, but I just keep banging my head with that conversion. It would be grand if someone had a link to a example 12-bit CCS-C program that used inline assembly to read from RETLW ROM tables. Anyone?
In the meantime, I will try to push the table related code to Page 0 to see if that provides a cheap workaround.
Here is the test program I used to find the compiler bug:
Code: | // *************************************************************************************
// CHIP BURN FUSE NOTICE
// WDT: Enabled
// MCLR: Disabled
// OSCILLATOR: IntRC
// CODE MEMORY: Protected
//
// *************************************************************************************
// External Files
#include <12C509.h>
#fuses INTRC, WDT, PROTECT, NOMCLR
#use FAST_IO(B)
#use Delay(Clock=4000000,RESTART_WDT)
#ZERO_RAM
// ROM TABLE
#ORG 0x3EF, 0x3F3 // Reserve top of code memory for user-edit table
BYTE CONST DEF_TABLE[3]={0x55,0xAA,0x01};
#RESERVE 0x30, 0x31, 0x32
#byte pw_min = 0x30
#byte pw_home = 0x31
#byte pw_max = 0x32
#ORG 0x2EF,0x340 // FORCE USE OF CODE PAGE 1
////////////////////////////////////////////////////////////////////////////////////////////
// MAIN()
//
void main(void) {
int x;
pw_home = 0x00; // Clear the data for easier debugging.
pw_min = 0x00;
pw_max = 0x00;
// This table read method does not work.
pw_home= DEF_TABLE[0]; // Read from table.
pw_min = DEF_TABLE[1];
pw_max = DEF_TABLE[2];
// This table read method works fine if the code is on Page 0.
x = 0;
pw_home= DEF_TABLE[x++];
pw_min = DEF_TABLE[x++];
pw_max = DEF_TABLE[x];
x = pw_home;
x = pw_min;
x = pw_max;
} |
Last edited by thomasb on Sun Feb 24, 2008 11:59 am; edited 1 time in total |
|
|
thomasb
Joined: 12 Mar 2005 Posts: 7
|
|
Posted: Sat Feb 23, 2008 10:50 pm |
|
|
Update:
I found the problem. I was a bad boy when I placed the ROM table at the high end of the code page. I moved it to within the first 255 words on Page-1 and now it works with the variable based index. Too bad the compiler does not issue a warning when the table is out of bounds.
BTW, the hard coded index method still does not read the table; the optimizer changes the code to use inline copied values instead of the real table values.
Case closed, happy ending. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|