Menu

NO FAULT FOUND: Reading second table fails

Help
2024-04-12
2024-04-15
1 2 > >> (Page 1 of 2)
  • Manfred Mornhinweg

    RESOLVED - the root causes was the programmer, see the later thread

    Hi all,
    I'm close to turning crazy trying to use large tables.
    I need to use a lookup table containing 6400 word values, on a PIC16F1788, which has 16 kilowords of program memory. After reading in the help file that up to 10,000 values are OK, I didn't expect trouble, considering that the program proper is small (less than 1 kilowords). After defining the table, compilation failed silently, and no hex file was created. I tried shortening the table for testing, and at 4000 values I did get at least an error message (program to big, subroutine to big, something it that line). At a table size of 2000 values it works, but of course that's too little for my needs.
    I turned to the forum, searching for messages about this problem, and learned that the data page size of this PIC is limited to 2048 words, and that there is some small overhead in the tables, so it makes sense that 2000 value tables work, and much larger ones don't. I also saw that word tables are divided into two byte tables, on separate pages.
    So I split up my table into four tables. The first three hold 2000 values each, while the fourth table holds the remaining 400 values. I modified my code to select which table to access, and read from it.

    And the PIC went totally crazy, doing random nonsense, ending up in a small LED flasher loop which I have in my program, despite the fact that the only call to this loop had been commented out! I assume that the program counter got loaded with nonsense. Also the flashing was at half the normal speed, which I assume means that the PIC's clock speed selection was overwritten.

    For further testing, I modified my program to always read from the first table, and commented out the other three tables. All worked as expected.

    Then I included the second table, and made my program read from the first and the second. The PIC went crazy.

    Then I modified it again to read only from the first table, but with the second table present. To make the compiler include the second table, I included a line that reads from it, but that never gets executed. All worked as expected.

    So I have to conclude that there is a bug in the compiler, so that when having more than one large tables, reading from the second table causes the poor PIC to get lost in space (and in its memory map).

    The compiler version I'm using is :
    2024.2.7 (Windows 64 bit) : Build 1332

    Searching in the forum, I see that apparently many people have trouble with large tables, but I didn't find any message giving a solution. There is at least one post relating table reading trouble to interrupt routines, but I'm not using any interrupt in my program.

    I come from PicBasic Pro. In that language I used this sort of tables by directly putting the table data in program memory using DATA statements, and then directly reading out the memory positions. It always worked well, and I hoped that the Table and ReadTable would provide the same functionality in GC Basic. Unfortunately PicBasic Pro doesn't support the PIC I'm using now, which forced me to move to GC Basic. Everything else in GC Basic so far has worked well for me, except for those darn tables!

    Is this a known and understood problem? Is there a fix, or a workaround? Or any way to directly write data into the program memory, and read it out from the program, just like in PBP? Or is it more likely a bug in my code?

    The program is attached.

     

    Last edit: Anobium 2024-04-15
  • Anobium

    Anobium - 2024-04-12

    I would have to refer to Hugh the originator of the compiler but for a 16F any table would be limited to the the page size on a 16F, so, ~2000 elements. So, that makes sense with your experience.

    This is not an issue that I was aware of. That does not deny the posts ( they may very old, or, misinformed ) and the the Help may be incorrect for this constraint.


    An easy fix.. change to an 18F.

    But, as I cannot test this, for at least two weeks, can you help?

    Please read the table data and send to a serial terminal ( so no PSMCx or ADRESx register read/write). Does the table operation work? ( The ASM looks correct, so, I am puzzled).


    If you can share any posts before 2021 that may help. Share the URLs.


    Summary. I am not aware of this issue, and, we should resolve.

     
  • Manfred Mornhinweg

    Changing to an 18F isn't a good option for me. I chose this very specific PIC because it has the PSMC hardware in. And I live pretty much at the end of the world, so that any PIC I buy is an import order with overhead cost and a long waiting time. Also it just seems a bad choice to use a more expensive PIC because a bug in the compiler prevents using the less expensive one!

    Also I don't see much use in doing the effort of setting up a serial terminal and writing the read values to a file. I have a test circuit set up, monitoring the output of the PSMC on an oscilloscope, while providing the analog inputs implemented so far. I can easily see on the scope screen that the first 2000 value table reads perfectly, with all values correct, and that at the first attempt to read from the second table the program goes totally nuts. From there on, the main loop no longer gets processed at all.

    I did several tests, by enabling and disabling the various tables and the instructions that read from them, and looking both at the hex file and the actual behavior of the PIC. I can see that the Table instruction writes the three 2000 value tables into the memory starting at the beginning of page 2, while the 400 value table gets written into pages 0 and 1 intermingled with the program. What fails is the ReadTable instruction, as soon as I attempt to read from any table that isn't the first one. I can have all four tables loaded into the PIC, and the program works fine as long as I read only from the first one, but crashes as soon as I attempt to read from any other table. It crashes even if I did not read from the first table before attempting to read from another.

    Maybe, just maybe, the problem might be this: I see that the Table statements write the low bytes of all word tables continuously starting from position 4096, spanning page 2 and page 3, then write the high bytes continuously starting at position 8192, also spanning two pages. So the first table ends up entirely in one page, while the second table begins in the last words of that same page, and continues into the next page! So the second table does not satisfy the requirement of being all in a single page.

    So, the Table command is writing the tables in 4 kiloword pages, while this PICs memory is divided into 2 kiloword pages. If the ReadTable instruction cannot span 2 kiloword page boundaries, that could be the bug!

    I'm attaching the hex file, that shows how the table data appears in 4 kiloword blocks, with a few empty words (FFFF) at the end of each block, accounting for the fact that my 2000 value tables don't completely fill a 2048 word page.

    I will try to work around this problem by trying to use the ProgramRead instruction instead, and putting my values into memory using #asmraw, then an ORG 2048 followed by a long list of DATA statements. If that works, it should actually be a better solution in my application, given that the values of my table all fit in 14 bits, but not in 8. So I would save half of the space, allowing a larger table, and thus a finer resolution in the gain control of my project.

    Since this is the first "serious" program I write in GCB, it's all new terrain for me, what works and what doesn't.

     
  • Manfred Mornhinweg

    Oops, apparently the attachment got deleted by Sourceforge's spambot protection... Trying again...

     
  • Manfred Mornhinweg

    Mistake correction: The blocks into which the Table statement puts the data are actually 2 kilowords long. So there is no page limit trespassing. I was confused by the PIC programmer counting the memory in bytes rather than 14-bit words.

    So the Table statement seems to work correctly, and the problem must be in the ReadTable statement.

    My attempt to put the data words directly into memory and then use ProgramRead so far doesn't have success. I can indeed put the data in memory using assembly dw statements, but so far I cannot control where I put them! The ORG statement doesn't work, instead it generates several error reports. Placing ORG 8192 before my dw list, I get:

    Error: GCASM:Bad ORG overwriting location 0x800
    Error: GCASM:Bad ORG overwriting location 0x1000
    Error: GCASM:Bad ORG overwriting location 0x1800
    Error: GCASM:Bad ORG overwriting location 0x2000
    Error: GCASM:Bad ORG overwriting location 0x2800
    Error: GCASM:Bad ORG overwriting location 0x3000

    But my ORG and list of dw's can't be overwriting anything! Because there is nothing at location 8192 (0x2000), and I'm not even trying to write data to any of the other page starts mentioned.

    Without an ORG, GCB embeds my data list in page 0, along with all the code, after the main program and before the subroutines. If my data list is long enough that the data plus all the code exceeds 2 kilowords, again I get error reports. Instead a short data list is tolerated, but I cannot attempt to read from it, because I don't know at what exact address it landed.

    It's really frustrating! Maybe I have to go back to Assembler programming, using Microchip's tools. But that feels soooooo old! Last time I programmed anything in Assembler was in the early 1990's. And it wasn't a PIC, but an 8039!

     
  • Anobium

    Anobium - 2024-04-12

    If I can advise, and, you help we can resolve.

    Do the serial test. I want a test dataset. Start at 0 thru 1999 for table1 ans then 2000 thru 3999 for the second table. Does this get read properly? Having a dataset I work with is critical. I will vever have the same test rig as yourself.

    ORG will not work as I have not implemented.


    I know this is not a page handling issue as I compiled into PICAS and the result was good. PICAS does robust page checking.

     
  • Manfred Mornhinweg

    OK about the ORG.

    About the test, just to confirm, because I'm not sure I'm understanding correctly. What you mean is that I should put a little loop at the beginning of my program, that reads out all the data values of the two tables, sends it out of the PIC through a hardware or software UART, interfacing the pin to the PC and capturing the data with a terminal program? I can of course do that, I just have to find an USB to serial converter and wire it up. Before doing that, I would like to know if actually that's what you mean!

    There is one more thing that caught my attention in your post: Read out positions 2000 to 3999 in the second table? Is that correct? It only has 2000 items, numbered 1 to 2000, plus the table length as item 0. So I thought that I have to read each of my tables starting from 1 or from 0!

    I'm pretty sure that I misunderstood something, I just don't know what!

     
    • Anobium

      Anobium - 2024-04-13

      Great questions to clarify the test program.

      Create a new program. I want to ensure we are looking only at the table functionality.
      Table 1 -range 0 to 1999
      Table 2 -range 2000 to 3999
      Read item 0 and show this value ( this should be the size of the table )
      Loop through the two tables from item 1 to show the results on the terminal.

      What I am trying to confirm: Read ops are correct for each table and there is no cross table reading.

      So, keep this program focused on the table operations, plus some serial support.

      Evan


      Re a workaround.

      Adding ORG is at least 4 weeks aways. I have a backlog of work todo. But, I should add ORG at some point.

      Or, you could merge the ASM generated by GCBASIC with another ASM that has all the table data at the Page/Adrress then use PROGREAD. Then, compile using MPASM or PICAS. This is essential an ORG workaround.

      However, the easiest... fix the root cause of the current table read issue.

       
  • Anobium

    Anobium - 2024-04-13

    Please see attached my example.

    Note - this is for your chip. It is untested but should show the results.

    I think you will get the correct results looking at the ASM. You should get two columns of data that are 2k difference. However, testing on real silicon is the real test and I am probably wrong and it will fail.

    If it fails, reduce the RANGE and make the tables smaller like 1000, 1500, 1750 etc. ( Change the range constant to suit). What I am looking for is some point where the table reads go wrong. :-(

     

    Last edit: Anobium 2024-04-13
  • Manfred Mornhinweg

    Well, your attachment was deleted by Sourceforge, I guess...

    No problem. I just wrote the little test program. I will try to attach both the program and the serial data captured.

    As you can see, the program starts correctly (with some rubbish characters during power-up), correctly reads the size of the first table, than immediately crashes and restarts while trying to read the size of the second table!

    It's interesting to note that every so many restarts, it does NOT EVEN read the size of table 1! Which probably means that it's not causing a PIC reset, but simply jumping to a random position in the memory map, which increments from cycle to cycle.

    I will do more tests now.

    Hmm... the stupid spambot protection of Sourceforge isn't allowing me to post. Trying now attaching just one file.

     
  • Manfred Mornhinweg

    And the output file.

     
  • Manfred Mornhinweg

    Second test: I modified the program to first read and send the first table, then the second one. This is the changed code:

    for count=0 to 2000
    readtable table1,count,value1
    hserprint value1
    hserprintcrlf
    next
    for count=0 to 2000
    readtable table2,count,value2
    hserprint value2
    hserprintcrlf
    next

    The program reads and sends the first table perfectly, but when trying to read element 0 of the second table, it crashes and restarts. Serial capture attached.

     
  • Manfred Mornhinweg

    Third test: Reading from teh second table first:

    for count=0 to 2000
    readtable table2,count,value2
    hserprint value2
    hserprintcrlf
    next
    for count=0 to 2000
    readtable table1,count,value1
    hserprint value1
    hserprintcrlf
    next

    It fails immediately when trying to read the second table. Output attached.

     
  • Manfred Mornhinweg

    Next test: I shortened each table to 1000 elements, and made my loops read elements 0 to 1000. It works perfectly.

     
  • Manfred Mornhinweg

    Next test: I increased each table to 1030 elements. The idea was to just exceed one memory page of total table size. It works perfectly.

     

    Last edit: Manfred Mornhinweg 2024-04-13
  • Manfred Mornhinweg

    With 1980 elements per table, it fails. Crashes when trying to read the size of table 2. I selected that number to leave a little more headroom per memory page.

    Instead of posting log files, I will now find out at what exact size it fails.

     
  • Manfred Mornhinweg

    The results are in: The magic number is 1864 elements. With two tables of 1864 elements each, it works fine. Instead with two tables of 1865 elements each, the program crashes while trying to begin reading table 2.

    More tests to follow!

     
  • Manfred Mornhinweg

    With 1865 elements in table 1, and 1864 in table 2, it works.
    With 1864 in table 1 and 1865 in table 2, it also works.
    With 1865 in each table, it fails.
    Looks like a limit on total number of elements. With check that.

     
  • Manfred Mornhinweg

    I keep making interesting findings. When I set table 1 to 2000 elements, then I get the following results according to the number of elements in table 2:

    1729 works fine.
    1730 works fine.
    1900 crashes when beginning to read the second table.
    1800 results in the program not starting at all, no output from the serial port!!! Not even the title line!
    1750 works fine.

    I give up! Tell me what other test I should do.

     
  • Manfred Mornhinweg

    Just another random test: I defined 4 tables of 1000 elements each. Tables 1, 2 and 3 read correctly, then the program crashes when trying to begin reading table 4.

    It makes no sense to me. I hope it will make some sense to you!

    Anyway for my application, which requires values no bigger than 1600, it makes more sense to use one 14-bit word per value. I will try if ProgramRead works well. If it does, I can edit my hex files to put the data block in. Of course it's a nuisance having to run each hex file through that editing process, during the many iterations of program development and testing. Since the assembler dw instruction works well in GCB, it would only be necessary to make ORG work too, to be able to put data directly into memory through GCB using dw.

    I would love a high-level sentence like:

    DATA 2048 'insert my data starting at memory location 2048
    2345, 1284, 16383, 45, 12 '14 bit words
    6666, 555, 1788
    END DATA

     
  • Anobium

    Anobium - 2024-04-13

    Good results. These tell me where to look.

    I think this could be the optimiser moving code though the pages ( on 16f only ) and some overflow is happening in the allocation of the program. I can compare the ASM to see what is happening.

    Would it be too much to ask for you to try the conditions using MPASM as the linker/compiler? This will tell me the ASM is valid for each run.

    Post the GCB and ASM for each test. Give each test a reasonable name, so, I can understand.


    I have an idea to workaround. I need time. Check back tomorrow morning.

    Evan

     
  • Manfred Mornhinweg

    I changed the configuration to MPASM, but it turns out that GCB tries to access MPASMX, which I don't have. Apparently I need to download the full MPLABX to get it (a few gigabytes, through a slow and traffic-limited internet connection).
    Currently the newest MPASM I have on my computer is MPASMWIN, from 2008. I don't think that this will do...

    Also I did my tests by editing the program every time, and not saving each version separately. So it won't be fun doing every test again... But I can do a few. It just will take time, due to the long download to get MPASMX.

    Meanwhile I checked the functionality of ProgramRead, by reading out and printing the whole 16 kilowords. It seems to work well. So I think that the best thing I can do is using that command, and write a small QuickBasic program that adds my data to the hex files created by GCB, as an interim solution before you add ORG functionality, or a high level command for putting data words directly into memory!

     
    • Anobium

      Anobium - 2024-04-14

      Here is the MPASM download. https://sourceforge.net/projects/gcbasic/files/Support%20Files/MicrochipCompilers/

      Install MPASM using the default folders then GCBASIC will work without issue.

      Use the GCBASIC Preferences Editor to select MPASM as the default compiler.

       
  • Manfred Mornhinweg

    Evan,

    6 hours later, late in the night... I have good news, and bad news!
    The good news are that the problem wasn't in GCB. So the bad news are that I made you lose your time for nothing! Sorry about that. If it serves as consolation, I lost a lot of my own time too...

    The problem was the PICPGM software not correctly detecting my PIC, and instead of refusing to program it due to lack of detection, it did program it anyway - but only the lower half of its memory! PICPGM then quietly ignores the rest of the hex file contents. So any program that uses memory in the upper half of the range, had to crash. No wonder!

    I noticed this only after writing a PC program to stuff my data table into the hex file, after GCB writes that file, and the end of my data being cut off too! What contributed to me not noticing earlier is the old confusion between bytes and words (thinking that PICPGM was displaying word count, while really it was displaying byte count), and also that when using GCB, the PICPGM works in the background, and any warning notices by GCB flash by so fast that I didn't notice them.

    Well... So you can put the Table issue to rest, and I have now two ways to make my inverter controller program: Using GCB tables and ReadTable, or stuffing my data into the hex file at one value per memory word, and using ProgramRead to access it. Both approaches work fine now.

    I will probably end up using the hex file stuffing method, because it uses only half as much memory for my data, allowing me to put in twice as detailed data as with GCB Tables, due to my data being larger than bytes but smaller than 14-bit words.

    So the outcome of this is:

    1. It would be good to not program the PIC, and keep the compilation/programming info window open, when the programmer software reports not being able to detect the PIC.

    2. It would be nice to have a high-level statement to stuff 14-bit data words (and 16- bit for the devices that support it), either into a user-selected memory area, or anywhere in memory but with a way to retrieve the starting address of the data block. Such a Data statement would be a really useful complement to ProgramRead. In fact much more useful than ProgramWrite!

    3. I'm getting old and dumb. In my younger years I would have noticed the cause of the problem sooner!

    Phew!

     
  • Anobium

    Anobium - 2024-04-14

    Not a problem. Honestly.

    Advice. Load/Stuff the HEX using MPLAB-IPE. It is a robust method. Or, use HEXMATE.

    I will add your idea of DATA-END DATA soon. I think we should have an option to pack the data as you are thinking.


    Do change to a PICKitPlus programmer. This will help me and it will help you.


    You can download MPASM from the the FILEs tab of this forum. Install using the defaults and then you can use MPASM to verify the ASM. MPASM is a small download.

     
1 2 > >> (Page 1 of 2)

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.