From aabb3b728813a508e09a57e948754c4e98eeabd2 Mon Sep 17 00:00:00 2001 From: Jake <jake.read@cba.mit.edu> Date: Fri, 22 Jun 2018 00:21:06 -0400 Subject: [PATCH] accel ticker OK --- .../atkstepper23/atkstepper23/atkhandler.c | 1 - embedded/atkstepper23/atkstepper23/atkport.c | 2 - embedded/atkstepper23/atkstepper23/main.c | 13 +- embedded/atkstepper23/atkstepper23/stepper.c | 131 +++++++++--------- embedded/atkstepper23/atkstepper23/stepper.h | 14 +- 5 files changed, 79 insertions(+), 82 deletions(-) diff --git a/embedded/atkstepper23/atkstepper23/atkhandler.c b/embedded/atkstepper23/atkstepper23/atkhandler.c index 6fb720b..85c6ce9 100644 --- a/embedded/atkstepper23/atkstepper23/atkhandler.c +++ b/embedded/atkstepper23/atkstepper23/atkhandler.c @@ -56,7 +56,6 @@ void atk_handle_packet(uint8_t *packet, uint8_t length){ uint32_t deccellength = ((int32_t)packet[i+17] << 24) | ((int32_t)packet[i+18] << 16) | (int32_t)(packet[i+19] << 8) | (int32_t)packet[i+20]; // do the business i += 21; - stepper_new_block(packet, &stepper, steps, entryspeed, accel, accellength, deccellength); } break; diff --git a/embedded/atkstepper23/atkstepper23/atkport.c b/embedded/atkstepper23/atkstepper23/atkport.c index 0e754bb..65b80e0 100644 --- a/embedded/atkstepper23/atkstepper23/atkport.c +++ b/embedded/atkstepper23/atkstepper23/atkport.c @@ -36,11 +36,9 @@ void atkport_scan(atkport_t *atkp, uint32_t maxpackets){ } else { // pull bytes out of buffer into the packet structure atkp->packets[atkp->packet_num][atkp->packet_position] = rb_get(atkp->uart->rbrx); - uart_sendchar_polled(&up1, atkp->packets[atkp->packet_num][atkp->packet_position]); atkp->packet_position ++; // now segment, point to them if(atkp->packet_position >= atkp->packets[atkp->packet_num][0]){ - pin_toggle(&stlerr); // length is 1st byte, like array[n] not array[n-1] // now volley for next pass // packet_num is index of head of packet buffer (just an array) diff --git a/embedded/atkstepper23/atkstepper23/main.c b/embedded/atkstepper23/atkstepper23/main.c index b9b7873..52521e2 100644 --- a/embedded/atkstepper23/atkstepper23/main.c +++ b/embedded/atkstepper23/atkstepper23/main.c @@ -108,19 +108,18 @@ int main(void) pin_init(&stlclk, &PORTF, PIN7_bm, 7, 1); pin_init(&stlerr, &PORTF, PIN6_bm, 6, 1); pin_set(&stlerr); - + pin_set(&stlclk); + // stepper business stephardware_init(); - // runtime globals - uint32_t tck = 0; - tmc26_start(&tmc); tmc26_enable(&tmc); tickers_init(); - - pin_set(&stlclk); + + // runtime globals + uint32_t tck = 0; while (1) { @@ -131,7 +130,7 @@ int main(void) // this modulo op is slow AF // that means streamlining atkport_scan without modulos is probably a rad thing if(!(fastModulo(tck, 16384))){ - pin_toggle(&stlclk); + //pin_toggle(&stlclk); } } } diff --git a/embedded/atkstepper23/atkstepper23/stepper.c b/embedded/atkstepper23/atkstepper23/stepper.c index 7cfe270..656ab0b 100644 --- a/embedded/atkstepper23/atkstepper23/stepper.c +++ b/embedded/atkstepper23/atkstepper23/stepper.c @@ -1,9 +1,9 @@ /* - * stepper.c - * - * Created: 2/17/2018 5:39:34 PM - * Author: Jake - */ +* stepper.c +* +* Created: 2/17/2018 5:39:34 PM +* Author: Jake +*/ #include "stepper.h" #include "hardware.h" @@ -11,7 +11,7 @@ #include "atkhandler.h" #include "fastmath.h" -void stepper_init(stepper_t *stepper, pin_t *step_pin, pin_t *dir_pin){ +void stepper_init(stepper_t *stepper, pin_t *step_pin, pin_t *dir_pin){ stepper->step_pin = step_pin; stepper->dir_pin = dir_pin; @@ -19,22 +19,18 @@ void stepper_init(stepper_t *stepper, pin_t *step_pin, pin_t *dir_pin){ } void stepper_reset(stepper_t *stepper){ - stepper->speed_period = 0; - stepper->accel_period = 0; - stepper->blockhead = 0; stepper->blocktail = 0; stepper->blocksize = BLOCKS_QUEUE_SIZE; + + stepper->speed_period = 0; + stepper->accel_period = 0; stepper->speed = 0; - stepper->last_step = 0; - stepper->last_accel = 0; - stepper->position_ticks = 0; stepper->position_accel_to = 0; stepper->position_deccel_from = 0; - stepper->position_ticks_end = 0; } void stepper_steps(stepper_t *stepper, int32_t steps, uint32_t speed){ @@ -55,7 +51,7 @@ void stepper_new_block(uint8_t *packet, stepper_t *stepper, int32_t steps, uint3 // still need to check this (accel < 3) ? accel = 3 : (0); (accel > 187500) ? accel = 187500 : (0); - // but we're going to wrap everything else in update() to avoid accel etc checks, we're just going to be counting + // but we're going to wrap everything else in update() to avoid accel etc checks, we're just going to be counting stepper->block[stepper->blockhead].entry_speed = accel; stepper->block[stepper->blockhead].position_end = abs(steps); stepper->block[stepper->blockhead].accel_period = STEPTICKER_ONE_SECOND; @@ -68,15 +64,19 @@ void stepper_new_block(uint8_t *packet, stepper_t *stepper, int32_t steps, uint3 // if there are currently no steps to make, we're not sure about the current step frequency, we'll set the period // otherwise we're taking for granted that we've set this properly following the last move if(stepper->blockhead == stepper->blocktail){ + // could we just call stepper_update now? uint16_t newper = STEPTICKER_ONE_SECOND / accel; stepticker_newperiod(newper); stepticker_reset(); + uint16_t accper = 65536; // gets 16-bit truncated + accelticker_newperiod(accper); + accelticker_reset(); } - } else { + } else { // a real move stepper->block[stepper->blockhead].is_nomove = 0; - // TODO: should block the execution of this block while we do this, so that we + // TODO: should block the execution of this block while we do this, so that we // have an interrupt safe ringbuffer // enforce no div/0 @@ -84,14 +84,16 @@ void stepper_new_block(uint8_t *packet, stepper_t *stepper, int32_t steps, uint3 (entryspeed > 187500) ? entryspeed = 187500 : (0); // no faster than this pls, else underneat timer resolution // going to have to catch blocks which cause deceleration to 0 during deceleration phases ! stepper->block[stepper->blockhead].entry_speed = entryspeed; - + // do starting speed period + (accel < 3) ? accel = 3 : (0); + (accel > 187500) ? accel = 187500 : (0); stepper->block[stepper->blockhead].accel_period = STEPTICKER_ONE_SECOND / accel; // set dir if(steps < 0){ stepper->block[stepper->blockhead].dir = 0; - } else { + } else { stepper->block[stepper->blockhead].dir = 1; } @@ -104,11 +106,14 @@ void stepper_new_block(uint8_t *packet, stepper_t *stepper, int32_t steps, uint3 stepper->block[stepper->blockhead].is_new = 1; // if there are currently no steps to make, we're not sure about the current step frequency, we'll set the period - // otherwise we're taking for granted that we've set this properly following the last move + // otherwise we're taking for granted that we've set this properly following the last move if(stepper->blockhead == stepper->blocktail){ uint16_t newper = STEPTICKER_ONE_SECOND / entryspeed; stepticker_newperiod(newper); stepticker_reset(); + uint16_t accper = STEPTICKER_ONE_SECOND / accel; + accelticker_newperiod(accper); + accelticker_reset(); } } // increment block head ptr: should catch full queue HERE but not bothering @@ -117,9 +122,8 @@ void stepper_new_block(uint8_t *packet, stepper_t *stepper, int32_t steps, uint3 void stepper_updatesteps(stepper_t *stepper){ if(stepper->blockhead == stepper->blocktail){ - //pin_clear(&stlerr); - // bail, no steps to make, ringbuffer is empty - } else if(stepper->block[stepper->blocktail].position_end > stepper->position_ticks){ + // no steps to make, ringbuffer is empty + } else if(stepper->block[stepper->blocktail].position_end > stepper->position_ticks){ // we have somewhere to go if(stepper->block[stepper->blocktail].is_new){ // if we're just starting this block, set the speed @@ -128,58 +132,37 @@ void stepper_updatesteps(stepper_t *stepper){ stepticker_newperiod(stepper->speed_period); stepticker_reset(); - // time for accels, etc is now zero - stepper->time = 0; + // and set the accel ticker + accelticker_newperiod(stepper->block[stepper->blocktail].accel_period); + accelticker_reset(); // and set the dir if(stepper->block[stepper->blocktail].dir > 0){ pin_set(stepper->dir_pin); - } else { + } else { pin_clear(stepper->dir_pin); } - // and distance was 0'd after last move // and then clear this flag - stepper->block[stepper->blocktail].is_new = 0; - } else { - stepper->time += stepper->speed_period; + stepper->block[stepper->blocktail].is_new = 0; } - // check for acceleration or deceleration - // CASE: acceleration rate faster than step rate? - /* - definitely, the timer will only need to be setup to fire on the next step, - but TI suggests to use two timers, one for steps and another for acceleration... this makes some sense - in this case, when acceleration rate is greater than step rate, we can set new periods of the step timer from the accel isr - and when we update period when it's already over that period, that will automatically call the isr - */ - if(stepper->position_ticks < stepper->block[stepper->blocktail].position_accel_to){ - // we're accelerating! - if(stepper->time - stepper->last_accel > stepper->block[stepper->blocktail].accel_period){ - stepper->speed += 1; - (stepper->speed > 187500) ? stepper->speed = 187500 : (0); // max speed due to timer res - stepper->speed_period = STEPTICKER_ONE_SECOND / stepper->speed; - stepticker_newperiod(stepper->speed_period); - stepper->last_accel = stepper->time; - } - } else if(stepper->position_ticks > stepper->block[stepper->blocktail].position_deccel_from){ - // we're decelerating! - if(stepper->time - stepper->last_accel > stepper->block[stepper->blocktail].accel_period){ - stepper->speed -= 1; - (stepper->speed < 3) ? stepper->speed = 3 : (0); // min speed due to timer res - stepper->speed_period = STEPTICKER_ONE_SECOND / stepper->speed; - stepticker_newperiod(stepper->speed_period); - stepper->last_accel = stepper->time; - } - } - // if there's steps to make, and this timer is firing, it's time to step! if(!stepper->block[stepper->blocktail].is_nomove){ pin_toggle(stepper->step_pin); } + stepper->position_ticks ++; - } else { + if(stepper->position_ticks < stepper->block[stepper->blocktail].position_accel_to){ + stepper->accelstate = STEP_ACCELSTATE_ACCEL; + } else if (stepper->position_ticks > stepper->block[stepper->blocktail].position_deccel_from){ + stepper->accelstate = STEP_ACCELSTATE_DECEL; + } else { + stepper->accelstate = STEP_ACCELSTATE_CRUISE; + } + + } else { // looks a lot like we're done here // send a reply for windowed transmission // this is dirty because we're passing the packet (referenced here in the ringbuffer) by reference, @@ -190,7 +173,7 @@ void stepper_updatesteps(stepper_t *stepper){ if(stepper->block[stepper->blocktail].is_nomove){ reply[0] = 131; reply[1] = 12; - } else { + } else { reply[0] = 131; reply[1] = 24; } @@ -203,12 +186,32 @@ void stepper_updatesteps(stepper_t *stepper){ } void stepper_updateaccel(stepper_t *stepper){ - + // check for acceleration or deceleration + switch (stepper->accelstate){ + case STEP_ACCELSTATE_ACCEL: + stepper->speed ++; + (stepper->speed > 187500) ? stepper->speed = 187500 : (0); // max speed due to timer res + stepper->speed_period = STEPTICKER_ONE_SECOND / stepper->speed; + stepticker_newperiod(stepper->speed_period); + break; + case STEP_ACCELSTATE_DECEL: + stepper->speed --; + (stepper->speed < 3) ? stepper->speed = 3 : (0); // min speed due to timer res + stepper->speed_period = STEPTICKER_ONE_SECOND / stepper->speed; + stepticker_newperiod(stepper->speed_period); + break; + case STEP_ACCELSTATE_CRUISE: + (0); + break; + default: + (0); + break; + } } void stepticker_newperiod(uint16_t per){ - TCC0.PERL = (uint8_t) per; - TCC0.PERH = (uint8_t) (per >> 8); + TCC0.PERBUFL = (uint8_t) per; + TCC0.PERBUFH = (uint8_t) (per >> 8); } void stepticker_reset(void){ @@ -216,8 +219,8 @@ void stepticker_reset(void){ } void accelticker_newperiod(uint16_t per){ - TCC1.PERL = (uint8_t) per; - TCC1.PERH = (uint8_t) (per >> 8); + TCC1.PERBUFL = (uint8_t) per; + TCC1.PERBUFH = (uint8_t) (per >> 8); } void accelticker_reset(void){ diff --git a/embedded/atkstepper23/atkstepper23/stepper.h b/embedded/atkstepper23/atkstepper23/stepper.h index 0b70b17..562f8c3 100644 --- a/embedded/atkstepper23/atkstepper23/stepper.h +++ b/embedded/atkstepper23/atkstepper23/stepper.h @@ -13,6 +13,9 @@ #define BLOCKS_QUEUE_SIZE 16 #define STEPTICKER_ONE_SECOND 187500 // one tick of timer is 5.3-- us +#define STEP_ACCELSTATE_CRUISE 0 +#define STEP_ACCELSTATE_ACCEL 1 +#define STEP_ACCELSTATE_DECEL 2 // one movement typedef struct { @@ -42,17 +45,13 @@ typedef struct { uint8_t blockhead; uint8_t blocktail; uint8_t blocksize; - - // tracking time (using single timer, updates) - unsigned long time; - + // tracking time periods uint16_t speed_period; // meaning we have a min. step speed of STEPTICKER_ONE_SECOND / 2^16 ( ~ 2.86 s/s) - unsigned long accel_period; + uint16_t accel_period; // tracking time for updates - unsigned long last_step; - unsigned long last_accel; + uint8_t accelstate; // have to track speed to update accel uint32_t speed; @@ -61,7 +60,6 @@ typedef struct { uint32_t position_ticks; uint32_t position_accel_to; uint32_t position_deccel_from; - uint32_t position_ticks_end; }stepper_t; void stepper_init(stepper_t *stepper, pin_t *step_pin, pin_t *dir_pin); -- GitLab