aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/basecmd.c91
-rw-r--r--src/basecmd.h13
-rw-r--r--src/stepper.c20
3 files changed, 84 insertions, 40 deletions
diff --git a/src/basecmd.c b/src/basecmd.c
index 4b4eca45..639add97 100644
--- a/src/basecmd.c
+++ b/src/basecmd.c
@@ -17,26 +17,53 @@
* Move queue
****************************************************************/
-static struct move *move_list, *move_free_list;
+struct move_freed {
+ struct move_freed *next;
+};
+
+static struct move_freed *move_free_list;
+static void *move_list;
static uint16_t move_count;
+static uint8_t move_item_size;
+
+// Is the config and move queue finalized?
+static int
+is_finalized(void)
+{
+ return !!move_count;
+}
+// Free previously allocated storage from move_alloc(). Caller must
+// disable irqs.
void
-move_free(struct move *m)
+move_free(void *m)
{
- m->next = move_free_list;
- move_free_list = m;
+ struct move_freed *mf = m;
+ mf->next = move_free_list;
+ move_free_list = mf;
}
-struct move *
+// Allocate runtime storage
+void *
move_alloc(void)
{
irqstatus_t flag = irq_save();
- struct move *m = move_free_list;
- if (!m)
+ struct move_freed *mf = move_free_list;
+ if (!mf)
shutdown("Move queue empty");
- move_free_list = m->next;
+ move_free_list = mf->next;
irq_restore(flag);
- return m;
+ return mf;
+}
+
+// Request minimum size of runtime allocations returned by move_alloc()
+void
+move_request_size(int size)
+{
+ if (size > UINT8_MAX || is_finalized())
+ shutdown("Invalid move request size");
+ if (size > move_item_size)
+ move_item_size = size;
}
static void
@@ -46,13 +73,28 @@ move_reset(void)
return;
// Add everything in move_list to the free list.
uint32_t i;
- for (i=0; i<move_count-1; i++)
- move_list[i].next = &move_list[i+1];
- move_list[move_count-1].next = NULL;
- move_free_list = &move_list[0];
+ for (i=0; i<move_count-1; i++) {
+ struct move_freed *mf = move_list + i*move_item_size;
+ mf->next = move_list + (i + 1)*move_item_size;
+ }
+ struct move_freed *mf = move_list + (move_count - 1)*move_item_size;
+ mf->next = NULL;
+ move_free_list = move_list;
}
DECL_SHUTDOWN(move_reset);
+static void
+move_finalize(void)
+{
+ move_request_size(sizeof(*move_free_list));
+ uint16_t count = alloc_maxsize(move_item_size*1024) / move_item_size;
+ move_list = malloc(count * move_item_size);
+ if (!count || !move_list)
+ shutdown("move queue malloc failed");
+ move_count = count;
+ move_reset();
+}
+
/****************************************************************
* Generic object ids (oid)
@@ -64,8 +106,6 @@ struct oid_s {
static struct oid_s *oids;
static uint8_t num_oid;
-static uint32_t config_crc;
-static uint8_t config_finalized;
void *
lookup_oid(uint8_t oid, void *type)
@@ -78,7 +118,7 @@ lookup_oid(uint8_t oid, void *type)
static void
assign_oid(uint8_t oid, void *type, void *data)
{
- if (oid >= num_oid || oids[oid].type || config_finalized)
+ if (oid >= num_oid || oids[oid].type || is_finalized())
shutdown("Can't assign oid");
oids[oid].type = type;
oids[oid].data = data;
@@ -124,27 +164,28 @@ command_allocate_oids(uint32_t *args)
}
DECL_COMMAND(command_allocate_oids, "allocate_oids count=%c");
+
+/****************************************************************
+ * Config CRC
+ ****************************************************************/
+
+static uint32_t config_crc;
+
void
command_get_config(uint32_t *args)
{
sendf("config is_config=%c crc=%u move_count=%hu"
- , config_finalized, config_crc, move_count);
+ , is_finalized(), config_crc, move_count);
}
DECL_COMMAND_FLAGS(command_get_config, HF_IN_SHUTDOWN, "get_config");
void
command_finalize_config(uint32_t *args)
{
- if (!oids || config_finalized)
+ if (!oids || is_finalized())
shutdown("Can't finalize");
- uint16_t count = alloc_maxsize(sizeof(*move_list)*1024) / sizeof(*move_list);
- move_list = malloc(count * sizeof(*move_list));
- if (!count || !move_list)
- shutdown("malloc failed");
- move_count = count;
- move_reset();
+ move_finalize();
config_crc = args[0];
- config_finalized = 1;
command_get_config(NULL);
}
DECL_COMMAND(command_finalize_config, "finalize_config crc=%u");
diff --git a/src/basecmd.h b/src/basecmd.h
index e5719c6f..b795e4db 100644
--- a/src/basecmd.h
+++ b/src/basecmd.h
@@ -3,16 +3,9 @@
#include <stdint.h> // uint8_t
-struct move {
- uint32_t interval;
- int16_t add;
- uint16_t count;
- struct move *next;
- uint8_t flags;
-};
-
-void move_free(struct move *m);
-struct move *move_alloc(void);
+void move_free(void *m);
+void *move_alloc(void);
+void move_request_size(int size);
void *lookup_oid(uint8_t oid, void *type);
void *alloc_oid(uint8_t oid, void *type, uint16_t size);
void *next_oid(uint8_t *i, void *type);
diff --git a/src/stepper.c b/src/stepper.c
index 23a073b1..b97a7a69 100644
--- a/src/stepper.c
+++ b/src/stepper.c
@@ -17,6 +17,16 @@
* Steppers
****************************************************************/
+struct stepper_move {
+ uint32_t interval;
+ int16_t add;
+ uint16_t count;
+ struct stepper_move *next;
+ uint8_t flags;
+};
+
+enum { MF_DIR=1<<0 };
+
struct stepper {
struct timer time;
uint32_t interval;
@@ -30,13 +40,12 @@ struct stepper {
#endif
struct gpio_out step_pin, dir_pin;
uint32_t position;
- struct move *first, **plast;
+ struct stepper_move *first, **plast;
uint32_t min_stop_interval;
// gcc (pre v6) does better optimization when uint8_t are bitfields
uint8_t flags : 8;
};
-enum { MF_DIR=1<<0 };
enum { SF_LAST_DIR=1<<0, SF_NEXT_DIR=1<<1, SF_INVERT_STEP=1<<2, SF_HAVE_ADD=1<<3,
SF_LAST_RESET=1<<4, SF_NO_NEXT_CHECK=1<<5 };
@@ -44,7 +53,7 @@ enum { SF_LAST_DIR=1<<0, SF_NEXT_DIR=1<<1, SF_INVERT_STEP=1<<2, SF_HAVE_ADD=1<<3
static uint_fast8_t
stepper_load_next(struct stepper *s, uint32_t min_next_time)
{
- struct move *m = s->first;
+ struct stepper_move *m = s->first;
if (!m) {
if (s->interval - s->add < s->min_stop_interval
&& !(s->flags & SF_NO_NEXT_CHECK))
@@ -144,6 +153,7 @@ command_config_stepper(uint32_t *args)
s->dir_pin = gpio_out_setup(args[2], 0);
s->min_stop_interval = args[3];
s->position = -STEPPER_POSITION_BIAS;
+ move_request_size(sizeof(struct stepper_move));
}
DECL_COMMAND(command_config_stepper,
"config_stepper oid=%c step_pin=%c dir_pin=%c"
@@ -154,7 +164,7 @@ void
command_queue_step(uint32_t *args)
{
struct stepper *s = lookup_oid(args[0], command_config_stepper);
- struct move *m = move_alloc();
+ struct stepper_move *m = move_alloc();
m->interval = args[1];
m->count = args[2];
if (!m->count)
@@ -244,7 +254,7 @@ stepper_stop(struct stepper *s)
gpio_out_write(s->dir_pin, 0);
gpio_out_write(s->step_pin, s->flags & SF_INVERT_STEP ? 1 : 0);
while (s->first) {
- struct move *next = s->first->next;
+ struct stepper_move *next = s->first->next;
move_free(s->first);
s->first = next;
}