Skip to content
Snippets Groups Projects
Commit aabb3b72 authored by Jake Read's avatar Jake Read
Browse files

accel ticker OK

parent d389fccf
Branches
No related tags found
No related merge requests found
......@@ -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;
......
......@@ -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)
......
......@@ -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);
}
}
}
......
......@@ -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 = 0;
stepper->speed_period = 0;
stepper->accel_period = 0;
stepper->last_step = 0;
stepper->last_accel = 0;
stepper->speed = 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){
......@@ -68,9 +64,13 @@ 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 {
// a real move
......@@ -86,6 +86,8 @@ void stepper_new_block(uint8_t *packet, stepper_t *stepper, int32_t steps, uint3
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
......@@ -109,6 +111,9 @@ void stepper_new_block(uint8_t *packet, stepper_t *stepper, int32_t steps, uint3
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,8 +122,7 @@ 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
// 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){
......@@ -128,8 +132,9 @@ 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){
......@@ -137,48 +142,26 @@ void stepper_updatesteps(stepper_t *stepper){
} 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;
}
// 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 ++;
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
......@@ -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){
......
......@@ -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 {
......@@ -43,16 +46,12 @@ typedef struct {
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);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment