DriftZ Posted November 8, 2003 Report Share Posted November 8, 2003 Hello,Is it possible to change the direction (CW+/CW- & CCW+/CCW-) in the MIOS software or does it have to be done in hardware (swap the pins of the encoder) ?thanks Quote Link to comment Share on other sites More sharing options...
TK. Posted November 9, 2003 Report Share Posted November 9, 2003 Hi,you can change the direction by inverting the incrementer value in USER_ENC_NotifyChange.Example (not checked) USER_ENC_NotifyChange ;; inverting the incrementer: ;; if negative: incrementer = NOT incrementer ;; if positive: incrementer = (NOT incrementer) + 1 comf MIOS_PARAMETER2, W IFCLR MIOS_PARAMETER2, 7, addlw 1 movwf MIOS_PARAMETER2 ;; continue... Best Regards, Thorsten. Quote Link to comment Share on other sites More sharing options...
DriftZ Posted November 10, 2003 Author Report Share Posted November 10, 2003 okay thanks TK ! Quote Link to comment Share on other sites More sharing options...
Steven_C Posted November 11, 2003 Report Share Posted November 11, 2003 I have also reversed (by accident) the direction of encoder by reversing the connections when soldering Quote Link to comment Share on other sites More sharing options...
sneakthief Posted March 29, 2007 Report Share Posted March 29, 2007 Sorry to drag this topic from the deep & dark vaults, but how does one do this now that the code has changed to this:USER_ENC_NotifyChange extern _ENC_NotifyChange lfsr FSR0, STACK_HEAD ; initialize stack lfsr FSR2, STACK_HEAD movff MIOS_PARAMETER2, POSTDEC0 ;; encoder number still in WREG goto _ENC_NotifyChange Quote Link to comment Share on other sites More sharing options...
stryd_one Posted March 30, 2007 Report Share Posted March 30, 2007 Where's that code from?Anyway TK's code is still good, just pop that at the top of your application's USER_ENC_NotifyChange Quote Link to comment Share on other sites More sharing options...
sneakthief Posted March 30, 2007 Report Share Posted March 30, 2007 oh sorry for not being more specific: that code was taken directly from the mios_wrapper.asm used in the C examples section.the code that TK posted doesn't seem to work at all with the Clockbox code - I get a Syntax Error Quote Link to comment Share on other sites More sharing options...
stryd_one Posted March 30, 2007 Report Share Posted March 30, 2007 So yours looks like this: USER_ENC_NotifyChange ;; inverting the incrementer: ;; if negative: incrementer = NOT incrementer ;; if positive: incrementer = (NOT incrementer) + 1 comf MIOS_PARAMETER2, W IFCLR MIOS_PARAMETER2, 7, addlw 1 movwf MIOS_PARAMETER2 ;; continue... extern _ENC_NotifyChange lfsr FSR0, STACK_HEAD ; initialize stack lfsr FSR2, STACK_HEAD movff MIOS_PARAMETER2, POSTDEC0 ;; encoder number still in WREG goto _ENC_NotifyChange Right? Edit: Oh yeh that's gonna screw with the encoder number in W.... Uhm.. Wow this post is old... Gimme a minute here to whip something up in ASM just for the archives... Of course in your case you can do it within the application... In main.c just do: ///////////////////////////////////////////////////////////////////////////// // This function is called by MIOS when an encoder has been moved // incrementer is positive when encoder has been turned clockwise, else // it is negative ///////////////////////////////////////////////////////////////////////////// void ENC_NotifyChange(unsigned char encoder, char incrementer) __wparam { incrementer *= -1; unsigned int value; // encoder 0 is used to control the BPM if( encoder == 0 ) { value = (unsigned int)MCLOCK_BPMGet() - 48; if( MIOS_HLP_16bitAddSaturate(incrementer, &value, 255 - 48) ) { MCLOCK_BPMSet((unsigned char)value + 48); app_flags.DISPLAY_UPDATE_REQ = 1; } } } Quote Link to comment Share on other sites More sharing options...
stryd_one Posted March 30, 2007 Report Share Posted March 30, 2007 OK I am not well right now so I make no promises, however... Try this if you want the ASM version.It's pretty simple, the encoder number is restored from MIOS_PARAMETER1 to W. This is necessary because the ENC_NotifyChange funtion uses the __wparam option which means that the first parameter is passed using WREG. USER_ENC_NotifyChange extern _ENC_NotifyChange ;; inverting the incrementer: ;; if negative: incrementer = NOT incrementer ;; if positive: incrementer = (NOT incrementer) + 1 comf MIOS_PARAMETER2, W IFCLR MIOS_PARAMETER2, 7, addlw 1 movwf MIOS_PARAMETER2 ;; continue... lfsr FSR0, STACK_HEAD ; initialize stack lfsr FSR2, STACK_HEAD movff MIOS_PARAMETER2, POSTDEC0 ;; put encoder number back in WREG movf MIOS_PARAMETER1, W goto _ENC_NotifyChange Quote Link to comment Share on other sites More sharing options...
sneakthief Posted March 30, 2007 Report Share Posted March 30, 2007 So yours looks like this:No, unless I'm missing something, it doesn't look like that at all.Here's the whole section: ;; -------------------------------------------------------------------------- ;; This function is called by MIOS when an encoder has been moved ;; Input: ;; o Encoder number in WREG and MIOS_PARAMETER1 ;; o signed incrementer value in MIOS_PARAMETER2: ;; - is positive when encoder has been turned clockwise ;; - is negative when encoder has been turned counter clockwise ;; -------------------------------------------------------------------------- USER_ENC_NotifyChange extern _ENC_NotifyChange lfsr FSR0, STACK_HEAD ; initialize stack lfsr FSR2, STACK_HEAD movff MIOS_PARAMETER2, POSTDEC0 ;; encoder number still in WREG goto _ENC_NotifyChange So there's nothing that resembles "IFCLR MIOS_PARAMETER2, 7, addlw 1" Quote Link to comment Share on other sites More sharing options...
stryd_one Posted March 30, 2007 Report Share Posted March 30, 2007 That IFCLR is part of TK's code... Let me start from the beginning to make more sense ;)BTW, in your case, you can skip right to the end if you do'nt care for technical stuff.....OK MIOS will detect the movement of the encoder and report it to the application by calling USER_ENC_NotifyChange. It has two values: the encoder number; and a number to show how much the encoder has changed, and in which direction.USER_ENC_NotifyChange is a part of the application. It is always in ASM. In the case of the C application, the function is in mios_wrapper.asm. It makes a few small preparations and then it calls the ENC_NotifyChange (Note the missing 'USER_' in the name) function in the main.c file.Because of this, you can change the encoder value either:In your ASM or INC file, for ASM based apps (MB64E, MBSEQ, MBSID),In the mios_wrapper.asm file, for C based applications (Clockbox), or...In the main.c file, for C based applications (Clockbox)Now, to invert the encoder is simple in C, so the third option is the easiest. The incrementer value and direction is saved in a value named...wait for it... 'incrementer'. you need to add incrementer *= -1; In...... ///////////////////////////////////////////////////////////////////////////// // This function is called by MIOS when an encoder has been moved // incrementer is positive when encoder has been turned clockwise, else // it is negative ///////////////////////////////////////////////////////////////////////////// void ENC_NotifyChange(unsigned char encoder, char incrementer) __wparam { <---------------------------------------------------------------------------------------HERE!!!!!!!!!!!!!!! unsigned int value; // encoder 0 is used to control the BPM if( encoder == 0 ) { value = (unsigned int)MCLOCK_BPMGet() - 48; if( MIOS_HLP_16bitAddSaturate(incrementer, &value, 255 - 48) ) { MCLOCK_BPMSet((unsigned char)value + 48); app_flags.DISPLAY_UPDATE_REQ = 1; } } } If you prefer, you can do it in ASM. This means altering your application's ASM or INC file - in the case of the C wrapper it is mios_wrapper.asm You need to add TK's code: ;; inverting the incrementer: ;; if negative: incrementer = NOT incrementer ;; if positive: incrementer = (NOT incrementer) + 1 comf MIOS_PARAMETER2, W IFCLR MIOS_PARAMETER2, 7, addlw 1 movwf MIOS_PARAMETER2 ;; continue... In.... ;; -------------------------------------------------------------------------- ;; This function is called by MIOS when an encoder has been moved ;; Input: ;; o Encoder number in WREG and MIOS_PARAMETER1 ;; o signed incrementer value in MIOS_PARAMETER2: ;; - is positive when encoder has been turned clockwise ;; - is negative when encoder has been turned counter clockwise ;; -------------------------------------------------------------------------- USER_ENC_NotifyChange extern _ENC_NotifyChange <---------------------------------------------------------------------------------------HERE!!!!!!!!!!!!!!! lfsr FSR0, STACK_HEAD ; initialize stack lfsr FSR2, STACK_HEAD movff MIOS_PARAMETER2, POSTDEC0 ;; encoder number still in WREG <--------------------------------------------------NOT TRUE!!!!!!!!!!!!!!! goto _ENC_NotifyChange Notice that my note mentions that the encoder number is not in WREG. W was manipulated by TK's code. (Note - the encoder number did not always go in W, this code from TK is for an older version of MIOS) WREG is needed to pass to the C function's 'unsigned char encoder' because the C function is forced to do so by the ' __wparam' at the end of the function definition. To fix this, we need to get the encoder number, which is fortunately still stored in MIOS_PARAMETER1, and move it to 'W'. You should change it so that instead of this: ;; encoder number still in WREG <--------------------------------------------------NOT TRUE!!!!!!!!!!!!!!! goto _ENC_NotifyChange it looks like this: ;; put encoder number back in WREG movf MIOS_PARAMETER1, W goto _ENC_NotifyChange The end product of all these can be seen en the last two posts.Hope that helps! Quote Link to comment Share on other sites More sharing options...
sneakthief Posted March 30, 2007 Report Share Posted March 30, 2007 First of all, thanks for taking the time to help me out with this :) I appreciate it!That IFCLR is part of TK's code... Let me start from the beginning to make more sense ;)I gathered as much :)Ok -Re. C encoder reverse: incrementer *= -1; This creates a syntax error: "token -> unsigned" Re. ASM encoder reverse: IFCLR MIOS_PARAMETER2, 7, addlw 1 This line also creates a syntax error. Am I doing something wrong here? Although I'm a C newbie (but not to programming in general), I understand exactly what you're trying to do. Quote Link to comment Share on other sites More sharing options...
stryd_one Posted March 30, 2007 Report Share Posted March 30, 2007 incrementer *= -1; This creates a syntax error: "token -> unsigned" Ahh OK... About the C thing, that will be my poor excuse for C code. Can one of you C gurus take a look? Re. ASM encoder reverse: IFCLR MIOS_PARAMETER2, 7, addlw 1 This line also creates a syntax error. Seems it didn't like us using the macro there. Try this (compiles OK for me) USER_ENC_NotifyChange extern _ENC_NotifyChange ;; inverting the incrementer: ;; if negative: incrementer = NOT incrementer ;; if positive: incrementer = (NOT incrementer) + 1 comf MIOS_PARAMETER2, W ;;IFCLR MIOS_PARAMETER2, 7, addlw 1 btfss MIOS_PARAMETER2, 7 addlw 1 movwf MIOS_PARAMETER2 ;; continue... lfsr FSR0, STACK_HEAD ; initialize stack lfsr FSR2, STACK_HEAD movff MIOS_PARAMETER2, POSTDEC0 ;; put encoder number back in WREG movf MIOS_PARAMETER1, W goto _ENC_NotifyChange Quote Link to comment Share on other sites More sharing options...
sneakthief Posted March 31, 2007 Report Share Posted March 31, 2007 I tried out your ASM code:When I turn the encoder CCW, the value decreases - but nothing happens when I turn it CW. Quote Link to comment Share on other sites More sharing options...
stryd_one Posted March 31, 2007 Report Share Posted March 31, 2007 Wow when I screw up I reallllly screw up! Sorry man.. WTF is going on here...Problem is that I rarely deal with signed values at the binary level, I have to do some homework here...I have just read the datasheet and the only mention of signed arithmetic is a two's complement system. wikipedia says:Negating a number (whether negative or positive) is done by inverting all the bits and then adding 1 to that resultSo if I can believe that, this should work: USER_ENC_NotifyChange extern _ENC_NotifyChange ;; inverting the incrementer: ;; incrementer = (NOT incrementer) + 1 ;; aka 2s complement comf MIOS_PARAMETER2, W addlw 1 movwf MIOS_PARAMETER2 ;; continue... lfsr FSR0, STACK_HEAD ; initialize stack lfsr FSR2, STACK_HEAD movff MIOS_PARAMETER2, POSTDEC0 ;; put encoder number back in WREG movf MIOS_PARAMETER1, W goto _ENC_NotifyChange I still think that this change should be done within the application, in C, in which case we could try the same trick... ///////////////////////////////////////////////////////////////////////////// // This function is called by MIOS when an encoder has been moved // incrementer is positive when encoder has been turned clockwise, else // it is negative ///////////////////////////////////////////////////////////////////////////// void ENC_NotifyChange(unsigned char encoder, char incrementer) __wparam { incrementer = (!incrementer)+1 //invert encoder direction by 2's complement unsigned int value; // encoder 0 is used to control the BPM if( encoder == 0 ) { value = (unsigned int)MCLOCK_BPMGet() - 48; if( MIOS_HLP_16bitAddSaturate(incrementer, &value, 255 - 48) ) { MCLOCK_BPMSet((unsigned char)value + 48); app_flags.DISPLAY_UPDATE_REQ = 1; } } } Quote Link to comment Share on other sites More sharing options...
sneakthief Posted March 31, 2007 Report Share Posted March 31, 2007 aha! i got your first C example to work :)here's what the problem was:when i did this it produced an error: incrementer *= -1; unsigned int value; however, when I changed the order it worked: unsigned int value; incrementer *= -1; thanks so much for your perseverence on this, stryd_one!! Quote Link to comment Share on other sites More sharing options...
stryd_one Posted March 31, 2007 Report Share Posted March 31, 2007 when i did this it produced an error: incrementer *= -1; unsigned int value; however, when I changed the order it worked: unsigned int value; incrementer *= -1; WTF!?!?I have noticed that SDCC is real picky about where you declare stuff.... Maybe it won't let you declare once the funciton has begun? Hmmm...Hey, whatever works! ;)Glad it's behaving ;D Quote Link to comment Share on other sites More sharing options...
stryd_one Posted April 6, 2007 Report Share Posted April 6, 2007 Just a quick followup - indeed, SDCC will only allow declarations to be made at the very top of the function before it actually does anything... as for negating the variable... a NEGF instruction would have done fine. D'oh! Quote Link to comment Share on other sites More sharing options...
DavidBanner Posted April 6, 2007 Report Share Posted April 6, 2007 SDCC will only allow declarations to be made at the very top of the function yup - that caused me a bit of head scratching for a while :) 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.