Jump to content

Coding CS handler in C (use of functions pointers?)


mess
 Share

Recommended Posts

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

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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 released

A 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 yet

see:http://sourceforge.net/tracker/index.php?func=detail&aid=1427663&group_id=599&atid=100599

Link to comment
Share on other sites

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...

Link to comment
Share on other sites

But if this is user error,

the compiler should display a error on line xx message instead

of these strange SIGSEGV messages?

in the meanwhile I've replaced the function pointers with switch case statements

it seems that the compiler should optimise these to jumptables...(sdcc manual)

now the code compiles ok..

Link to comment
Share on other sites

I would prefer the table based method, it's much faster

As 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

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

×
×
  • Create New...