mess Posted August 6, 2006 Report Share Posted August 6, 2006 Hi,I'm struggling with coding a CS handler in C...it seems straightforward to handle parameters by translating the TC example to C(see http://www.midibox.org/forum/index.php?PHPSESSID=5e0c61976960c6db9364e9325330d7a7&topic=611.0)but how do you map buttons to functions?should this be implemented with a switch statement or with a table with function pointers?for example 4 buttons with 3 layers: Button 1 Button2 Button3 Button4 layer one: functionA functionB functionC functionD layer two: functionE functionF functionG functionH layer three: functionI functionJ functionK functionL with switch...case statements: switch (nr_of_layer) { case 0: switch (nr_of_button) { case 0: functionA(); case 1: functionB(); ... } case 1: switch (nr_of_button) { case 0: functionE(); case 1: functionF(); ... } .... } with functionpointers: //declaration of pointer array void (*Buttonfunctions[]) () = { functionA, functionB, functionC,functionD, functionE, functionF, functionG,functionH, functionI, functionJ, functionK,functionL, }; //usage *Buttonfunctions[button_nr * layer_nr](); please tell me if my question is not clear...Michaël Quote Link to comment Share on other sites More sharing options...
TK. Posted August 6, 2006 Report Share Posted August 6, 2006 I would prefer the table based method, it's much faster (just compare the produced .asm code in _output)Fine that you are starting with a CS in C - this will be a great contribution! :)Best Regards, Thorsten. Quote Link to comment Share on other sites More sharing options...
mess Posted August 10, 2006 Author Report Share Posted August 10, 2006 I'm having some problems with function pointers:declarations //simple function pointer void (*testp1) (void); //array of function pointers void (*testp2[]) (void); //some dummy functions void testf1 (void) {int a = 8;} void testf2 (void) {int a = 9;} void testf3 (void) {int a = 10;} function using first function pointer, compiles ok void testPointerfunction1 () { testp1 = testf1; testf1(); } using function pointer array, see error below void testPointerfunction2 () { testp2[0] = &testf1; testp2[1] = &testf2; testp2[2] = &testf3; testp2[0](); } error message: Makefile generated. Makefile.bat generated. Assembling MIOS SDCC wrapper ========================================================================== Compiling pic18f452.c Processor: 18F452 ========================================================================== Compiling main.c Processor: 18F452 Caught signal 11: SIGSEGV ERROR! is it possible that the library doesn't support function pointer arrays? Quote Link to comment Share on other sites More sharing options...
stryd_one Posted August 10, 2006 Report Share Posted August 10, 2006 I assume you included TK's library? Tried a SDCC nightly build? Quote Link to comment Share on other sites More sharing options...
mess Posted August 10, 2006 Author Report Share Posted August 10, 2006 I assume you included TK's library? Tried a SDCC nightly build?The library is included, I can use arrays of unsigned chars with no errors...I haven't tried a nightly build because of this from the MIOS C Interface page: Finally download the 2.5.0 release of SDCC.Note: the use of newer binary snapshots is not recommented, since the parameter passing method is not stable yet. Please only use SDCC versions which have been tested with the latest wrapper release!Maybe it's worth the try since SDCC 2.6.0 is released:July 31th, 2006: Small Device C Compiler 2.6.0 releasedA new release of SDCC, the portable optimizing compiler for 8051, DS390, Z80, PIC, and HC08 microprocessors is now available (http://sdcc.sourceforge.net). Sources, documentation and binaries compiled for x86 Linux, x86 Microsoft Windows and PPC Mac OS X are available.This release improves the compiler's conformance to the C standard. Significant progress was also made on the PIC (both 14- and 16-bit) backends. For the 8051 SDCC has seen the addition of a new memory model, code banking and bit variables. Numerous feature requests and bug fixes are included as well.Since 2.5.0 the ChangeLog has grown by more than 3000 lines so all changes are simply too numerous to name.I'm going to try this on another pc since I don't want to mess with my working config.to be continued... :)*edit: it seems that this bug is reported but not fixed yetsee:http://sourceforge.net/tracker/index.php?func=detail&aid=1427663&group_id=599&atid=100599 Quote Link to comment Share on other sites More sharing options...
stryd_one Posted August 10, 2006 Report Share Posted August 10, 2006 hey 2.6 is out at last! that's great news, long awaited!TK is right to recommend 2.5.0, as it is the only known working solution, but so far I have used nightly builds without any issues (in fact, one section of some test code I did required nightly builds rather than 2.5.0). Most of the instabilities are gone now, and with 2.6 being final, I think it should be safe... Quote Link to comment Share on other sites More sharing options...
stryd_one Posted August 10, 2006 Report Share Posted August 10, 2006 Re: your edit - that's not a reproducible fault, which means it is probably user error, not a bug Quote Link to comment Share on other sites More sharing options...
mess Posted August 10, 2006 Author Report Share Posted August 10, 2006 But if this is user error,the compiler should display a error on line xx message insteadof these strange SIGSEGV messages?in the meanwhile I've replaced the function pointers with switch case statementsit seems that the compiler should optimise these to jumptables...(sdcc manual)now the code compiles ok.. Quote Link to comment Share on other sites More sharing options...
audiocommander Posted August 10, 2006 Report Share Posted August 10, 2006 I would prefer the table based method, it's much fasterAs I also read some time ago in the SDCC-manual that switch-statements get converted to tables: has the switch-method been the preferred one, then?(I'm a bit tangled up, because I'm not sure if functionpointers are a "table-based method"...)cheers,Michael Quote Link to comment Share on other sites More sharing options...
TK. Posted August 10, 2006 Report Share Posted August 10, 2006 This would be perfect!Could you please take a look into the assembly output? It's located in the _output directoryBest Regards, Thorsten. Quote Link to comment Share on other sites More sharing options...
audiocommander Posted August 10, 2006 Report Share Posted August 10, 2006 well, I'm having this for example: // get enc button state switch(encoder) { case ENC_A_MIN: encDown = MIOS_DIN_PinGet(DIN_A_MIN) ^ 0x1; break; case ENC_A_MAX: encDown = MIOS_DIN_PinGet(DIN_A_MAX) ^ 0x1; break; case ENC_B_MIN: encDown = MIOS_DIN_PinGet(DIN_B_MIN) ^ 0x1; break; case ENC_B_MAX: encDown = MIOS_DIN_PinGet(DIN_B_MAX) ^ 0x1; break; case ENC_C_MIN: encDown = MIOS_DIN_PinGet(DIN_C_MIN) ^ 0x1; break; case ENC_C_MAX: encDown = MIOS_DIN_PinGet(DIN_C_MAX) ^ 0x1; break; case ENC_D_MIN: encDown = MIOS_DIN_PinGet(DIN_D_MIN) ^ 0x1; break; case ENC_D_MAX: encDown = MIOS_DIN_PinGet(DIN_D_MAX) ^ 0x1; break; default: encDown = FALSE; break; } and SDCC generates this: ; .line 696; main.c switch(encoder) { MOVLW 0x08 SUBWF r0x00, W BTFSC STATUS, 0 BRA _00454_DS_ MOVFF r0x0B, POSTDEC1 MOVFF r0x0C, POSTDEC1 CLRF r0x0C RLCF r0x00, W RLCF r0x0C, F RLCF WREG, W RLCF r0x0C, F ANDLW 0xfc MOVWF r0x0B MOVLW UPPER(_00490_DS_) MOVWF PCLATU MOVLW HIGH(_00490_DS_) MOVWF PCLATH MOVLW LOW(_00490_DS_) ADDWF r0x0B, F MOVF r0x0C, W ADDWFC PCLATH, F BTFSC STATUS, 0 INCF PCLATU, F MOVF r0x0B, W MOVFF PREINC1, r0x0C MOVFF PREINC1, r0x0B MOVWF PCL _00490_DS_: GOTO _00446_DS_ GOTO _00448_DS_ GOTO _00450_DS_ GOTO _00452_DS_ GOTO _00447_DS_ GOTO _00449_DS_ GOTO _00451_DS_ GOTO _00453_DS_ _00446_DS_: ; .line 697; main.c case ENC_A_MIN: encDown = MIOS_DIN_PinGet(DIN_A_MIN) ^ 0x1; break; MOVLW 0x02 CALL _MIOS_DIN_PinGet MOVWF r0x04 MOVLW 0x01 XORWF r0x04, F BRA _00455_DS_ _00447_DS_: ; .line 698; main.c case ENC_A_MAX: encDown = MIOS_DIN_PinGet(DIN_A_MAX) ^ 0x1; break; MOVLW 0x06 CALL _MIOS_DIN_PinGet MOVWF r0x05 MOVLW 0x01 XORWF r0x05, W MOVWF r0x04 BRA _00455_DS_ _00448_DS_: ; .line 699; main.c case ENC_B_MIN: encDown = MIOS_DIN_PinGet(DIN_B_MIN) ^ 0x1; break; MOVLW 0x0a CALL _MIOS_DIN_PinGet MOVWF r0x05 MOVLW 0x01 XORWF r0x05, W MOVWF r0x04 BRA _00455_DS_ _00449_DS_: ; .line 700; main.c case ENC_B_MAX: encDown = MIOS_DIN_PinGet(DIN_B_MAX) ^ 0x1; break; MOVLW 0x0e CALL _MIOS_DIN_PinGet MOVWF r0x05 MOVLW 0x01 XORWF r0x05, W MOVWF r0x04 BRA _00455_DS_ _00450_DS_: ; .line 701; main.c case ENC_C_MIN: encDown = MIOS_DIN_PinGet(DIN_C_MIN) ^ 0x1; break; MOVLW 0x12 CALL _MIOS_DIN_PinGet MOVWF r0x05 MOVLW 0x01 XORWF r0x05, W MOVWF r0x04 BRA _00455_DS_ _00451_DS_: ; .line 702; main.c case ENC_C_MAX: encDown = MIOS_DIN_PinGet(DIN_C_MAX) ^ 0x1; break; MOVLW 0x16 CALL _MIOS_DIN_PinGet MOVWF r0x05 MOVLW 0x01 XORWF r0x05, W MOVWF r0x04 BRA _00455_DS_ _00452_DS_: ; .line 703; main.c case ENC_D_MIN: encDown = MIOS_DIN_PinGet(DIN_D_MIN) ^ 0x1; break; MOVLW 0x1a CALL _MIOS_DIN_PinGet MOVWF r0x05 MOVLW 0x01 XORWF r0x05, W MOVWF r0x04 BRA _00455_DS_ _00453_DS_: ; .line 704; main.c case ENC_D_MAX: encDown = MIOS_DIN_PinGet(DIN_D_MAX) ^ 0x1; break; MOVLW 0x1e CALL _MIOS_DIN_PinGet MOVWF r0x05 MOVLW 0x01 XORWF r0x05, W MOVWF r0x04 BRA _00455_DS_ _00454_DS_: ; .line 705; main.c default: encDown = FALSE; break; CLRF r0x04 _00455_DS_: seems somehow like a jumping thing... is that good? Quote Link to comment Share on other sites More sharing options...
TK. Posted August 10, 2006 Report Share Posted August 10, 2006 yes, it's ok, even this method consumes more memory, because a "goto" instruction takes 4 bytes, storing the target program counter in a table would only take two byes per entry.However, for simple applications this should be ok, and for larger applications just use the PIC18F4620 ;-)Best Regards, Thorsten. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.