time to save, looks like the DDA is working! NOTE: endstops disabled in dda.c lines 291-296 in this revision
This commit is contained in:
parent
fbeafe3ba7
commit
b6b2951db7
|
|
@ -32,14 +32,15 @@ F_CPU = 16000000L
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
ARCH = avr-
|
ARCH = avr-
|
||||||
OPTIMIZE = -Os
|
OPTIMIZE = -Os -ffunction-sections -finline-functions-called-once
|
||||||
CFLAGS = -g -Wall -Wstrict-prototypes $(OPTIMIZE) -mmcu=$(MCU_TARGET) -DF_CPU=$(F_CPU) $(DEFS) -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -ffunction-sections -save-temps
|
# OPTIMIZE = -O0
|
||||||
LDFLAGS = -Wl,--as-needed -Wl,--gc-sections -finline-functions-called-once
|
CFLAGS = -g -Wall -Wstrict-prototypes $(OPTIMIZE) -mmcu=$(MCU_TARGET) -DF_CPU=$(F_CPU) $(DEFS) -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -save-temps
|
||||||
|
LDFLAGS = -Wl,--as-needed -Wl,--gc-sections
|
||||||
|
|
||||||
CC = $(ARCH)gcc
|
CC = $(ARCH)gcc
|
||||||
OBJDUMP = $(ARCH)objdump
|
OBJDUMP = $(ARCH)objdump
|
||||||
OBJCOPY = $(ARCH)objcopy
|
OBJCOPY = $(ARCH)objcopy
|
||||||
AVRDUDE = avrdude -F
|
AVRDUDE = avrdude
|
||||||
|
|
||||||
PROGPORT = /dev/arduino
|
PROGPORT = /dev/arduino
|
||||||
PROGBAUD = 19200
|
PROGBAUD = 19200
|
||||||
|
|
|
||||||
|
|
@ -13,14 +13,16 @@
|
||||||
|
|
||||||
#define _READ(IO) (IO ## _RPORT & MASK(IO ## _PIN))
|
#define _READ(IO) (IO ## _RPORT & MASK(IO ## _PIN))
|
||||||
#define _WRITE(IO, v) if (v) { IO ## _WPORT |= MASK(IO ## _PIN); } else { IO ## _WPORT &= ~MASK(IO ## _PIN); }
|
#define _WRITE(IO, v) if (v) { IO ## _WPORT |= MASK(IO ## _PIN); } else { IO ## _WPORT &= ~MASK(IO ## _PIN); }
|
||||||
|
#define _TOGGLE(IO) (IO ## _RPORT = MASK(IO ## _PIN))
|
||||||
|
|
||||||
#define _SET_INPUT(IO) (IO ## _DDR |= MASK(IO ## _PIN))
|
#define _SET_INPUT(IO) (IO ## _DDR &= ~MASK(IO ## _PIN))
|
||||||
#define _SET_OUTPUT(IO) (IO ## _DDR &= ~MASK(IO ## _PIN))
|
#define _SET_OUTPUT(IO) (IO ## _DDR |= MASK(IO ## _PIN))
|
||||||
|
|
||||||
// why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
|
// why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
|
||||||
|
|
||||||
#define READ(IO) _READ(IO)
|
#define READ(IO) _READ(IO)
|
||||||
#define WRITE(IO, v) _WRITE(IO, v)
|
#define WRITE(IO, v) _WRITE(IO, v)
|
||||||
|
#define TOGGLE(IO) _TOGGLE(IO)
|
||||||
#define SET_INPUT(IO) _SET_INPUT(IO)
|
#define SET_INPUT(IO) _SET_INPUT(IO)
|
||||||
#define SET_OUTPUT(IO) _SET_OUTPUT(IO)
|
#define SET_OUTPUT(IO) _SET_OUTPUT(IO)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,17 +21,21 @@ volatile uint8_t clock_flag_250ms = 0;
|
||||||
void clock_setup() {
|
void clock_setup() {
|
||||||
// use system clock
|
// use system clock
|
||||||
ASSR = 0;
|
ASSR = 0;
|
||||||
|
|
||||||
// no compare match, CTC mode
|
// no compare match, CTC mode
|
||||||
TCCR2A = MASK(WGM21);
|
TCCR2A = MASK(WGM21);
|
||||||
|
|
||||||
// 128 prescaler (16MHz / 128 = 125KHz)
|
// 128 prescaler (16MHz / 128 = 125KHz)
|
||||||
TCCR2B = MASK(CS22) | MASK(CS20);
|
TCCR2B = MASK(CS22) | MASK(CS20);
|
||||||
|
|
||||||
// 125KHz / 125 = 1KHz for a 1ms tick rate
|
// 125KHz / 125 = 1KHz for a 1ms tick rate
|
||||||
OCR2A = 125;
|
OCR2A = 125;
|
||||||
|
|
||||||
// interrupt on overflow, when counter reaches OCR2A
|
// interrupt on overflow, when counter reaches OCR2A
|
||||||
TIMSK2 |= MASK(TOIE2);
|
TIMSK2 |= MASK(OCIE2A);
|
||||||
}
|
}
|
||||||
|
|
||||||
ISR(TIMER2_OVF_vect) {
|
ISR(TIMER2_COMPA_vect) {
|
||||||
// global clock
|
// global clock
|
||||||
clock++;
|
clock++;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,5 +9,6 @@ uint32_t clock_read(void);
|
||||||
extern volatile uint8_t clock_flag_250ms;
|
extern volatile uint8_t clock_flag_250ms;
|
||||||
|
|
||||||
#define CLOCK_FLAG_250MS_TEMPCHECK 1
|
#define CLOCK_FLAG_250MS_TEMPCHECK 1
|
||||||
|
#define CLOCK_FLAG_250MS_REPORT 2
|
||||||
|
|
||||||
#endif /* _CLOCK_H */
|
#endif /* _CLOCK_H */
|
||||||
|
|
|
||||||
136
mendel/dda.c
136
mendel/dda.c
|
|
@ -3,6 +3,16 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
#include "serial.h"
|
||||||
|
#include "sermsg.h"
|
||||||
|
|
||||||
|
#ifndef ABS
|
||||||
|
#define ABS(v) (((v) >= 0)?(v):(-(v)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ABSDELTA
|
||||||
|
#define ABSDELTA(a, b) (((a) >= (b))?((a) - (b)):((b) - (a)))
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
move queue
|
move queue
|
||||||
|
|
@ -16,8 +26,8 @@ DDA movebuffer[MOVEBUFFER_SIZE];
|
||||||
position tracking
|
position tracking
|
||||||
*/
|
*/
|
||||||
|
|
||||||
TARGET startpoint = { 0, 0, 0, 0, 0 };
|
TARGET startpoint = { 0, 0, 0, 0, FEEDRATE_SLOW_Z };
|
||||||
TARGET current_position = { 0, 0, 0, 0, 0 };
|
TARGET current_position = { 0, 0, 0, 0, FEEDRATE_SLOW_Z };
|
||||||
|
|
||||||
uint8_t queue_full() {
|
uint8_t queue_full() {
|
||||||
if (mb_tail == 0)
|
if (mb_tail == 0)
|
||||||
|
|
@ -26,6 +36,10 @@ uint8_t queue_full() {
|
||||||
return mb_head == (mb_tail - 1);
|
return mb_head == (mb_tail - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t queue_empty() {
|
||||||
|
return (mb_tail == mb_head) && !movebuffer[mb_tail].live;
|
||||||
|
}
|
||||||
|
|
||||||
void enqueue(TARGET *t) {
|
void enqueue(TARGET *t) {
|
||||||
while (queue_full())
|
while (queue_full())
|
||||||
delay(WAITING_DELAY);
|
delay(WAITING_DELAY);
|
||||||
|
|
@ -43,6 +57,7 @@ void next_move() {
|
||||||
// queue is empty
|
// queue is empty
|
||||||
disable_steppers();
|
disable_steppers();
|
||||||
setTimer(DEFAULT_TICK);
|
setTimer(DEFAULT_TICK);
|
||||||
|
disableTimerInterrupt();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
uint8_t t = mb_tail;
|
uint8_t t = mb_tail;
|
||||||
|
|
@ -122,6 +137,12 @@ uint32_t approx_distance_3( int32_t dx, int32_t dy, int32_t dz )
|
||||||
return (( approx + 512 ) >> 10 );
|
return (( approx + 512 ) >> 10 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t abs32(int32_t v) {
|
||||||
|
if (v < 0)
|
||||||
|
return -v;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
CREATE
|
CREATE
|
||||||
*/
|
*/
|
||||||
|
|
@ -129,18 +150,14 @@ uint32_t approx_distance_3( int32_t dx, int32_t dy, int32_t dz )
|
||||||
void dda_create(TARGET *target, DDA *dda) {
|
void dda_create(TARGET *target, DDA *dda) {
|
||||||
uint32_t distance;
|
uint32_t distance;
|
||||||
|
|
||||||
// we start at the previous endpoint
|
// we end at the passed target
|
||||||
// memcpy(&dda->currentpoint, &startpoint, sizeof(TARGET));
|
|
||||||
// we end at the passed command's endpoint
|
|
||||||
memcpy(&dda->endpoint, target, sizeof(TARGET));
|
memcpy(&dda->endpoint, target, sizeof(TARGET));
|
||||||
|
|
||||||
dda->x_delta = dda->endpoint.X - startpoint.X;
|
dda->x_delta = abs32(dda->endpoint.X - startpoint.X);
|
||||||
dda->y_delta = dda->endpoint.Y - startpoint.Y;
|
dda->y_delta = abs32(dda->endpoint.Y - startpoint.Y);
|
||||||
dda->z_delta = dda->endpoint.Z - startpoint.Z;
|
dda->z_delta = abs32(dda->endpoint.Z - startpoint.Z);
|
||||||
// always relative
|
dda->e_delta = abs32(dda->endpoint.E - startpoint.E);
|
||||||
dda->e_delta = dda->endpoint.E;
|
dda->f_delta = abs32(dda->endpoint.F - startpoint.F);
|
||||||
// always absolute
|
|
||||||
dda->f_delta = dda->endpoint.F - startpoint.F;
|
|
||||||
|
|
||||||
// since it's unusual to combine X, Y and Z changes in a single move on reprap, check if we can use simpler approximations before trying the full 3d approximation.
|
// since it's unusual to combine X, Y and Z changes in a single move on reprap, check if we can use simpler approximations before trying the full 3d approximation.
|
||||||
if (dda->z_delta == 0)
|
if (dda->z_delta == 0)
|
||||||
|
|
@ -163,22 +180,27 @@ void dda_create(TARGET *target, DDA *dda) {
|
||||||
|
|
||||||
if (dda->e_delta > dda->total_steps)
|
if (dda->e_delta > dda->total_steps)
|
||||||
dda->total_steps = dda->e_delta;
|
dda->total_steps = dda->e_delta;
|
||||||
if (dda->f_delta > dda->total_steps)
|
|
||||||
dda->total_steps = dda->f_delta;
|
|
||||||
|
|
||||||
if (dda->total_steps == 0)
|
if (dda->total_steps == 0) {
|
||||||
dda->nullmove = 1;
|
dda->nullmove = 1;
|
||||||
|
// copy F in case we're doing a null move speed change
|
||||||
|
startpoint.F = dda->endpoint.F;
|
||||||
|
current_position.F = dda->endpoint.F;
|
||||||
|
}
|
||||||
|
|
||||||
if (dda->f_delta > dda->total_steps) {
|
if (dda->f_delta > dda->total_steps) {
|
||||||
dda->f_scale = dda->f_delta / dda->total_steps;
|
dda->f_scale = dda->f_delta / dda->total_steps;
|
||||||
if (dda->f_scale > 3) {
|
if (dda->f_scale > 3) {
|
||||||
dda->f_delta /= dda->f_scale;
|
dda->f_delta = dda->total_steps;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dda->f_scale = 1;
|
dda->f_scale = 1;
|
||||||
dda->total_steps = dda->f_delta;
|
dda->total_steps = dda->f_delta;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
dda->f_scale = 1;
|
||||||
|
}
|
||||||
|
|
||||||
dda->x_direction = (dda->endpoint.X > startpoint.X)?1:0;
|
dda->x_direction = (dda->endpoint.X > startpoint.X)?1:0;
|
||||||
dda->y_direction = (dda->endpoint.Y > startpoint.Y)?1:0;
|
dda->y_direction = (dda->endpoint.Y > startpoint.Y)?1:0;
|
||||||
|
|
@ -200,6 +222,9 @@ void dda_create(TARGET *target, DDA *dda) {
|
||||||
|
|
||||||
// make sure we're not running
|
// make sure we're not running
|
||||||
dda->live = 0;
|
dda->live = 0;
|
||||||
|
|
||||||
|
// fire up
|
||||||
|
enableTimerInterrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -226,14 +251,23 @@ void dda_start(DDA *dda) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uint8_t can_step(uint8_t min, uint8_t max, int32_t current, int32_t target, uint8_t dir) {
|
uint8_t can_step(uint8_t min, uint8_t max, int32_t current, int32_t target, uint8_t dir) {
|
||||||
if (target == current)
|
if (current == target)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (min && !dir)
|
if (dir) {
|
||||||
return 0;
|
// forwards/positive
|
||||||
|
if (max)
|
||||||
if (max && dir)
|
return 0;
|
||||||
return 0;
|
if (current > target)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// backwards/negative
|
||||||
|
if (min)
|
||||||
|
return 0;
|
||||||
|
if (target > current)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return 255;
|
return 255;
|
||||||
}
|
}
|
||||||
|
|
@ -251,10 +285,15 @@ void dda_step(DDA *dda) {
|
||||||
#define F_CAN_STEP 16
|
#define F_CAN_STEP 16
|
||||||
#define REAL_MOVE 32
|
#define REAL_MOVE 32
|
||||||
|
|
||||||
|
WRITE(SCK, 1);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
step_option |= can_step(x_min(), x_max(), current_position.X, dda->endpoint.X, dda->x_direction) & X_CAN_STEP;
|
// step_option |= can_step(x_min(), x_max(), current_position.X, dda->endpoint.X, dda->x_direction) & X_CAN_STEP;
|
||||||
step_option |= can_step(y_min(), y_max(), current_position.Y, dda->endpoint.Y, dda->y_direction) & Y_CAN_STEP;
|
// step_option |= can_step(y_min(), y_max(), current_position.Y, dda->endpoint.Y, dda->y_direction) & Y_CAN_STEP;
|
||||||
step_option |= can_step(z_min(), z_max(), current_position.Z, dda->endpoint.Z, dda->z_direction) & Z_CAN_STEP;
|
// step_option |= can_step(z_min(), z_max(), current_position.Z, dda->endpoint.Z, dda->z_direction) & Z_CAN_STEP;
|
||||||
|
step_option |= can_step(0 , 0 , current_position.X, dda->endpoint.X, dda->x_direction) & X_CAN_STEP;
|
||||||
|
step_option |= can_step(0 , 0 , current_position.Y, dda->endpoint.Y, dda->y_direction) & Y_CAN_STEP;
|
||||||
|
step_option |= can_step(0 , 0 , current_position.Z, dda->endpoint.Z, dda->z_direction) & Z_CAN_STEP;
|
||||||
step_option |= can_step(0 , 0 , current_position.E, dda->endpoint.E, dda->e_direction) & E_CAN_STEP;
|
step_option |= can_step(0 , 0 , current_position.E, dda->endpoint.E, dda->e_direction) & E_CAN_STEP;
|
||||||
step_option |= can_step(0 , 0 , current_position.F, dda->endpoint.F, dda->f_direction) & F_CAN_STEP;
|
step_option |= can_step(0 , 0 , current_position.F, dda->endpoint.F, dda->f_direction) & F_CAN_STEP;
|
||||||
|
|
||||||
|
|
@ -264,13 +303,12 @@ void dda_step(DDA *dda) {
|
||||||
step_option |= REAL_MOVE;
|
step_option |= REAL_MOVE;
|
||||||
|
|
||||||
x_step();
|
x_step();
|
||||||
|
|
||||||
dda->x_counter += dda->total_steps;
|
|
||||||
|
|
||||||
if (dda->x_direction)
|
if (dda->x_direction)
|
||||||
current_position.X++;
|
current_position.X++;
|
||||||
else
|
else
|
||||||
current_position.X--;
|
current_position.X--;
|
||||||
|
|
||||||
|
dda->x_counter += dda->total_steps;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -280,13 +318,12 @@ void dda_step(DDA *dda) {
|
||||||
step_option |= REAL_MOVE;
|
step_option |= REAL_MOVE;
|
||||||
|
|
||||||
y_step();
|
y_step();
|
||||||
|
|
||||||
dda->y_counter += dda->total_steps;
|
|
||||||
|
|
||||||
if (dda->y_direction)
|
if (dda->y_direction)
|
||||||
current_position.Y++;
|
current_position.Y++;
|
||||||
else
|
else
|
||||||
current_position.Y--;
|
current_position.Y--;
|
||||||
|
|
||||||
|
dda->y_counter += dda->total_steps;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -296,13 +333,12 @@ void dda_step(DDA *dda) {
|
||||||
step_option |= REAL_MOVE;
|
step_option |= REAL_MOVE;
|
||||||
|
|
||||||
z_step();
|
z_step();
|
||||||
|
|
||||||
dda->z_counter += dda->total_steps;
|
|
||||||
|
|
||||||
if (dda->z_direction)
|
if (dda->z_direction)
|
||||||
current_position.Z++;
|
current_position.Z++;
|
||||||
else
|
else
|
||||||
current_position.Z--;
|
current_position.Z--;
|
||||||
|
|
||||||
|
dda->z_counter += dda->total_steps;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -312,13 +348,12 @@ void dda_step(DDA *dda) {
|
||||||
step_option |= REAL_MOVE;
|
step_option |= REAL_MOVE;
|
||||||
|
|
||||||
e_step();
|
e_step();
|
||||||
|
|
||||||
dda->e_counter += dda->total_steps;
|
|
||||||
|
|
||||||
if (dda->e_direction)
|
if (dda->e_direction)
|
||||||
current_position.E++;
|
current_position.E++;
|
||||||
else
|
else
|
||||||
current_position.E--;
|
current_position.E--;
|
||||||
|
|
||||||
|
dda->e_counter += dda->total_steps;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -328,13 +363,32 @@ void dda_step(DDA *dda) {
|
||||||
|
|
||||||
dda->f_counter += dda->total_steps;
|
dda->f_counter += dda->total_steps;
|
||||||
|
|
||||||
if (dda->f_direction)
|
if (dda->f_scale == 0)
|
||||||
|
dda->f_scale = 1;
|
||||||
|
|
||||||
|
if (dda->f_direction) {
|
||||||
current_position.F += dda->f_scale;
|
current_position.F += dda->f_scale;
|
||||||
else
|
if (current_position.F > dda->endpoint.F)
|
||||||
|
current_position.F = dda->endpoint.F;
|
||||||
|
}
|
||||||
|
else {
|
||||||
current_position.F -= dda->f_scale;
|
current_position.F -= dda->f_scale;
|
||||||
|
if (current_position.F < dda->endpoint.F)
|
||||||
|
current_position.F = dda->endpoint.F;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while ( ((step_option & REAL_MOVE ) == 0) &&
|
|
||||||
|
serial_writechar('[');
|
||||||
|
serwrite_uint16(dda->f_scale);
|
||||||
|
serial_writechar(',');
|
||||||
|
serwrite_int32(current_position.F);
|
||||||
|
serial_writechar('/');
|
||||||
|
serwrite_int32(dda->endpoint.F);
|
||||||
|
serial_writechar('#');
|
||||||
|
serwrite_uint32(dda->move_duration);
|
||||||
|
serial_writechar(']');
|
||||||
|
} while ( ((step_option & REAL_MOVE ) == 0) &&
|
||||||
((step_option & F_CAN_STEP) != 0) );
|
((step_option & F_CAN_STEP) != 0) );
|
||||||
|
|
||||||
// turn off step outputs, hopefully they've been on long enough by now to register with the drivers
|
// turn off step outputs, hopefully they've been on long enough by now to register with the drivers
|
||||||
|
|
@ -346,4 +400,6 @@ void dda_step(DDA *dda) {
|
||||||
|
|
||||||
// if we could step, we're still running
|
// if we could step, we're still running
|
||||||
dda->live = (step_option & (X_CAN_STEP | Y_CAN_STEP | Z_CAN_STEP | E_CAN_STEP | F_CAN_STEP));
|
dda->live = (step_option & (X_CAN_STEP | Y_CAN_STEP | Z_CAN_STEP | E_CAN_STEP | F_CAN_STEP));
|
||||||
|
|
||||||
|
WRITE(SCK, 0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
12
mendel/dda.h
12
mendel/dda.h
|
|
@ -26,11 +26,11 @@ typedef struct {
|
||||||
uint8_t nullmove :1;
|
uint8_t nullmove :1;
|
||||||
uint8_t live :1;
|
uint8_t live :1;
|
||||||
|
|
||||||
int16_t x_delta;
|
uint32_t x_delta;
|
||||||
int16_t y_delta;
|
uint32_t y_delta;
|
||||||
int16_t z_delta;
|
uint32_t z_delta;
|
||||||
int16_t e_delta;
|
uint32_t e_delta;
|
||||||
int16_t f_delta;
|
uint32_t f_delta;
|
||||||
|
|
||||||
int32_t x_counter;
|
int32_t x_counter;
|
||||||
int32_t y_counter;
|
int32_t y_counter;
|
||||||
|
|
@ -51,7 +51,7 @@ extern TARGET startpoint;
|
||||||
extern TARGET current_position;
|
extern TARGET current_position;
|
||||||
|
|
||||||
uint8_t queue_full(void);
|
uint8_t queue_full(void);
|
||||||
inline uint8_t queue_empty(void) { return (mb_tail == mb_head) && !movebuffer[mb_tail].live; }
|
uint8_t queue_empty(void);
|
||||||
void enqueue(TARGET *t);
|
void enqueue(TARGET *t);
|
||||||
void next_move(void);
|
void next_move(void);
|
||||||
|
|
||||||
|
|
|
||||||
133
mendel/gcode.c
133
mendel/gcode.c
|
|
@ -14,13 +14,15 @@ decfloat read_digit;
|
||||||
|
|
||||||
#define PI 3.1415926535
|
#define PI 3.1415926535
|
||||||
|
|
||||||
|
const char alphabet[] = "GMXYZEFSP";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
utility functions
|
utility functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int8_t indexof(uint8_t c, char *string) {
|
int8_t indexof(uint8_t c, const char *string) {
|
||||||
int8_t i;
|
int8_t i;
|
||||||
for (i = 0;string[i];i++) {
|
for (i = 0; string[i]; i++) {
|
||||||
if (c == string[i])
|
if (c == string[i])
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
@ -29,7 +31,11 @@ int8_t indexof(uint8_t c, char *string) {
|
||||||
|
|
||||||
int32_t decfloat_to_int(decfloat *df, int32_t multiplicand, int32_t denominator) {
|
int32_t decfloat_to_int(decfloat *df, int32_t multiplicand, int32_t denominator) {
|
||||||
int32_t r = df->mantissa;
|
int32_t r = df->mantissa;
|
||||||
uint8_t e = df->exponent - 1;
|
uint8_t e = df->exponent;
|
||||||
|
|
||||||
|
// e=1 means we've seen a decimal point but no digits after it, and e=2 means we've seen a decimal point with one digit so it's too high by one if not zero
|
||||||
|
if (e)
|
||||||
|
e--;
|
||||||
|
|
||||||
// scale factors
|
// scale factors
|
||||||
if (multiplicand != 1)
|
if (multiplicand != 1)
|
||||||
|
|
@ -87,37 +93,44 @@ void SpecialMoveE(int32_t e, uint32_t f) {
|
||||||
|
|
||||||
void scan_char(uint8_t c) {
|
void scan_char(uint8_t c) {
|
||||||
static uint8_t last_field = 0;
|
static uint8_t last_field = 0;
|
||||||
static GCODE_COMMAND next_target = { 0, 0, 0, 0, { 0, 0, 0, 0, 0 } };
|
static GCODE_COMMAND next_target = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0 } };
|
||||||
|
|
||||||
// uppercase
|
// uppercase
|
||||||
if (c >= 'a' && c <= 'z')
|
if (c >= 'a' && c <= 'z')
|
||||||
c &= ~32;
|
c &= ~32;
|
||||||
|
|
||||||
// process field
|
// process field
|
||||||
if (indexof(c, "GMXYZEFSP\n") >= 0) {
|
if (last_field) {
|
||||||
if (last_field) {
|
if ((indexof(c, alphabet) >= 0) || (c == 10)) {
|
||||||
switch (last_field) {
|
switch (last_field) {
|
||||||
case 'G':
|
case 'G':
|
||||||
next_target.G = read_digit.mantissa;
|
next_target.G = read_digit.mantissa;
|
||||||
|
serwrite_uint8(next_target.G);
|
||||||
break;
|
break;
|
||||||
case 'M':
|
case 'M':
|
||||||
next_target.M = read_digit.mantissa;
|
next_target.M = read_digit.mantissa;
|
||||||
|
serwrite_uint8(next_target.M);
|
||||||
break;
|
break;
|
||||||
case 'X':
|
case 'X':
|
||||||
next_target.target.X = decfloat_to_int(&read_digit, STEPS_PER_MM_X, 1);
|
next_target.target.X = decfloat_to_int(&read_digit, STEPS_PER_MM_X, 1);
|
||||||
|
serwrite_int32(next_target.target.X);
|
||||||
break;
|
break;
|
||||||
case 'Y':
|
case 'Y':
|
||||||
next_target.target.Y = decfloat_to_int(&read_digit, STEPS_PER_MM_Y, 1);
|
next_target.target.Y = decfloat_to_int(&read_digit, STEPS_PER_MM_Y, 1);
|
||||||
|
serwrite_int32(next_target.target.Y);
|
||||||
break;
|
break;
|
||||||
case 'Z':
|
case 'Z':
|
||||||
next_target.target.Z = decfloat_to_int(&read_digit, STEPS_PER_MM_Z, 1);
|
next_target.target.Z = decfloat_to_int(&read_digit, STEPS_PER_MM_Z, 1);
|
||||||
|
serwrite_int32(next_target.target.Z);
|
||||||
break;
|
break;
|
||||||
case 'E':
|
case 'E':
|
||||||
next_target.target.E = decfloat_to_int(&read_digit, STEPS_PER_MM_E, 1);
|
next_target.target.E = decfloat_to_int(&read_digit, STEPS_PER_MM_E, 1);
|
||||||
|
serwrite_uint32(next_target.target.E);
|
||||||
break;
|
break;
|
||||||
case 'F':
|
case 'F':
|
||||||
// just save an integer value for F, we need move distance and n_steps to convert it to a useful value, so wait until we have those to convert it
|
// just save an integer value for F, we need move distance and n_steps to convert it to a useful value, so wait until we have those to convert it
|
||||||
next_target.target.F = read_digit.mantissa;
|
next_target.target.F = read_digit.mantissa;
|
||||||
|
serwrite_uint32(next_target.target.F);
|
||||||
break;
|
break;
|
||||||
case 'S':
|
case 'S':
|
||||||
// if this is temperature, multiply by 4 to convert to quarter-degree units
|
// if this is temperature, multiply by 4 to convert to quarter-degree units
|
||||||
|
|
@ -127,6 +140,7 @@ void scan_char(uint8_t c) {
|
||||||
next_target.S = decfloat_to_int(&read_digit, 4, 1);
|
next_target.S = decfloat_to_int(&read_digit, 4, 1);
|
||||||
else
|
else
|
||||||
next_target.S = decfloat_to_int(&read_digit, 1, 1);
|
next_target.S = decfloat_to_int(&read_digit, 1, 1);
|
||||||
|
serwrite_uint16(next_target.S);
|
||||||
break;
|
break;
|
||||||
case 'P':
|
case 'P':
|
||||||
// if this is dwell, multiply by 1 million to convert seconds to milliseconds
|
// if this is dwell, multiply by 1 million to convert seconds to milliseconds
|
||||||
|
|
@ -134,66 +148,103 @@ void scan_char(uint8_t c) {
|
||||||
next_target.P = decfloat_to_int(&read_digit, 1000, 1);
|
next_target.P = decfloat_to_int(&read_digit, 1000, 1);
|
||||||
else
|
else
|
||||||
next_target.P = decfloat_to_int(&read_digit, 1, 1);
|
next_target.P = decfloat_to_int(&read_digit, 1, 1);
|
||||||
|
serwrite_uint16(next_target.P);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
last_field = 0;
|
||||||
read_digit.sign = 0;
|
read_digit.sign = 0;
|
||||||
read_digit.mantissa = 0;
|
read_digit.mantissa = 0;
|
||||||
read_digit.exponent = 0;
|
read_digit.exponent = 0;
|
||||||
}
|
}
|
||||||
last_field = c;
|
}
|
||||||
|
|
||||||
|
// not in a comment?
|
||||||
|
if ((option_bitfield & OPTION_COMMENT) == 0) {
|
||||||
|
if (indexof(c, alphabet) >= 0) {
|
||||||
|
last_field = c;
|
||||||
|
serial_writechar(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
// process character
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
// each command is either G or M, so preserve previous G/M unless a new one has appeared
|
||||||
case 'G':
|
case 'G':
|
||||||
next_target.seen |= SEEN_G;
|
next_target.seen_G = 1;
|
||||||
|
next_target.seen_M = 0;
|
||||||
|
next_target.M = 0;
|
||||||
break;
|
break;
|
||||||
case 'M':
|
case 'M':
|
||||||
next_target.seen |= SEEN_M;
|
next_target.seen_M = 1;
|
||||||
|
next_target.seen_G = 0;
|
||||||
|
next_target.G = 0;
|
||||||
break;
|
break;
|
||||||
case 'X':
|
case 'X':
|
||||||
next_target.seen |= SEEN_X;
|
next_target.seen_X = 1;
|
||||||
break;
|
break;
|
||||||
case 'Y':
|
case 'Y':
|
||||||
next_target.seen |= SEEN_Y;
|
next_target.seen_Y = 1;
|
||||||
break;
|
break;
|
||||||
case 'Z':
|
case 'Z':
|
||||||
next_target.seen |= SEEN_Z;
|
next_target.seen_Z = 1;
|
||||||
break;
|
break;
|
||||||
case 'E':
|
case 'E':
|
||||||
next_target.seen |= SEEN_E;
|
next_target.seen_E = 1;
|
||||||
break;
|
break;
|
||||||
case 'F':
|
case 'F':
|
||||||
next_target.seen |= SEEN_F;
|
next_target.seen_F = 1;
|
||||||
break;
|
break;
|
||||||
case 'S':
|
case 'S':
|
||||||
next_target.seen |= SEEN_S;
|
next_target.seen_S = 1;
|
||||||
break;
|
break;
|
||||||
case 'P':
|
case 'P':
|
||||||
next_target.seen |= SEEN_P;
|
next_target.seen_P = 1;
|
||||||
break;
|
break;
|
||||||
case '\n':
|
|
||||||
// process
|
|
||||||
process_gcode_command(&next_target);
|
|
||||||
|
|
||||||
// save options
|
// comments
|
||||||
option_bitfield = next_target.option;
|
case ';':
|
||||||
|
option_bitfield |= OPTION_COMMENT;
|
||||||
// reset variables
|
|
||||||
last_field = 0;
|
|
||||||
next_target.seen = 0;
|
|
||||||
|
|
||||||
serial_writeblock((uint8_t *) "OK\n", 3);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// now for some numeracy
|
||||||
|
case '-':
|
||||||
|
read_digit.sign = 1;
|
||||||
|
// force sign to be at start of number
|
||||||
|
read_digit.exponent = 0;
|
||||||
|
read_digit.mantissa = 0;
|
||||||
|
break;
|
||||||
|
case '.':
|
||||||
|
if (read_digit.exponent == 0)
|
||||||
|
read_digit.exponent = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// can't do ranges in switch..case, so process actual digits here
|
||||||
|
if (c >= '0' && c <= '9') {
|
||||||
|
read_digit.mantissa = (read_digit.mantissa << 3) + (read_digit.mantissa << 1) + (c - '0');
|
||||||
|
if (read_digit.exponent)
|
||||||
|
read_digit.exponent++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// process digits
|
// got a command
|
||||||
else if (c == '-')
|
if (c == 10) {
|
||||||
read_digit.sign = 1;
|
serial_writechar(c);
|
||||||
else if ((c == '.') && (read_digit.exponent == 0))
|
// process
|
||||||
read_digit.exponent = 1;
|
process_gcode_command(&next_target);
|
||||||
else if (c >= '0' && c <= '9') {
|
|
||||||
read_digit.mantissa = (read_digit.mantissa << 3) + (read_digit.mantissa << 1) + (c - '0');
|
// save options
|
||||||
if (read_digit.exponent)
|
option_bitfield = next_target.option;
|
||||||
read_digit.exponent++;
|
option_bitfield &= ~OPTION_COMMENT;
|
||||||
|
|
||||||
|
// reset variables
|
||||||
|
last_field = 0;
|
||||||
|
next_target.seen_X = next_target.seen_Y = next_target.seen_Z = next_target.seen_E = next_target.seen_F = next_target.seen_S = next_target.seen_P = 0;
|
||||||
|
read_digit.sign = 0;
|
||||||
|
read_digit.mantissa = 0;
|
||||||
|
read_digit.exponent = 0;
|
||||||
|
|
||||||
|
serial_writestr_P(PSTR("OK\n"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -205,7 +256,7 @@ void process_gcode_command(GCODE_COMMAND *gcmd) {
|
||||||
gcmd->target.E += startpoint.E;
|
gcmd->target.E += startpoint.E;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gcmd->seen & SEEN_G) {
|
if (gcmd->seen_G) {
|
||||||
switch (gcmd->G) {
|
switch (gcmd->G) {
|
||||||
// G0 - rapid, unsynchronised motion
|
// G0 - rapid, unsynchronised motion
|
||||||
// since it would be a major hassle to force the dda to not synchronise, just provide a fast feedrate and hope it's close enough to what host expects
|
// since it would be a major hassle to force the dda to not synchronise, just provide a fast feedrate and hope it's close enough to what host expects
|
||||||
|
|
@ -306,12 +357,12 @@ void process_gcode_command(GCODE_COMMAND *gcmd) {
|
||||||
|
|
||||||
// TODO: spit an error
|
// TODO: spit an error
|
||||||
default:
|
default:
|
||||||
serial_writeblock((uint8_t *) "E: Bad G-code ", 14);
|
serial_writestr_P(PSTR("E: Bad G-code "));
|
||||||
serwrite_uint8(gcmd->G);
|
serwrite_uint8(gcmd->G);
|
||||||
serial_writechar('\n');
|
serial_writechar('\n');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (gcmd->seen & SEEN_M) {
|
if (gcmd->seen_M) {
|
||||||
switch (gcmd->M) {
|
switch (gcmd->M) {
|
||||||
// M101- extruder on
|
// M101- extruder on
|
||||||
case 101:
|
case 101:
|
||||||
|
|
@ -335,7 +386,7 @@ void process_gcode_command(GCODE_COMMAND *gcmd) {
|
||||||
// do .. while block here to provide local scope for temp
|
// do .. while block here to provide local scope for temp
|
||||||
do {
|
do {
|
||||||
uint16_t t = temp_get();
|
uint16_t t = temp_get();
|
||||||
serial_writeblock((uint8_t *) "T: ", 3);
|
serial_writestr_P(PSTR("T: "));
|
||||||
serwrite_uint16(t >> 2);
|
serwrite_uint16(t >> 2);
|
||||||
serial_writechar('.');
|
serial_writechar('.');
|
||||||
if (t & 3) {
|
if (t & 3) {
|
||||||
|
|
@ -366,7 +417,7 @@ void process_gcode_command(GCODE_COMMAND *gcmd) {
|
||||||
|
|
||||||
// TODO: spit an error
|
// TODO: spit an error
|
||||||
default:
|
default:
|
||||||
serial_writeblock((uint8_t *) "E: Bad M-code ", 14);
|
serial_writestr_P(PSTR("E: Bad M-code "));
|
||||||
serwrite_uint8(gcmd->M);
|
serwrite_uint8(gcmd->M);
|
||||||
serial_writechar('\n');
|
serial_writechar('\n');
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,21 +12,21 @@ typedef struct {
|
||||||
} decfloat;
|
} decfloat;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t seen;
|
uint8_t seen_G :1;
|
||||||
#define SEEN_G 1
|
uint8_t seen_M :1;
|
||||||
#define SEEN_M 2
|
uint8_t seen_X :1;
|
||||||
#define SEEN_X 4
|
uint8_t seen_Y :1;
|
||||||
#define SEEN_Y 8
|
uint8_t seen_Z :1;
|
||||||
#define SEEN_Z 16
|
uint8_t seen_E :1;
|
||||||
#define SEEN_E 32
|
uint8_t seen_F :1;
|
||||||
#define SEEN_F 64
|
uint8_t seen_S :1;
|
||||||
#define SEEN_S 128
|
uint8_t seen_P :1;
|
||||||
#define SEEN_P 256
|
|
||||||
|
|
||||||
uint8_t option;
|
uint8_t option;
|
||||||
#define OPTION_RELATIVE 1
|
#define OPTION_RELATIVE 1
|
||||||
#define OPTION_SYNCHRONISE 2
|
#define OPTION_SYNCHRONISE 2
|
||||||
#define OPTION_UNIT_INCHES 4
|
#define OPTION_UNIT_INCHES 4
|
||||||
|
#define OPTION_COMMENT 128
|
||||||
|
|
||||||
uint8_t G;
|
uint8_t G;
|
||||||
uint8_t M;
|
uint8_t M;
|
||||||
|
|
@ -36,7 +36,7 @@ typedef struct {
|
||||||
uint16_t P;
|
uint16_t P;
|
||||||
} GCODE_COMMAND;
|
} GCODE_COMMAND;
|
||||||
|
|
||||||
int8_t indexof(uint8_t c, char *string);
|
int8_t indexof(uint8_t c, const char *string);
|
||||||
int32_t decfloat_to_int(decfloat *df, int32_t multiplicand, int32_t denominator);
|
int32_t decfloat_to_int(decfloat *df, int32_t multiplicand, int32_t denominator);
|
||||||
|
|
||||||
void scan_char(uint8_t c);
|
void scan_char(uint8_t c);
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,12 @@
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "clock.h"
|
#include "clock.h"
|
||||||
#include "temp.h"
|
#include "temp.h"
|
||||||
|
#include "sermsg.h"
|
||||||
|
|
||||||
int main (void)
|
int main (void)
|
||||||
{
|
{
|
||||||
|
uint8_t report;
|
||||||
|
|
||||||
// set up serial
|
// set up serial
|
||||||
serial_init();
|
serial_init();
|
||||||
|
|
||||||
|
|
@ -45,26 +48,89 @@ int main (void)
|
||||||
WRITE(MISO, 1); SET_INPUT(MISO);
|
WRITE(MISO, 1); SET_INPUT(MISO);
|
||||||
WRITE(SS, 0); SET_OUTPUT(SS);
|
WRITE(SS, 0); SET_OUTPUT(SS);
|
||||||
|
|
||||||
|
|
||||||
// set up timers
|
// set up timers
|
||||||
setupTimerInterrupt();
|
setupTimerInterrupt();
|
||||||
|
|
||||||
|
// set up clock
|
||||||
|
clock_setup();
|
||||||
|
|
||||||
// enable interrupts
|
// enable interrupts
|
||||||
sei();
|
sei();
|
||||||
|
|
||||||
serial_writeblock((uint8_t *) "Start\n", 6);
|
// say hi to host
|
||||||
|
serial_writestr_P(PSTR("Start\n"));
|
||||||
|
|
||||||
|
// start queue
|
||||||
|
//enableTimerInterrupt();
|
||||||
|
|
||||||
// main loop
|
// main loop
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (serial_rxchars()) {
|
if (serial_rxchars()) {
|
||||||
uint8_t c = serial_popchar();
|
uint8_t c = serial_popchar();
|
||||||
|
// TOGGLE(SCK);
|
||||||
scan_char(c);
|
scan_char(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clock_flag_250ms & CLOCK_FLAG_250MS_TEMPCHECK) {
|
// if (clock_flag_250ms & CLOCK_FLAG_250MS_TEMPCHECK) {
|
||||||
clock_flag_250ms &= ~CLOCK_FLAG_250MS_TEMPCHECK;
|
// clock_flag_250ms &= ~CLOCK_FLAG_250MS_TEMPCHECK;
|
||||||
temp_tick();
|
// temp_tick();
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (clock_flag_250ms & CLOCK_FLAG_250MS_REPORT) {
|
||||||
|
clock_flag_250ms &= ~CLOCK_FLAG_250MS_REPORT;
|
||||||
|
report++;
|
||||||
|
if (report == 4) {
|
||||||
|
report = 0;
|
||||||
|
|
||||||
|
// current move
|
||||||
|
serial_writestr_P(PSTR("DDA: f#"));
|
||||||
|
serwrite_int32(movebuffer[mb_head].f_counter);
|
||||||
|
serial_writechar('/');
|
||||||
|
serwrite_uint16(movebuffer[mb_head].f_scale);
|
||||||
|
serial_writechar('/');
|
||||||
|
serwrite_int16(movebuffer[mb_head].f_delta);
|
||||||
|
serial_writechar('\n');
|
||||||
|
|
||||||
|
// current position
|
||||||
|
serial_writestr_P(PSTR("Pos: "));
|
||||||
|
serwrite_int32(current_position.X);
|
||||||
|
serial_writechar(',');
|
||||||
|
serwrite_int32(current_position.Y);
|
||||||
|
serial_writechar(',');
|
||||||
|
serwrite_int32(current_position.Z);
|
||||||
|
serial_writechar(',');
|
||||||
|
serwrite_uint32(current_position.E);
|
||||||
|
serial_writechar(',');
|
||||||
|
serwrite_uint32(current_position.F);
|
||||||
|
serial_writechar('\n');
|
||||||
|
|
||||||
|
// target position
|
||||||
|
serial_writestr_P(PSTR("Tar: "));
|
||||||
|
serwrite_int32(movebuffer[mb_head].endpoint.X);
|
||||||
|
serial_writechar(',');
|
||||||
|
serwrite_int32(movebuffer[mb_head].endpoint.Y);
|
||||||
|
serial_writechar(',');
|
||||||
|
serwrite_int32(movebuffer[mb_head].endpoint.Z);
|
||||||
|
serial_writechar(',');
|
||||||
|
serwrite_uint32(movebuffer[mb_head].endpoint.E);
|
||||||
|
serial_writechar(',');
|
||||||
|
serwrite_uint32(movebuffer[mb_head].endpoint.F);
|
||||||
|
serial_writechar('\n');
|
||||||
|
|
||||||
|
// Queue
|
||||||
|
serial_writestr_P(PSTR("Q : "));
|
||||||
|
// serwrite_uint8((mb_head - mb_tail) & (MOVEBUFFER_SIZE - 1));
|
||||||
|
serwrite_uint8(mb_head);
|
||||||
|
serial_writechar('/');
|
||||||
|
serwrite_uint8(mb_tail);
|
||||||
|
|
||||||
|
if (queue_full())
|
||||||
|
serial_writechar('F');
|
||||||
|
if (queue_empty())
|
||||||
|
serial_writechar('E');
|
||||||
|
serial_writechar('\n');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,12 +23,12 @@
|
||||||
#define Y_DIR_PIN AIO4
|
#define Y_DIR_PIN AIO4
|
||||||
#define Y_MIN_PIN AIO5
|
#define Y_MIN_PIN AIO5
|
||||||
|
|
||||||
#define Z_STEP_PIN DIO5
|
#define Z_STEP_PIN DIO2
|
||||||
#define Z_DIR_PIN DIO7
|
#define Z_DIR_PIN DIO3
|
||||||
#define Z_MIN_PIN DIO8
|
#define Z_MIN_PIN DIO4
|
||||||
|
|
||||||
#define E_STEP_PIN DIO2
|
#define E_STEP_PIN DIO7
|
||||||
#define E_DIR_PIN DIO3
|
#define E_DIR_PIN DIO8
|
||||||
|
|
||||||
// list of PWM-able pins and corresponding timers
|
// list of PWM-able pins and corresponding timers
|
||||||
// OC0A DIO6
|
// OC0A DIO6
|
||||||
|
|
@ -41,7 +41,7 @@
|
||||||
#define HEATER_PIN DIO6
|
#define HEATER_PIN DIO6
|
||||||
#define HEATER_PIN_PWM OC0A
|
#define HEATER_PIN_PWM OC0A
|
||||||
|
|
||||||
#define FAN_PIN DIO9
|
#define FAN_PIN DIO5
|
||||||
|
|
||||||
#define SCK DIO13
|
#define SCK DIO13
|
||||||
#define MISO DIO12
|
#define MISO DIO12
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,26 @@
|
||||||
#include "ringbuffer.h"
|
#include "ringbuffer.h"
|
||||||
|
|
||||||
uint16_t _rb_mod(uint16_t num, uint16_t denom)
|
RB_BITS _rb_mod(RB_BITS num, RB_BITS denom)
|
||||||
{
|
{
|
||||||
for (; num >= denom; num -= denom);
|
for (; num >= denom; num -= denom);
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ringbuffer_init(ringbuffer *buf, int bufsize)
|
void ringbuffer_init(ringbuffer *buf, RB_BITS bufsize)
|
||||||
{
|
{
|
||||||
buf->read_pointer = 0;
|
buf->read_pointer = 0;
|
||||||
buf->write_pointer = 0;
|
buf->write_pointer = 0;
|
||||||
buf->size = bufsize - sizeof(ringbuffer);
|
buf->size = bufsize - sizeof(ringbuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ringbuffer_canread(ringbuffer *buf)
|
RB_BITS ringbuffer_canread(ringbuffer *buf)
|
||||||
{
|
{
|
||||||
return _rb_mod(buf->write_pointer + buf->size + buf->size - buf->read_pointer, buf->size);
|
return _rb_mod(buf->size + buf->write_pointer - buf->read_pointer, buf->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ringbuffer_canwrite(ringbuffer *buf)
|
RB_BITS ringbuffer_canwrite(ringbuffer *buf)
|
||||||
{
|
{
|
||||||
return _rb_mod(buf->read_pointer + buf->size + buf->size - buf->write_pointer - 1, buf->size);
|
return _rb_mod(buf->size + buf->size + buf->read_pointer - buf->write_pointer - 1, buf->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t ringbuffer_readchar(ringbuffer *buf)
|
uint8_t ringbuffer_readchar(ringbuffer *buf)
|
||||||
|
|
@ -44,23 +44,23 @@ void ringbuffer_writechar(ringbuffer *buf, uint8_t data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint8_t ringbuffer_peekchar(ringbuffer *buf, uint16_t index)
|
uint8_t ringbuffer_peekchar(ringbuffer *buf, RB_BITS index)
|
||||||
{
|
{
|
||||||
return buf->data[_rb_mod(buf->read_pointer + index, buf->size)];
|
return buf->data[_rb_mod(buf->read_pointer + index, buf->size)];
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ringbuffer_readblock(ringbuffer *buf, uint8_t *newbuf, int size)
|
RB_BITS ringbuffer_readblock(ringbuffer *buf, uint8_t *newbuf, RB_BITS size)
|
||||||
{
|
{
|
||||||
uint16_t nc, i;
|
RB_BITS nc, i;
|
||||||
uint8_t *rp, *ms;
|
uint8_t *rp, *ms;
|
||||||
if ((nc = ringbuffer_canread(buf)) < size)
|
if ((nc = ringbuffer_canread(buf)) < size)
|
||||||
size = nc;
|
size = nc;
|
||||||
if (size)
|
if (size)
|
||||||
{
|
{
|
||||||
for (i = 0, rp = buf->data + buf->read_pointer, ms = buf->data + buf->size; i < size; i++, rp++)
|
for (i = 0, rp = ((uint8_t *) buf->data + buf->read_pointer), ms = ((uint8_t *) buf->data + buf->size); i < size; i++, rp++)
|
||||||
{
|
{
|
||||||
if (rp >= ms)
|
if (rp >= ms)
|
||||||
rp = buf->data;
|
rp = (uint8_t *) buf->data;
|
||||||
newbuf[i] = *rp;
|
newbuf[i] = *rp;
|
||||||
}
|
}
|
||||||
buf->read_pointer = rp - buf->data;
|
buf->read_pointer = rp - buf->data;
|
||||||
|
|
@ -68,19 +68,19 @@ uint16_t ringbuffer_readblock(ringbuffer *buf, uint8_t *newbuf, int size)
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ringbuffer_writeblock(ringbuffer *buf, uint8_t *data, int size)
|
RB_BITS ringbuffer_writeblock(ringbuffer *buf, uint8_t *data, RB_BITS size)
|
||||||
{
|
{
|
||||||
uint16_t nc, i;
|
RB_BITS nc, i;
|
||||||
uint8_t *wp, *ms;
|
uint8_t *wp, *ms;
|
||||||
|
|
||||||
if ((nc = ringbuffer_canwrite(buf)) < size)
|
if ((nc = ringbuffer_canwrite(buf)) < size)
|
||||||
size = nc;
|
size = nc;
|
||||||
if (size)
|
if (size)
|
||||||
{
|
{
|
||||||
for (i = 0, wp = buf->write_pointer + buf->data, ms = buf->data + buf->size; i < size; i++, wp++)
|
for (i = 0, wp = (uint8_t *) (buf->write_pointer + buf->data), ms = (uint8_t *) (buf->data + buf->size); i < size; i++, wp++)
|
||||||
{
|
{
|
||||||
if (wp >= ms)
|
if (wp >= ms)
|
||||||
wp = buf->data;
|
wp = (uint8_t *) buf->data;
|
||||||
*wp = data[i];
|
*wp = data[i];
|
||||||
}
|
}
|
||||||
buf->write_pointer = wp - buf->data;
|
buf->write_pointer = wp - buf->data;
|
||||||
|
|
|
||||||
|
|
@ -4,23 +4,25 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <avr/interrupt.h>
|
#include <avr/interrupt.h>
|
||||||
|
|
||||||
|
#define RB_BITS uint8_t
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t read_pointer;
|
volatile RB_BITS read_pointer;
|
||||||
uint16_t write_pointer;
|
volatile RB_BITS write_pointer;
|
||||||
uint16_t size;
|
volatile RB_BITS size;
|
||||||
uint8_t data[];
|
volatile RB_BITS data[];
|
||||||
} ringbuffer;
|
} ringbuffer;
|
||||||
|
|
||||||
void ringbuffer_init(ringbuffer *buf, int bufsize);
|
void ringbuffer_init(ringbuffer *buf, RB_BITS bufsize);
|
||||||
|
|
||||||
uint16_t ringbuffer_canread(ringbuffer *buf);
|
RB_BITS ringbuffer_canread(ringbuffer *buf);
|
||||||
uint16_t ringbuffer_canwrite(ringbuffer *buf);
|
RB_BITS ringbuffer_canwrite(ringbuffer *buf);
|
||||||
|
|
||||||
uint8_t ringbuffer_readchar(ringbuffer *buf);
|
uint8_t ringbuffer_readchar(ringbuffer *buf);
|
||||||
uint8_t ringbuffer_peekchar(ringbuffer *buf, uint16_t index);
|
uint8_t ringbuffer_peekchar(ringbuffer *buf, RB_BITS index);
|
||||||
uint16_t ringbuffer_readblock(ringbuffer *buf, uint8_t *newbuf, int size);
|
RB_BITS ringbuffer_readblock(ringbuffer *buf, uint8_t *newbuf, RB_BITS size);
|
||||||
|
|
||||||
void ringbuffer_writechar(ringbuffer *buf, uint8_t data);
|
void ringbuffer_writechar(ringbuffer *buf, uint8_t data);
|
||||||
uint16_t ringbuffer_writeblock(ringbuffer *buf, uint8_t *data, int size);
|
RB_BITS ringbuffer_writeblock(ringbuffer *buf, uint8_t *data, RB_BITS size);
|
||||||
|
|
||||||
#endif /* _RINGBUFFER_H */
|
#endif /* _RINGBUFFER_H */
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,9 @@
|
||||||
volatile uint8_t _rx_buffer[BUFSIZE];
|
volatile uint8_t _rx_buffer[BUFSIZE];
|
||||||
volatile uint8_t _tx_buffer[BUFSIZE];
|
volatile uint8_t _tx_buffer[BUFSIZE];
|
||||||
|
|
||||||
|
#define rx_buffer ((ringbuffer *) _rx_buffer)
|
||||||
|
#define tx_buffer ((ringbuffer *) _tx_buffer)
|
||||||
|
|
||||||
void serial_init()
|
void serial_init()
|
||||||
{
|
{
|
||||||
ringbuffer_init(rx_buffer, BUFSIZE);
|
ringbuffer_init(rx_buffer, BUFSIZE);
|
||||||
|
|
@ -30,13 +33,9 @@ ISR(USART_RX_vect)
|
||||||
ISR(USART_UDRE_vect)
|
ISR(USART_UDRE_vect)
|
||||||
{
|
{
|
||||||
if (ringbuffer_canread(tx_buffer))
|
if (ringbuffer_canread(tx_buffer))
|
||||||
{
|
|
||||||
UDR0 = ringbuffer_readchar(tx_buffer);
|
UDR0 = ringbuffer_readchar(tx_buffer);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
UCSR0B &= ~(1 << UDRIE0);
|
UCSR0B &= ~(1 << UDRIE0);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t serial_rxchars()
|
uint16_t serial_rxchars()
|
||||||
|
|
@ -61,12 +60,34 @@ uint16_t serial_recvblock(uint8_t *block, int blocksize)
|
||||||
|
|
||||||
void serial_writechar(uint8_t data)
|
void serial_writechar(uint8_t data)
|
||||||
{
|
{
|
||||||
|
for (;ringbuffer_canwrite(tx_buffer) == 0;);
|
||||||
ringbuffer_writechar(tx_buffer, data);
|
ringbuffer_writechar(tx_buffer, data);
|
||||||
UCSR0B |= (1 << UDRIE0);
|
UCSR0B |= (1 << UDRIE0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void serial_writeblock(uint8_t *data, int datalen)
|
void serial_writeblock(void *data, int datalen)
|
||||||
{
|
{
|
||||||
ringbuffer_writeblock(tx_buffer, data, datalen);
|
for (int i = 0; i < datalen; i++)
|
||||||
|
serial_writechar(((uint8_t *) data)[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void serial_writechar_P(PGM_P data)
|
||||||
|
{
|
||||||
|
for (;ringbuffer_canwrite(tx_buffer) == 0;);
|
||||||
|
ringbuffer_writechar(tx_buffer, pgm_read_byte(data));
|
||||||
UCSR0B |= (1 << UDRIE0);
|
UCSR0B |= (1 << UDRIE0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void serial_writeblock_P(PGM_P data, int datalen)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < datalen; i++)
|
||||||
|
serial_writechar_P(&data[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void serial_writestr_P(PGM_P data)
|
||||||
|
{
|
||||||
|
uint8_t i = 0;
|
||||||
|
// yes, this is *supposed* to be assignment rather than comparison
|
||||||
|
for (uint8_t r; (r = pgm_read_byte(&data[i])); i++)
|
||||||
|
serial_writechar(r);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,7 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
#include "ringbuffer.h"
|
|
||||||
|
|
||||||
#define rx_buffer ((ringbuffer *) _rx_buffer)
|
|
||||||
#define tx_buffer ((ringbuffer *) _tx_buffer)
|
|
||||||
|
|
||||||
extern volatile uint8_t _rx_buffer[];
|
|
||||||
extern volatile uint8_t _tx_buffer[];
|
|
||||||
|
|
||||||
void serial_init(void);
|
void serial_init(void);
|
||||||
|
|
||||||
|
|
@ -21,6 +14,11 @@ uint8_t serial_popchar(void);
|
||||||
void serial_writechar(uint8_t data);
|
void serial_writechar(uint8_t data);
|
||||||
|
|
||||||
uint16_t serial_recvblock(uint8_t *block, int blocksize);
|
uint16_t serial_recvblock(uint8_t *block, int blocksize);
|
||||||
void serial_writeblock(uint8_t *data, int datalen);
|
void serial_writeblock(void *data, int datalen);
|
||||||
|
|
||||||
|
void serial_writechar_P(PGM_P data);
|
||||||
|
void serial_writeblock_P(PGM_P data, int datalen);
|
||||||
|
|
||||||
|
void serial_writestr_P(PGM_P data);
|
||||||
|
|
||||||
#endif /* _SERIAL_H */
|
#endif /* _SERIAL_H */
|
||||||
|
|
|
||||||
119
mendel/sermsg.c
119
mendel/sermsg.c
|
|
@ -2,42 +2,105 @@
|
||||||
|
|
||||||
#include "serial.h"
|
#include "serial.h"
|
||||||
|
|
||||||
void serwrite_uint8(uint8_t v) {
|
// void serwrite_uint8(uint8_t v) {
|
||||||
uint8_t t;
|
// serwrite_uint32(v);
|
||||||
if (v > 100) {
|
// }
|
||||||
|
//
|
||||||
|
// void serwrite_int8(int8_t v) {
|
||||||
|
// if (v < 0) {
|
||||||
|
// serial_writechar('-');
|
||||||
|
// v = -v;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// serwrite_uint32(v);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// void serwrite_uint16(uint16_t v) {
|
||||||
|
// serwrite_uint32(v);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// void serwrite_int16(int16_t v) {
|
||||||
|
// if (v < 0) {
|
||||||
|
// serial_writechar('-');
|
||||||
|
// v = -v;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// serwrite_uint32(v);
|
||||||
|
// }
|
||||||
|
|
||||||
|
void serwrite_uint32(uint32_t v) {
|
||||||
|
uint8_t t = 0;
|
||||||
|
if (v >= 1000000000) {
|
||||||
|
for (t = 0; v >= 1000000000; v -= 1000000000, t++);
|
||||||
|
serial_writechar(t + '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v >= 100000000) {
|
||||||
|
for (t = 0; v >= 100000000; v -= 100000000, t++);
|
||||||
|
serial_writechar(t + '0');
|
||||||
|
}
|
||||||
|
else if (t != 0)
|
||||||
|
serial_writechar('0');
|
||||||
|
|
||||||
|
if (v >= 10000000) {
|
||||||
|
for (t = 0; v >= 10000000; v -= 10000000, t++);
|
||||||
|
serial_writechar(t + '0');
|
||||||
|
}
|
||||||
|
else if (t != 0)
|
||||||
|
serial_writechar('0');
|
||||||
|
|
||||||
|
if (v >= 1000000) {
|
||||||
|
for (t = 0; v >= 1000000; v -= 1000000, t++);
|
||||||
|
serial_writechar(t + '0');
|
||||||
|
}
|
||||||
|
else if (t != 0)
|
||||||
|
serial_writechar('0');
|
||||||
|
|
||||||
|
if (v >= 100000) {
|
||||||
|
for (t = 0; v >= 100000; v -= 100000, t++);
|
||||||
|
serial_writechar(t + '0');
|
||||||
|
}
|
||||||
|
else if (t != 0)
|
||||||
|
serial_writechar('0');
|
||||||
|
|
||||||
|
if (v >= 10000) {
|
||||||
|
for (t = 0; v >= 10000; v -= 10000, t++);
|
||||||
|
serial_writechar(t + '0');
|
||||||
|
}
|
||||||
|
else if (t != 0)
|
||||||
|
serial_writechar('0');
|
||||||
|
|
||||||
|
if (v >= 1000) {
|
||||||
|
for (t = 0; v >= 1000; v -= 1000, t++);
|
||||||
|
serial_writechar(t + '0');
|
||||||
|
}
|
||||||
|
else if (t != 0)
|
||||||
|
serial_writechar('0');
|
||||||
|
|
||||||
|
if (v >= 100) {
|
||||||
t = v / 100;
|
t = v / 100;
|
||||||
serial_writechar(t + '0');
|
serial_writechar(t + '0');
|
||||||
v -= t;
|
v -= (t * 100);
|
||||||
}
|
}
|
||||||
if (v > 10) {
|
else if (t != 0)
|
||||||
|
serial_writechar('0');
|
||||||
|
|
||||||
|
if (v >= 10) {
|
||||||
t = v / 10;
|
t = v / 10;
|
||||||
serial_writechar(t + '0');
|
serial_writechar(t + '0');
|
||||||
v -= t;
|
v -= (t * 10);
|
||||||
}
|
}
|
||||||
|
else if (t != 0)
|
||||||
|
serial_writechar('0');
|
||||||
|
|
||||||
serial_writechar(v + '0');
|
serial_writechar(v + '0');
|
||||||
}
|
}
|
||||||
|
|
||||||
void serwrite_uint16(uint16_t v) {
|
void serwrite_int32(int32_t v) {
|
||||||
uint16_t t;
|
if (v < 0) {
|
||||||
if (v > 10000) {
|
serial_writechar('-');
|
||||||
t = v / 10000;
|
v = -v;
|
||||||
serial_writechar(t + '0');
|
|
||||||
v -= t;
|
|
||||||
}
|
}
|
||||||
if (v > 1000) {
|
|
||||||
t = v / 1000;
|
serwrite_uint32(v);
|
||||||
serial_writechar(t + '0');
|
|
||||||
v -= t;
|
|
||||||
}
|
|
||||||
if (v > 100) {
|
|
||||||
t = v / 100;
|
|
||||||
serial_writechar(t + '0');
|
|
||||||
v -= t;
|
|
||||||
}
|
|
||||||
if (v > 10) {
|
|
||||||
t = v / 10;
|
|
||||||
serial_writechar(t + '0');
|
|
||||||
v -= t;
|
|
||||||
}
|
|
||||||
serial_writechar(v + '0');
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,18 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
void serwrite_uint8(uint8_t v);
|
// void serwrite_uint8(uint8_t v);
|
||||||
void serwrite_uint16(uint16_t v);
|
// void serwrite_int8(int8_t v);
|
||||||
|
//
|
||||||
|
// void serwrite_uint16(uint16_t v);
|
||||||
|
// void serwrite_int16(int16_t v);
|
||||||
|
|
||||||
|
#define serwrite_uint8(v) serwrite_uint32(v)
|
||||||
|
#define serwrite_int8(v) serwrite_int32(v)
|
||||||
|
#define serwrite_uint16(v) serwrite_uint32(v)
|
||||||
|
#define serwrite_int16(v) serwrite_int32(v)
|
||||||
|
|
||||||
|
void serwrite_uint32(uint32_t v);
|
||||||
|
void serwrite_int32(int32_t v);
|
||||||
|
|
||||||
#endif /* _SERMSG_H */
|
#endif /* _SERMSG_H */
|
||||||
|
|
@ -6,16 +6,15 @@
|
||||||
#include "dda.h"
|
#include "dda.h"
|
||||||
|
|
||||||
ISR(TIMER1_COMPA_vect) {
|
ISR(TIMER1_COMPA_vect) {
|
||||||
// static interruptBlink = 0;
|
if(movebuffer[mb_tail].live) {
|
||||||
//
|
// this interrupt can be interruptible
|
||||||
// interruptBlink++;
|
disableTimerInterrupt();
|
||||||
// if (interruptBlink == 0x80) {
|
sei();
|
||||||
// blink();
|
|
||||||
// interruptBlink = 0;
|
|
||||||
// }
|
|
||||||
|
|
||||||
if(movebuffer[mb_tail].live)
|
|
||||||
dda_step(&movebuffer[mb_tail]);
|
dda_step(&movebuffer[mb_tail]);
|
||||||
|
|
||||||
|
enableTimerInterrupt();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
next_move();
|
next_move();
|
||||||
}
|
}
|
||||||
|
|
@ -23,26 +22,16 @@ ISR(TIMER1_COMPA_vect) {
|
||||||
void setupTimerInterrupt()
|
void setupTimerInterrupt()
|
||||||
{
|
{
|
||||||
//clear the registers
|
//clear the registers
|
||||||
|
|
||||||
|
// no outputs
|
||||||
TCCR1A = 0;
|
TCCR1A = 0;
|
||||||
TCCR1B = 0;
|
// CTC mode
|
||||||
TCCR1C = 0;
|
TCCR1B = MASK(WGM12);
|
||||||
|
// no interrupts yet
|
||||||
TIMSK1 = 0;
|
TIMSK1 = 0;
|
||||||
|
|
||||||
//waveform generation = 0100 = CTC
|
|
||||||
TCCR1B &= ~(1<<WGM13);
|
|
||||||
TCCR1B |= (1<<WGM12);
|
|
||||||
TCCR1A &= ~(1<<WGM11);
|
|
||||||
TCCR1A &= ~(1<<WGM10);
|
|
||||||
|
|
||||||
//output mode = 00 (disconnected)
|
|
||||||
TCCR1A &= ~(1<<COM1A1);
|
|
||||||
TCCR1A &= ~(1<<COM1A0);
|
|
||||||
TCCR1A &= ~(1<<COM1B1);
|
|
||||||
TCCR1A &= ~(1<<COM1B0);
|
|
||||||
|
|
||||||
//start off with a slow frequency.
|
//start off with a slow frequency.
|
||||||
setTimerResolution(4);
|
setTimer(10000);
|
||||||
setTimerCeiling(65535);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t getTimerResolution(const uint32_t delay)
|
uint8_t getTimerResolution(const uint32_t delay)
|
||||||
|
|
@ -52,37 +41,32 @@ uint8_t getTimerResolution(const uint32_t delay)
|
||||||
// our slowest speed at our highest resolution ( (2^16-1) * 0.0625 usecs = 4095 usecs (4 millisecond max))
|
// our slowest speed at our highest resolution ( (2^16-1) * 0.0625 usecs = 4095 usecs (4 millisecond max))
|
||||||
// range: 8Mhz max - 122hz min
|
// range: 8Mhz max - 122hz min
|
||||||
if (delay <= 65535L)
|
if (delay <= 65535L)
|
||||||
return 0;
|
return 1;
|
||||||
// our slowest speed at our next highest resolution ( (2^16-1) * 0.5 usecs = 32767 usecs (32 millisecond max))
|
// our slowest speed at our next highest resolution ( (2^16-1) * 0.5 usecs = 32767 usecs (32 millisecond max))
|
||||||
// range:1Mhz max - 15.26hz min
|
// range:1Mhz max - 15.26hz min
|
||||||
else if (delay <= 524280L)
|
else if (delay <= 524280L)
|
||||||
return 1;
|
return 2;
|
||||||
// our slowest speed at our medium resolution ( (2^16-1) * 4 usecs = 262140 usecs (0.26 seconds max))
|
// our slowest speed at our medium resolution ( (2^16-1) * 4 usecs = 262140 usecs (0.26 seconds max))
|
||||||
// range: 125Khz max - 1.9hz min
|
// range: 125Khz max - 1.9hz min
|
||||||
else if (delay <= 4194240L)
|
else if (delay <= 4194240L)
|
||||||
return 2;
|
return 3;
|
||||||
// our slowest speed at our medium-low resolution ( (2^16-1) * 16 usecs = 1048560 usecs (1.04 seconds max))
|
// our slowest speed at our medium-low resolution ( (2^16-1) * 16 usecs = 1048560 usecs (1.04 seconds max))
|
||||||
// range: 31.25Khz max - 0.475hz min
|
// range: 31.25Khz max - 0.475hz min
|
||||||
else if (delay <= 16776960L)
|
else if (delay <= 16776960L)
|
||||||
return 3;
|
return 4;
|
||||||
// our slowest speed at our lowest resolution ((2^16-1) * 64 usecs = 4194240 usecs (4.19 seconds max))
|
// our slowest speed at our lowest resolution ((2^16-1) * 64 usecs = 4194240 usecs (4.19 seconds max))
|
||||||
// range: 7.812Khz max - 0.119hz min
|
// range: 7.812Khz max - 0.119hz min
|
||||||
// else if (delay <= 67107840L)
|
// else if (delay <= 67107840L)
|
||||||
// return 4;
|
// return 5;
|
||||||
//its really slow... hopefully we can just get by with super slow.
|
//its really slow... hopefully we can just get by with super slow.
|
||||||
// else
|
// else
|
||||||
return 4;
|
return 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setTimerResolution(uint8_t r)
|
void setTimerResolution(uint8_t r)
|
||||||
{
|
{
|
||||||
//here's how you figure out the tick size:
|
|
||||||
// 1000000 / ((F_CPU / prescaler))
|
|
||||||
// 1000000 = microseconds in 1 second
|
|
||||||
// prescaler = your prescaler
|
|
||||||
|
|
||||||
// assuming CS10,CS11,CS12 are adjacent bits in platform endian order,
|
// assuming CS10,CS11,CS12 are adjacent bits in platform endian order,
|
||||||
TCCR1B = (TCCR1B & ~(MASK(CS10) | MASK(CS11) | MASK(CS12))) | ((r + 1) << CS10);
|
TCCR1B = (TCCR1B & ~(MASK(CS12) | MASK(CS11) | MASK(CS10))) | (r << CS10);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t getTimerCeiling(const uint32_t delay)
|
uint16_t getTimerCeiling(const uint32_t delay)
|
||||||
|
|
|
||||||
|
|
@ -25,15 +25,8 @@ void delay_ms(uint32_t delay);
|
||||||
#define delay_us(d) delayMicrosecondsInterruptible(d)
|
#define delay_us(d) delayMicrosecondsInterruptible(d)
|
||||||
void delayMicrosecondsInterruptible(unsigned int us);
|
void delayMicrosecondsInterruptible(unsigned int us);
|
||||||
|
|
||||||
inline void enableTimerInterrupt(void)
|
#define enableTimerInterrupt() do { TIMSK1 |= (1<<OCIE1A); } while (0)
|
||||||
{
|
#define disableTimerInterrupt() do { TIMSK1 &= ~(1<<OCIE1A); } while (0)
|
||||||
TIMSK1 |= (1<<OCIE1A);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void disableTimerInterrupt(void)
|
|
||||||
{
|
|
||||||
TIMSK1 &= ~(1<<OCIE1A);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define setTimerCeiling(c) OCR1A = c
|
#define setTimerCeiling(c) OCR1A = c
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue