After spending much time trying to figure out the random crashes with my code and diving into the asm file and documentation, finally. It appears there are two problems with the on interrupt generated by GC. In my case, I am using a PIC12F683. But this appears to be in general across the newer mid range devices.
1 - The sysw and sysstatus variables must be defined between addresses 70H and 7FH. This allows for saving w and status no matter which bank is selected.
2 - You need to reset to bank 0 during the context save. Probably need to follow the example code:
MOVWF W_TEMP ;Copy W to TEMP register
SWAPF STATUS,W ;Swap status to be saved into W
CLRF STATUS ;bank 0, regardless of current bank, Clears IRP,RP1,RP0
MOVWF STATUS_TEMP
The only difference is the addition of the CLRF STATUS instruction.
This is a rather big problem. Many thanks if you can find the time to fix this soon, otherwise I will have to hack it myself in the mean time. As a much lower priority could you fix the problem with the 18F tables.
Thanks for the tireless effort.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
But #1 still appears half correct, the sysw variable needs to be defined between addresses 70H and 7FH (for a 256 RAM chip). GCBasic does not assure this. Maybe you could just assign the last address to sysw.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I broke down and got the ICD version of the PIC12 after I was still having problems. Well an hour later I discovered the issues and have the code running stable now.
a - The first post is correct on item #2. The CLRF STATUS is needed in the interrupt handler.
b - The second post is also correct. The sysw (only) variable must be defined in the "shared" ram segment. For the PIC12 thats 70H to 7FH.
c - I ran out of stack space. As is, with an interrupt enabled, you only get ONE subroutine level in your code (at least what parts of GCBasic I am using). I believe you really need at least two levels for reasonable code. The "real" culprit in my case, is the wait 10ms and wait sec call the wait ms routine, causing another level of stack. This does lower code size, and in a Pic18 part, its probably not an issue.
This is tough to ask, but maybe it would be nice in the compiler for a PIC12 with interrupts enabled, you combine the wait routines??? This is going to be a pain going forward, as I now have lots of manual edits to make at each compile.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Can your conditional statements can be reworded so that a couple of variables are evaluated each time?, and thereby reducing the subroutine goto's. If you have to say wait seconds in an interrupt subroutine, then the timing must not be too critical. Set or increment a variable, retfie, and do it your task in Main.
Another thought might be to use select case statements. Really hard to say without some more background, and a sample subroutine.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I ruled out compound logic statements a while ago. They really add code to the assembly. Two if's are much smaller in code size, especially if one of them involves a zero (which the compiler can optimize). Modifying the wait10ms (in my case), isn't too difficult. I may write a post compile program to do this if I need to do much more, along with the CLRF statement, and moving the sysw variable to address 127. Adding an "else" statement to the IF, would be MUCH appreciated, and would save many statements.
My interrupt routine handles the timing critical tasks, the main task is in fact timing uncritical. The interrupt handler has no wait statements, or any complex statements that would cause the interrupts to be disabled (in the interrupt). The wait statements are easy, but a curse also. As they hog the MCU. If I was writing for the larger pic's I would use an OS that would provide for multitasking and timers, and thus not block other actions. But for my application, they are fine.
I only have two subroutines, but one calls the other. Combining would be too much code. Simply modifying the wait10ms seems easier than some other options.
I have ran across one other issue now that I am very close to the 2K code limit of my pic (but I don't think it's related to filling up the pic). It appears I am running out of IF's. The compiler locks up during compile at the "compile if's" part, when I put in over about 100 if's. This number changes though, so it might be related to total statements somehow. I took a quick look at the source for an array too small issue, but couldn't find it easily. I was able to get rid of a few to get things to work, for now. If I need to add more after quality testing, then this is going to be an issue. As another note, I am very close on ram locations, but the compiler actually thinks I have more. I suspect it doesn't count the variables added for it's own usage.
One last item, I can't get the "Table xx Store Data" to work. Any comments? No go for the PIC12? ???
I really appreciate this work. And I was able to get the project complete (as of now, more will be needed later I'm sure) with the current version, with some manual edits. Much less work than writing in assembly, and open source. So I am quite happy! I could of course, modify the source myself (as a last resort).
Here's the pertinent compiler output:
Compiling commands:
ReadTable ... (Found 0)
POT ... (Found 0)
DO ... (Found 1)
DIR ... (Found 3)
WAIT ... (Found 20)
On ... (Found 1)
SET ... (Found 77)
ROTATE ... (Found 9)
Repeat ... (Found 0)
Select ... (Found 4)
IF ... (Found 98) <-locks up here, anywhere from 99 to 103 has locked it up
Variable setting commands ... (Found 262)
END, EXIT SUB/FUNCTION ... (Found 4)
GOTO ... (Found 60)
Well you have a much better grip on things then myself, so can only brainstorm ideas.
1) Else statements supported, undocumented feature, but discussed in forum.
2) Tried the On Interrupt GPIOChange Call... for the 12f683, and no problem. What are your assembler equ's for sysW and sysSTATUS? Seems like a banksel sysW would need to be used if these variables got pushed to bank1, bank2,.... under the current setup?
3) Using one too many IF statements was how I found out about the 2k limit. Very erratic operation, or wouldn't completely assemble, until the extra code was commented out. The #option lcall (for non 18f's), used to work for the 2k boundary, not so sure now. For my hobby use, the 18f was the path of least resistance.
4) ReadTable has worked for me in the past (16f, and 18f anyway), haven't tried a "store table", or looked into it.
5) You can save a pile of code if you can work around any word size variables.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
1 - Thanks about the info on else. I missed that one. That should save me some if's and space. (Wish I found that one a month ago).
2 - On interrrupt works fine, as long as by chance bank 1 is not selected when the interrupt occurs. In which case who knows what will happen. In my case, the interrupt would be disabled, as it would write the enable off, instead of the interrupt flag. The sysW is along the same line. As long as bank 0 is selected on interrupt it works.
3 - The PIC18's are better. In my application I needed small physical size (using SOIC package even), and the only 8 pin is a PIC12. Thanks for the info about the 2k limit, I didn't know that. In my case, thats the size of my device, so probably not a problem.
4 - I do have 1 readtable, it does work great (for a PIC12. The PIC18 tables have an even byte problem still). But the new feature of a table in EEPROM, doesn't work for me.
Thanks for the help.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
After spending much time trying to figure out the random crashes with my code and diving into the asm file and documentation, finally. It appears there are two problems with the on interrupt generated by GC. In my case, I am using a PIC12F683. But this appears to be in general across the newer mid range devices.
1 - The sysw and sysstatus variables must be defined between addresses 70H and 7FH. This allows for saving w and status no matter which bank is selected.
2 - You need to reset to bank 0 during the context save. Probably need to follow the example code:
MOVWF W_TEMP ;Copy W to TEMP register
SWAPF STATUS,W ;Swap status to be saved into W
CLRF STATUS ;bank 0, regardless of current bank, Clears IRP,RP1,RP0
MOVWF STATUS_TEMP
The only difference is the addition of the CLRF STATUS instruction.
This is a rather big problem. Many thanks if you can find the time to fix this soon, otherwise I will have to hack it myself in the mean time. As a much lower priority could you fix the problem with the 18F tables.
Thanks for the tireless effort.
Well, I was a little wrong above.
Disregard #2. I am a little green to the PIC.
But #1 still appears half correct, the sysw variable needs to be defined between addresses 70H and 7FH (for a 256 RAM chip). GCBasic does not assure this. Maybe you could just assign the last address to sysw.
I broke down and got the ICD version of the PIC12 after I was still having problems. Well an hour later I discovered the issues and have the code running stable now.
a - The first post is correct on item #2. The CLRF STATUS is needed in the interrupt handler.
b - The second post is also correct. The sysw (only) variable must be defined in the "shared" ram segment. For the PIC12 thats 70H to 7FH.
c - I ran out of stack space. As is, with an interrupt enabled, you only get ONE subroutine level in your code (at least what parts of GCBasic I am using). I believe you really need at least two levels for reasonable code. The "real" culprit in my case, is the wait 10ms and wait sec call the wait ms routine, causing another level of stack. This does lower code size, and in a Pic18 part, its probably not an issue.
This is tough to ask, but maybe it would be nice in the compiler for a PIC12 with interrupts enabled, you combine the wait routines??? This is going to be a pain going forward, as I now have lots of manual edits to make at each compile.
Can your conditional statements can be reworded so that a couple of variables are evaluated each time?, and thereby reducing the subroutine goto's. If you have to say wait seconds in an interrupt subroutine, then the timing must not be too critical. Set or increment a variable, retfie, and do it your task in Main.
Another thought might be to use select case statements. Really hard to say without some more background, and a sample subroutine.
I ruled out compound logic statements a while ago. They really add code to the assembly. Two if's are much smaller in code size, especially if one of them involves a zero (which the compiler can optimize). Modifying the wait10ms (in my case), isn't too difficult. I may write a post compile program to do this if I need to do much more, along with the CLRF statement, and moving the sysw variable to address 127. Adding an "else" statement to the IF, would be MUCH appreciated, and would save many statements.
My interrupt routine handles the timing critical tasks, the main task is in fact timing uncritical. The interrupt handler has no wait statements, or any complex statements that would cause the interrupts to be disabled (in the interrupt). The wait statements are easy, but a curse also. As they hog the MCU. If I was writing for the larger pic's I would use an OS that would provide for multitasking and timers, and thus not block other actions. But for my application, they are fine.
I only have two subroutines, but one calls the other. Combining would be too much code. Simply modifying the wait10ms seems easier than some other options.
I have ran across one other issue now that I am very close to the 2K code limit of my pic (but I don't think it's related to filling up the pic). It appears I am running out of IF's. The compiler locks up during compile at the "compile if's" part, when I put in over about 100 if's. This number changes though, so it might be related to total statements somehow. I took a quick look at the source for an array too small issue, but couldn't find it easily. I was able to get rid of a few to get things to work, for now. If I need to add more after quality testing, then this is going to be an issue. As another note, I am very close on ram locations, but the compiler actually thinks I have more. I suspect it doesn't count the variables added for it's own usage.
One last item, I can't get the "Table xx Store Data" to work. Any comments? No go for the PIC12? ???
I really appreciate this work. And I was able to get the project complete (as of now, more will be needed later I'm sure) with the current version, with some manual edits. Much less work than writing in assembly, and open source. So I am quite happy! I could of course, modify the source myself (as a last resort).
Here's the pertinent compiler output:
Compiling commands:
ReadTable ... (Found 0)
POT ... (Found 0)
DO ... (Found 1)
DIR ... (Found 3)
WAIT ... (Found 20)
On ... (Found 1)
SET ... (Found 77)
ROTATE ... (Found 9)
Repeat ... (Found 0)
Select ... (Found 4)
IF ... (Found 98) <-locks up here, anywhere from 99 to 103 has locked it up
Variable setting commands ... (Found 262)
END, EXIT SUB/FUNCTION ... (Found 4)
GOTO ... (Found 60)
Summary:
Read by GCBASIC:
Input lines: 5969 (20000 max)
Variables: 91 (128 max)
Constants: 182 (400 max)
Subroutines: 124 (500 max)
Assembly program lines written: 2932 (20000 max)
Well you have a much better grip on things then myself, so can only brainstorm ideas.
1) Else statements supported, undocumented feature, but discussed in forum.
2) Tried the On Interrupt GPIOChange Call... for the 12f683, and no problem. What are your assembler equ's for sysW and sysSTATUS? Seems like a banksel sysW would need to be used if these variables got pushed to bank1, bank2,.... under the current setup?
3) Using one too many IF statements was how I found out about the 2k limit. Very erratic operation, or wouldn't completely assemble, until the extra code was commented out. The #option lcall (for non 18f's), used to work for the 2k boundary, not so sure now. For my hobby use, the 18f was the path of least resistance.
4) ReadTable has worked for me in the past (16f, and 18f anyway), haven't tried a "store table", or looked into it.
5) You can save a pile of code if you can work around any word size variables.
1 - Thanks about the info on else. I missed that one. That should save me some if's and space. (Wish I found that one a month ago).
2 - On interrrupt works fine, as long as by chance bank 1 is not selected when the interrupt occurs. In which case who knows what will happen. In my case, the interrupt would be disabled, as it would write the enable off, instead of the interrupt flag. The sysW is along the same line. As long as bank 0 is selected on interrupt it works.
3 - The PIC18's are better. In my application I needed small physical size (using SOIC package even), and the only 8 pin is a PIC12. Thanks for the info about the 2k limit, I didn't know that. In my case, thats the size of my device, so probably not a problem.
4 - I do have 1 readtable, it does work great (for a PIC12. The PIC18 tables have an even byte problem still). But the new feature of a table in EEPROM, doesn't work for me.
Thanks for the help.