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