Shop OBEX P1 Docs P2 Docs Learn Events
C: Does This Look Right? — Parallax Forums

C: Does This Look Right?

idbruceidbruce Posts: 6,197
edited 2015-04-14 11:20 in Propeller 1
Bit masking and shifting ARRRGGG... Does this look right?
void x_axis_driver(void *par)
{
	int32_t x_counter;

	// Set DIRA as an output.
	DIRA |= (1 << X_DIRECTION);

	do
	{
		if(app_move_now == true)
		{
			app_move_now = false;

			// Set the output pin for Counter A.
			CTRA = X_STEP;

			// Set up the CTRMODE of Counter A for NCO/PWM single-ended.
			CTRA += 0b00100 << 26;

			// Set the value to be added to PHSA with every clock cycle.
			FRQA = 1;

			// Set DIRA as an output.
			DIRA |= (1 << X_STEP);

			// Set the OUTA register to match the desired direction of rotation.
			if(current_gcode.x_dir == 0)
			{
				OUTA &= (~X_DIRECTION);
			}
			else
			{
				OUTA |= X_DIRECTION;
			}

EDIT: I already found one mistake

Comments

  • DavidZemonDavidZemon Posts: 2,973
    edited 2015-04-12 12:51
    Looked good to me. You clipped a couple lines at the bottom. Here's what I came up with
    void x_axis_driver(void *par) {
        int32_t x_counter;
    
        // Set DIRA as an output.
        DIRA |= (1 << X_DIRECTION);
    
        while (1) {
            if (app_move_now == true) {
                app_move_now = false;
    
                // Set the output pin for Counter A.
                CTRA = X_STEP;
    
                // Set up the CTRMODE of Counter A for NCO/PWM single-ended.
                CTRA += 0b00100 << 26;
    
                // Set the value to be added to PHSA with every clock cycle.
                FRQA = 1;
    
                // Set DIRA as an output.
                DIRA |= (1 << X_STEP);
    
                // Set the OUTA register to match the desired direction of rotation.
                if (current_gcode.x_dir == 0) {
                    OUTA &= (~X_DIRECTION);
                } else {
                    OUTA |= X_DIRECTION;
                }
            }
        }
    }
    
  • idbruceidbruce Posts: 6,197
    edited 2015-04-12 13:34
    David

    Since I already had this copied, I am going to paste it before trying your code. The code shown below does not work and this is breaking it down to the minimum.
    #include "propeller.h"
    
    #define X_DIRECTION 22
    #define X_STEP 23
    #define X_PULSE_WIDTH CLKFREQ / 1000000 // 80
    #define X_MIN_SPEED CLKFREQ / 5714 // 14000 Rounded
    
    int main(void)
    {
    	int counter;
    	int steps = 2000;
    	int dir = 1;
    
    	// Set DIRA as an output.
    	DIRA |= 1 << X_DIRECTION;
    
    	CTRA = (4 << 26) | X_STEP;
    
    	// Set the value to be added to PHSA with every clock cycle.
    	FRQA = 1;
    
    	// Set DIRA as an output.
    	DIRA |= 1 << X_STEP;
    
    	// Set the OUTA register to match the desired direction of rotation.
    	if(dir == 0)
    	{
    		OUTA &= (~1 << X_DIRECTION);
    	}
    	else
    	{
    		OUTA |= 1 << X_DIRECTION;
    	}
    
    	// Get the current System Counter value.
    	counter = CNT;
    
    	// Run the stepper motor at the current speed for a predetermined amount of steps
    	while(steps > 0)
    	{
    		// Send out a high pulse on the step pin for the desired duration.
    		PHSA = -X_PULSE_WIDTH;
    
    		// Wait for a specified period of time before sending another
    		// high pulse to the step pin.
    		waitcnt(counter += X_MIN_SPEED);
    
    		// Decrement running_steps
    		steps--;
    	}
    
    	return 0;
    }
    
  • idbruceidbruce Posts: 6,197
    edited 2015-04-12 14:00
    One thing is for sure....

    Your code got a real high pitch from my motor, which is more than I got all day LOL

    By the way, I am not laughing at your help, just my situation :)
  • idbruceidbruce Posts: 6,197
    edited 2015-04-12 14:09
    Aha....

    For one thing my defines are not correct. I hard coded the spots where the defines went and I got movement!!!!
  • DavidZemonDavidZemon Posts: 2,973
    edited 2015-04-12 14:19
    Awesome :) Good job
  • idbruceidbruce Posts: 6,197
    edited 2015-04-12 14:29
    @David

    The following code is what I ended up with. Those darn defines caused me a lot of grief. I knew better than to not enclose them in parenthesis.

    @anyone

    The following code will setup a counter in C for NCO/PWM single-ended and drive a stepper motor that requires a 1uS high pulse width.
    #include "propeller.h"
    
    #define X_DIRECTION 22
    #define X_STEP 23
    #define X_PULSE_WIDTH (CLKFREQ / 1000000) // 80
    #define X_MIN_SPEED (CLKFREQ / 5714) // 14000 Rounded
    
    int main(void)
    {
    	int counter;
    	int steps = 2000;
    	int dir = 0;
    
    	// Set DIRA as an output.
    	DIRA |= 1 << X_DIRECTION;
    
    	// Set up the CTRMODE of Counter A for NCO/PWM single-ended.
    	CTRA = 4 << 26 | X_STEP;
    
    	// Set the value to be added to PHSA with every clock cycle.
    	FRQA = 1;
    
    	// Set DIRA as an output.
    	DIRA |= 1 << X_STEP;
    
    	// Set the OUTA register to match the desired direction of rotation.
    	if(dir == 0)
    	{
    		OUTA &= ~1 << X_DIRECTION;
    	}
    	else
    	{
    		OUTA |= 1 << X_DIRECTION;
    	}
    
    	// Get the current System Counter value.
    	counter = CNT;
    
    	// Run the stepper motor at the current speed for a predetermined amount of steps
    	while(steps > 0)
    	{
    		// Send out a high pulse on the step pin for the desired duration.
    		PHSA = -X_PULSE_WIDTH;
    
    		// Wait for a specified period of time before sending another
    		// high pulse to the step pin.
    		waitcnt(counter += X_MIN_SPEED);
    
    		// Decrement running_steps
    		steps--;
    	}
    
    	return 0;
    }
    

    With the incorrect defines... It almost makes me want to test the Teacup code one more time.
  • Dave HeinDave Hein Posts: 6,347
    edited 2015-04-13 11:28
    "OUTA &= ~1 << X_DIRECTION;" is the same as "OUTA &= (~1) << X_DIRECTION;". It should be "OUTA &= ~(1 << X_DIRECTION);".

    "4 << 26 | X_STEP" is a bit dangerous unless you know for sure that "<<" has higher precedence than "|", which it does. However, "4 << 26 + X_STEP" would not produce the desired result since "+" has higher precedence than "<<". It's safer to use "(4 << 26) | X_STEP".
  • DavidZemonDavidZemon Posts: 2,973
    edited 2015-04-13 12:08
    Dave Hein wrote: »
    "4 << 26 | X_STEP" is a bit dangerous unless you know for sure that "<<" has higher precedence than "|", which it does. However, "4 << 26 + X_STEP" would not produce the desired result since "+" has higher precedence than "<<". It's safer to use "(4 << 26) | X_STEP".

    Definitely a good point. And personally, I'd rather see "4 << 26" as a constant. Either a preprocessor macro (#define) or global constant variable or enum. Enum would be my top choice, since that's what they're made for really (it'd be cool if such an enum were provided in PropGCC)
  • idbruceidbruce Posts: 6,197
    edited 2015-04-13 13:15
    Dave
    "OUTA &= ~1 << X_DIRECTION;" is the same as "OUTA &= (~1) << X_DIRECTION;". It should be "OUTA &= ~(1 << X_DIRECTION);".

    "4 << 26 | X_STEP" is a bit dangerous unless you know for sure that "<<" has higher precedence than "|", which it does. However, "4 << 26 + X_STEP" would not produce the desired result since "+" has higher precedence than "<<". It's safer to use "(4 << 26) | X_STEP".

    Thanks Dave, I will change those items per your recommendations. I have also seen the following:
    DIRA |= (1 << X_STEP);
    OUTA |= (1 << X_DIRECTION);
    

    I currently have this:
    DIRA |= 1 << X_STEP;
    OUTA |= 1 << X_DIRECTION;
    

    Should these be changed also?
  • DavidZemonDavidZemon Posts: 2,973
    edited 2015-04-13 13:18
    I have also seen the following:
    DIRA |= (1 << X_STEP);
    OUTA |= (1 << X_DIRECTION);
    

    I currently have this:
    DIRA |= 1 << X_STEP;
    OUTA |= 1 << X_DIRECTION;
    

    Should these be changed also?[/QUOTE]

    I wouldn't change them. The equals operator (or any of its siblings, like |=, &=, ^=) will always be evaluated last - that's a given in any language.
  • Dave HeinDave Hein Posts: 6,347
    edited 2015-04-13 13:25
    There's no ambiguity in the |= statements. The parentheses aren't needed there, but you can certainly use them. When in doubt add parentheses. Another place I use them is when a #define contains an expression. You can get in trouble if a defined symbol is used in an expression that changes the order of computation, such as in the following example.
    #define VALUE  2+3
    ...
    x = 4*VALUE;
    x = VALUE*4;
    x = 4*(VALUE);
    
    The three statements produce three different results for x.
  • idbruceidbruce Posts: 6,197
    edited 2015-04-13 13:33
    Thanks Dave and David
    Another place I use them is when a #define contains an expression. You can get in trouble if a defined symbol is used in an expression that changes the order of computation

    Yea, those defines really had me going in circles yesterday, but I knew better... My own stupidity, caused me grief. If it was not for the memory size issue, I would probably go back and try Teacup with my altered defines, but I do not see much point in it.
  • Dave HeinDave Hein Posts: 6,347
    edited 2015-04-13 13:41
    Bruce, I think you are using the right approach now. The Teacup software has some nice features, but it's got too much AVR junk in it to make it a clean port to the Propeller.
  • idbruceidbruce Posts: 6,197
    edited 2015-04-13 17:21
    Dave
    Bruce, I think you are using the right approach now. The Teacup software has some nice features, but it's got too much AVR junk in it to make it a clean port to the Propeller.

    I just feel like I am trying to reinvent the wheel, but then again, we really need CNC and 3D printer firmware for the Propeller. I just don't believe that I am smart enough to pull it off all by myself. LOOKAHEAD will be a critical and very difficult component as well as other algorithms that will need to be figured out.

    I can surely handle the simple stuff, to make a good skeleton app, but it will definitely need some smart thinkers to make it desirable firmware.
  • DavidZemonDavidZemon Posts: 2,973
    edited 2015-04-14 11:20
    idbruce wrote: »
    we really need CNC and 3D printer firmware for the Propeller

    If this is your inspiration, a belief in a need, why not work with davidsaunders to port his code base to C++? His Spin examples could be converted to C++ running in CMM mode (equivalent size and speed) and his DAT sections remain as assembly drivers (.S files). I would think this would likely result in a single, better piece of firmware than either of you two can produce by yourselves.
Sign In or Register to comment.