mp035 0 Report post Posted August 19, 2014 (edited) Hi, I am having some issues with incorrect results from a signed 32bit multiply, which I am unable to reproduce with a concise project under mplab sim. Looking at the dissasembly, it seems as if the main and interrupt routines are calling the same function, causing corruption of the registers used. interrupt disassembly ! accumulator -= (temp * temp); 0x471: MOVF sendval, W 0x472: MOVWF a 0x473: MOVF 0x68, W 0x474: MOVWF 0x72 0x475: MOVF 0x69, W 0x476: MOVWF 0x73 0x477: MOVF 0x6A, W 0x478: MOVWF 0x74 0x479: MOVF sendval, W 0x47A: MOVWF b 0x47B: MOVF 0x68, W 0x47C: MOVWF 0x76 0x47D: MOVF 0x69, W 0x47E: MOVWF 0x77 0x47F: MOVF 0x6A, W 0x480: MOVWF 0x78 0x481: CALL 0x7 !********************** I beleive this is the mul32 function. 0x482: MOVF $ret, W 0x483: MOVWF 0x6D 0x484: MOVF 0x7A, W 0x485: MOVWF 0x6E 0x486: MOVF 0x7B, W 0x487: MOVWF 0x6F 0x488: MOVF 0x7C, W 0x489: MOVWF 0x70 0x48A: MOVF 0x6D, W 0x48B: SUBWF accumulator, F 0x48C: MOVF 0x6E, W 0x48D: BTFSS STATUS, 0x0 0x48E: INCFSZ 0x6E, W 0x48F: SUBWF 0x29, F 0x490: MOVF 0x6F, W 0x491: BTFSS STATUS, 0x0 0x492: INCFSZ 0x6F, W 0x493: SUBWF 0x2A, F 0x494: MOVF 0x70, W 0x495: BTFSS STATUS, 0x0 0x496: INCFSZ 0x70, W 0x497: SUBWF 0x2B, F and in main: ! accumulated_value *= -1L; 0x365: MOVF accumulated_value, W 0x366: MOVWF a 0x367: MOVF 0x21, W 0x368: MOVWF 0x72 0x369: MOVF 0x22, W 0x36A: MOVWF 0x73 0x36B: MOVF 0x23, W 0x36C: MOVWF 0x74 0x36D: MOVLW 0xFF 0x36E: MOVWF b 0x36F: CLRF 0x76 0x370: DECF 0x76, F 0x371: CLRF 0x77 0x372: DECF 0x77, F 0x373: CLRF 0x78 0x374: DECF 0x78, F 0x375: CALL 0x7 !**************************** same function call. 0x376: MOVF $ret, W 0x377: MOVWF accumulated_value 0x378: MOVF 0x7A, W 0x379: MOVWF 0x21 0x37A: MOVF 0x7B, W 0x37B: MOVWF 0x22 0x37C: MOVF 0x7C, W 0x37D: MOVWF 0x23 Can anyone weigh in on whether this is a bug, or whether I should keep looking? Thanks. EDIT: putting intcon.GIE = 0, intcon.GIE=1 instructions around the main.c multiply solves the issue, so I'm almost certain this is a bug. Older versions of boostc used to flag this situation during compilation. I am using PIC16F1823, my main and interrupt functions are in different files (main.c and interrupt.c respectively.) Edited August 19, 2014 by mp035 Quote Share this post Link to post Share on other sites
Reynard 0 Report post Posted August 19, 2014 Hi, You should have been given a warning about this. Have you tried turning on all warnings. Putting a time consuming calculation like this into the interrupt is probably not a good idea. Collect the data you want quickly, set a flag, semaphore or create an event which can then be processed by the main program. Cheers Reynard Quote Share this post Link to post Share on other sites
mp035 0 Report post Posted August 25, 2014 Thanks for the reply Reynard. Yes I turned all warnings on, still no mention of the issue. I understand your concern regarding long calculations in the interrupt routine, this program is for real-time true RMS calculations of a waveform. Squaring in the ISR is the best option. I have been using this method for about 8 years on various compilers, but have just started coding with boostc again because of the shortcomings of the XC8 compiler. Boost V6 (and V5, I think) used to throw an error if a builtin function was called in both threads, but it looks like V7 does not. Quote Share this post Link to post Share on other sites
Reynard 0 Report post Posted August 25, 2014 (edited) HI, This is what I get for your processor: Building CASM file Serious Warning: Possible sw stack corruption, function '__mul_32s_32s' called by more than one asynchronous thread (main/Task, interrupt, interrupt low) Cheers Reynard ps. Using 7.22 Edited August 25, 2014 by Reynard Quote Share this post Link to post Share on other sites
mp035 0 Report post Posted August 26, 2014 Hi Reynard, Thanks for trying it out, do you have interrupt and main in different files? Quote Share this post Link to post Share on other sites
Hiker 0 Report post Posted August 26, 2014 Hi This post may be a little off topic - more towards algorithms.The line: accumulated_value * = -1L; Can be rewritten as: accumulated_value = -accumulated_value; As compiles inline, to a few instructions, without calls to subroutines. I have only tested on the v7.22 compiler, with PIC18F87J10 as target, but here uses 10 instructions in total. Quote Share this post Link to post Share on other sites
Reynard 0 Report post Posted August 26, 2014 Hi , Ah! you didn't say they were in different files. I now have the interrupt function in its own source file as part of the project and I still get the same warning message when building the CASM file. Cheers Reynard Quote Share this post Link to post Share on other sites
Reynard 0 Report post Posted August 26, 2014 Here is something interesting if you are working with signed integers. The boostc.h header file has (for PIC16): extern unsigned long __mul_32s_32s( unsigned long a, unsigned long b ); A signed multiplication that takes and returns unsigned values. Also, there appears to be no signed multiplication functions for the PIC18. Cheers Reynard Quote Share this post Link to post Share on other sites
mp035 0 Report post Posted August 26, 2014 (edited) Thanks Reynard, I am using PIC16F1823, my main and interrupt functions are in different files (main.c and interrupt.c respectively.) I wonder why I am not getting the warning? --- WAIT..... Bl**dy H**l !!!!!!!!!! Because it was not in blue or red on MPLABX I did not see it, I should have been looking harder! Hi This post may be a little off topic - more towards algorithms.The line: accumulated_value * = -1L; Can be rewritten as: accumulated_value = -accumulated_value; As compiles inline, to a few instructions, without calls to subroutines. I have only tested on the v7.22 compiler, with PIC18F87J10 as target, but here uses 10 instructions in total. Thanks for posting this, it is a good point. -- EDIT: I used your method instead of disabling the interrupts, as well as solving the issue, it will be faster. Thanks. Here is something interesting if you are working with signed integers. The boostc.h header file has (for PIC16): extern unsigned long __mul_32s_32s( unsigned long a, unsigned long b ); A signed multiplication that takes and returns unsigned values. Also, there appears to be no signed multiplication functions for the PIC18. Cheers Reynard Good note. Boost C uses 2's complement for signed integers, so the bit representation of the output will be correct whether or not the values are passed as signed. Edited August 26, 2014 by mp035 Quote Share this post Link to post Share on other sites