Skip to content

Commit 3a2d107

Browse files
committedJun 1, 2012
Removed file specific enumerators, implemented generic configuration scheme. Finalizing analog section (pwm to follow).
1 parent baa7a9b commit 3a2d107

11 files changed

+586
-735
lines changed
 

‎analog.c

+100-67
Original file line numberDiff line numberDiff line change
@@ -11,39 +11,60 @@
1111
#include "debug.h"
1212

1313

14-
struct analog_data_record {
15-
const char* device_path;
16-
int channel;
17-
update_callback* callback;
18-
unsigned int value; // last value
19-
int filter_length; // set to value > 0 for running average
14+
struct analog_channel_record {
15+
channel_tag id;
16+
const char* device_path;
17+
channel_tag update_channel;
18+
update_callback* callback;
19+
unsigned int value; // last value
20+
int filter_length; // set to value > 0 for running average
2021
struct average_data {
21-
unsigned int value; // integer part average
22-
unsigned int remainder; // remainder
23-
unsigned int count; // divisor for average
24-
} average;
22+
unsigned int value; // integer part average
23+
unsigned int remainder; // remainder
24+
unsigned int count; // divisor for average
25+
} average;
2526
};
2627

27-
static struct analog_data_record* analog_data = NULL;
28-
static unsigned int analog_num_channels = 0;
28+
static struct analog_channel_record* analog_channels = NULL;
29+
static unsigned int num_analog_channels = 0;
30+
31+
static int analog_index_lookup( channel_tag analog_channel)
32+
{
33+
for (int ix = 0 ; ix < num_analog_channels ; ++ix) {
34+
if (analog_channels[ ix].id == analog_channel) {
35+
return ix;
36+
}
37+
}
38+
if (debug_flags & DEBUG_ANALOG) {
39+
fprintf( stderr, "analog_index_lookup failed for '%s'\n", tag_name( analog_channel));
40+
}
41+
return -1;
42+
}
2943

3044
/*
3145
* Set a callback for temperature updates, one callback for each analog channel
3246
* can be registered. Any previous value will be overwritten.
3347
* Set a callback to NULL to disable it.
3448
*/
35-
int analog_set_update_callback( unsigned int analog_channel, update_callback* temp_update, update_channel_t temp_channel)
49+
int analog_set_update_callback( channel_tag analog_channel, update_callback* ptemp_update, channel_tag update_channel)
3650
{
37-
fprintf( stderr, "analog_set_update_callback for analog channel %d, temperature channel %d\n", analog_channel, temp_channel);
38-
if (analog_channel >= 0 && analog_channel <= analog_num_channels) {
39-
analog_data[ analog_channel].callback = temp_update;
40-
analog_data[ analog_channel].channel = temp_channel;
51+
if (debug_flags & DEBUG_ANALOG) {
52+
printf( "analog_set_update_callback from '%s' to '%s'\n", analog_channel, update_channel);
4153
}
42-
return 0;
54+
int ix = analog_index_lookup( analog_channel);
55+
if (ix >= 0) {
56+
analog_channels[ ix].callback = ptemp_update;
57+
analog_channels[ ix].update_channel = update_channel;
58+
return 0;
59+
}
60+
if (debug_flags & DEBUG_ANALOG) {
61+
fprintf( stderr, "analog_set_update_callback failed for '%s'\n", tag_name( analog_channel));
62+
}
63+
return -1;
4364
}
4465

45-
#define ANALOG_CYCLE_TIME 200000 /* usecs, sensor readout cycle */
46-
#define UPDATE_CYCLE_TIME 2000000 /* usecs, update interval callbacks */
66+
#define ANALOG_CYCLE_TIME 20000 /* usecs, sensor readout cycle */
67+
#define UPDATE_CYCLE_TIME 200000 /* usecs, update interval callbacks */
4768

4869
/*
4970
* This is the worker thread that reads the analog inputs and
@@ -58,9 +79,9 @@ void* analog_worker( void* arg)
5879
int cycle = 0;
5980

6081
fprintf( stderr, "analog_thread: started\n");
61-
fd = calloc( analog_num_channels, sizeof( *fd));
62-
for (i = 0 ; i < analog_num_channels ; ++i) {
63-
ret = fd[ i] = open( analog_data[ i].device_path, O_RDONLY);
82+
fd = calloc( num_analog_channels, sizeof( *fd));
83+
for (i = 0 ; i < num_analog_channels ; ++i) {
84+
ret = fd[ i] = open( analog_channels[ i].device_path, O_RDONLY);
6485
if (ret < 0) {
6586
perror( "analog_thread: opening of ADC file failed");
6687
goto failure;
@@ -72,51 +93,51 @@ void* analog_worker( void* arg)
7293
* Update all adc values at a fixed rate, determined by ANALOG_CYCLE_TIME.
7394
* Spread the reads evenly over the cycle.
7495
*/
75-
usleep( ANALOG_CYCLE_TIME / analog_num_channels);
96+
usleep( ANALOG_CYCLE_TIME / num_analog_channels);
7697
ret = read( fd[ i], buf, sizeof( buf));
7798
if (ret > 0) {
7899
int val = atoi( buf);
79-
struct analog_data_record* p = &analog_data[ i];
100+
struct analog_channel_record* p = &analog_channels[ i];
80101
if (p->filter_length > 0) {
81102
int avg = p->average.value;
82103
int rem = p->average.remainder;
83104
int cnt = p->average.count;
84-
if (cnt < p->filter_length) {
85-
++cnt;
86-
p->average.count = cnt;
87-
}
88-
val = (cnt - 1) * avg + val + rem;
89-
p->average.value = val / cnt;
90-
p->average.remainder = val % cnt;
105+
if (cnt < p->filter_length) {
106+
++cnt;
107+
p->average.count = cnt;
108+
}
109+
val = (cnt - 1) * avg + val + rem;
110+
p->average.value = val / cnt;
111+
p->average.remainder = val % cnt;
91112
p->value = (val + rem + cnt / 2) / cnt;
92113
} else {
93-
p->value = val;
114+
p->value = val;
94115
}
95116
lseek( fd[ i], 0, SEEK_SET);
96117
} else if (ret < 0) {
97118
perror( "analog thread: ADC read failed -");
98119
goto failure;
99120
}
100121
++i;
101-
if (i == analog_num_channels) {
122+
if (i == num_analog_channels) {
102123
// Once every this often, push values to clients
103124
if (++cycle >= UPDATE_CYCLE_TIME / ANALOG_CYCLE_TIME) {
104-
unsigned int ch;
105-
for (ch = 0 ; ch < analog_num_channels ; ++ch) {
106-
struct analog_data_record* p = &analog_data[ ch];
107-
if (p->callback != NULL) {
108-
if (debug_flags & DEBUG_ANALOG) {
109-
fprintf( stderr, "analog_worker, calling temp_update for channel %d with value %d\n",
110-
p->channel, p->value);
111-
}
112-
(void) (p->callback)( p->channel, p->value);
113-
}
114-
}
125+
unsigned int ch;
126+
for (ch = 0 ; ch < num_analog_channels ; ++ch) {
127+
struct analog_channel_record* p = &analog_channels[ ch];
128+
if (p->callback != NULL) {
129+
if (debug_flags & DEBUG_ANALOG) {
130+
fprintf( stderr, "analog_worker, calling temp_update for %s with value %d\n",
131+
p->update_channel, p->value);
132+
}
133+
(void) (p->callback)( p->update_channel, p->value);
134+
}
135+
}
115136
if (debug_flags & DEBUG_ANALOG) {
116137
int ch;
117138
printf( "ADC values:");
118-
for (ch = 0 ; ch < analog_num_channels ; ++ch) {
119-
printf( " avg[ %d]=%d", ch, analog_data[ ch].value);
139+
for (ch = 0 ; ch < num_analog_channels ; ++ch) {
140+
printf( " avg[ %d]=%d", ch, analog_channels[ ch].value);
120141
}
121142
printf( "\n");
122143
}
@@ -134,16 +155,19 @@ void* analog_worker( void* arg)
134155
* a configuration call is used to communicate these with this
135156
* code.
136157
*/
137-
static const analog_config_struct* analog_config_data = NULL;
158+
static analog_config_record* analog_config_data = NULL;
138159
static int analog_config_items = 0;
139160

140-
int analog_config( const analog_config_struct* config_data, int nr_config_items)
161+
int analog_config( analog_config_record* config_data, int nr_config_items)
141162
{
163+
if (debug_flags & DEBUG_ANALOG) {
164+
printf( "analog_config called with %d records'\n", nr_config_items);
165+
}
142166
analog_config_data = config_data;
143167
analog_config_items = nr_config_items;
144-
// this shouldn't be called more than once, so keep the code simple
145-
analog_data = calloc( nr_config_items, sizeof( struct analog_data_record));
146-
analog_num_channels = 0;
168+
// this mustn't be called more than once, so keep the code simple
169+
analog_channels = calloc( nr_config_items, sizeof( struct analog_channel_record));
170+
num_analog_channels = 0;
147171
return 0;
148172
}
149173

@@ -153,31 +177,40 @@ static pthread_t worker;
153177
int analog_init( void)
154178
{
155179
unsigned int ch;
180+
if (debug_flags & DEBUG_ANALOG) {
181+
printf( "analog_init called'\n");
182+
}
156183
if (analog_config_data) {
157184
for (ch = 0 ; ch < analog_config_items ; ++ch) {
158-
struct analog_data_record* p = &analog_data[ ch];
159-
p->device_path = analog_config_data[ ch].device_path;
160-
p->filter_length = analog_config_data[ ch].filter_length;
161-
p->callback = NULL;
162-
p->value = 0;
163-
p->average.count = 0;
164-
p->average.value = 0;
165-
p->average.remainder = 0;
166-
++analog_num_channels;
185+
analog_config_record* ps = &analog_config_data[ ch];
186+
struct analog_channel_record* pd = &analog_channels[ ch];
187+
188+
pd->id = ps->tag;
189+
pd->device_path = ps->device_path;
190+
pd->filter_length = ps->filter_length;
191+
pd->callback = NULL;
192+
pd->value = 0;
193+
pd->average.count = 0;
194+
pd->average.value = 0;
195+
pd->average.remainder = 0;
196+
++num_analog_channels;
167197
}
168198
return mendel_thread_create( "analog", &worker, NULL, &analog_worker, NULL);
169199
}
170200
fprintf( stderr, "analog_init: no configuration data!\n");
171201
return -1;
172202
}
173203

174-
int analog_get_raw_value( unsigned int channel, int* value)
204+
int analog_get_raw_value( channel_tag analog_channel, int* pvalue)
175205
{
176-
if (value != NULL && channel >= 0 && channel < analog_num_channels) {
177-
// TODO: lock?
178-
*value = analog_data[ channel].value;
179-
// TODO: unlock?
180-
return 0;
206+
if (pvalue != NULL) {
207+
int ix = analog_index_lookup( analog_channel);
208+
if (ix >= 0) {
209+
// TODO: lock?
210+
*pvalue = analog_channels[ ix].value;
211+
// TODO: unlock?
212+
return 0;
213+
}
181214
}
182215
return -1;
183216
}

‎analog.h

+9-7
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
#ifndef _ANALOG_H
22
#define _ANALOG_H
33

4-
typedef struct {
4+
#include "beaglebone.h"
5+
6+
typedef const struct {
7+
channel_tag tag;
58
const char* device_path;
69
unsigned int filter_length;
7-
} analog_config_struct;
10+
} analog_config_record;
811

9-
typedef int update_channel_t;
10-
typedef int (update_callback)( update_channel_t, int);
12+
typedef int (update_callback)( channel_tag channel, int new_value);
1113

1214
extern int analog_init( void);
13-
extern int analog_set_update_callback( unsigned int analog_channel, update_callback* update, update_channel_t temp_channel);
14-
extern int analog_config( const analog_config_struct* config_data, int nr_config_items);
15+
extern int analog_set_update_callback( channel_tag analog_channel, update_callback* pupdate, channel_tag update_channel);
16+
extern int analog_config( analog_config_record* pconfig_data, int nr_config_items);
1517
// Do not use this, for debugging only!
16-
extern int analog_get_raw_value( unsigned int analog_channel, int* value);
18+
extern int analog_get_raw_value( channel_tag analog_channel, int* pvalue);
1719

1820
#endif

‎beaglebone.h

+3
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,7 @@
55

66
#define NR_ITEMS( x) (sizeof( (x)) / sizeof( *(x)))
77

8+
typedef const char* channel_tag;
9+
static inline const char* tag_name( channel_tag tag) { return (char*)tag; }
10+
811
#endif

‎bebopr_r2.c

+56-18
Original file line numberDiff line numberDiff line change
@@ -16,50 +16,88 @@
1616
//#define AIN_PATH_PREFIX "/sys/devices/platform/tsc/" /* kernel 3.2.0 */
1717
#define AIN_PATH_PREFIX "/sys/devices/platform/omap/tsc/" /* kernel 3.2.16 */
1818

19-
static const analog_config_struct analog_config_data[] = {
20-
{ // e_analog_1
19+
#define PWM_PATH_PREFIX "/sys/class/pwm/"
20+
21+
/*
22+
* Note, for the easy of implementation, the string addresses are used.
23+
* This means one cannot use identical strings, but must use pointers
24+
* to the one and only string!
25+
*/
26+
//#define GENERATE_TAG( name) static const char name[] = #name
27+
#define GENERATE_TAG( name) static const char name[] = #name
28+
GENERATE_TAG( bed_thermistor);
29+
GENERATE_TAG( extruder_thermistor);
30+
GENERATE_TAG( spare_ain);
31+
GENERATE_TAG( temp_extruder);
32+
GENERATE_TAG( temp_bed);
33+
GENERATE_TAG( heater_extruder);
34+
GENERATE_TAG( heater_bed);
35+
GENERATE_TAG( pwm_extruder);
36+
GENERATE_TAG( pwm_bed);
37+
GENERATE_TAG( pwm_fan);
38+
39+
static const analog_config_record analog_config_data[] = {
40+
{
41+
.tag = bed_thermistor,
2142
.device_path = AIN_PATH_PREFIX "ain2", // BEBOPR_R2_J6 - THRM0 (hardware ain1)
2243
.filter_length = 0,
2344
},
24-
{ // e_analog_2
45+
{
46+
.tag = spare_ain,
2547
.device_path = AIN_PATH_PREFIX "ain4", // BEBOPR_R2_J7 - THRM1 (hardware ain3)
2648
.filter_length = 10,
2749
},
28-
{ // e_analog_3
50+
{
51+
.tag = extruder_thermistor,
2952
.device_path = AIN_PATH_PREFIX "ain6", // BEBOPR_R2_J8 - THRM2 (hardware ain5)
30-
.filter_length = 10,
53+
.filter_length = 50,
3154
},
3255
};
3356

34-
static const temp_config_struct temp_config_data[] = {
57+
static const temp_config_record temp_config_data[] = {
3558
{
36-
.sensor = e_temp_extruder,
37-
.channel = 2, // index of THRM2 entry in analog_config_data
59+
.tag = temp_extruder,
60+
.source = extruder_thermistor,
3861
.in_range_time = 5000,
3962
.conversion = bone_epcos_b5760g104f,
4063
},
4164
{
42-
.sensor = e_temp_bed,
43-
.channel = 0, // index of THRM0 entry in analog_config_data
65+
.tag = temp_bed,
66+
.source = bed_thermistor,
4467
.in_range_time = 5000,
4568
.conversion = bone_thermistor_100k,
4669
},
4770
};
4871

49-
static const heater_config_struct heater_config_data[] = {
72+
static const heater_config_record heater_config_data[] = {
5073
{
51-
.heater = e_heater_extruder,
52-
.sensor = e_temp_extruder,
53-
.pwm_output = e_pwm_output_2
74+
.tag = heater_extruder,
75+
.analog_input = temp_extruder,
76+
.analog_output = pwm_extruder,
77+
.pid =
78+
{
79+
.K = 0.0,
80+
.P = 15.0,
81+
.I = 0.0,
82+
.D = 0.0,
83+
.I_limit = 12.0,
84+
},
5485
},
5586
{
56-
.heater = e_heater_bed,
57-
.sensor = e_temp_bed,
58-
.pwm_output = e_pwm_output_1
87+
.tag = heater_bed,
88+
.analog_input = temp_bed,
89+
.analog_output = pwm_bed,
90+
.pid =
91+
{
92+
.K = 0.0,
93+
.P = 1.0,
94+
.I = 0.0,
95+
.D = 0.0,
96+
.I_limit = 0.0,
97+
},
5998
},
6099
};
61100

62-
63101
int bebopr_pre_init( void)
64102
{
65103
int result = -1;

‎gcode_process.c

+52-32
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ uint8_t next_tool;
4040
static TARGET gcode_current_pos;
4141
static TARGET gcode_home_pos;
4242

43+
static channel_tag heater_extruder = NULL;
44+
static channel_tag heater_bed = NULL;
45+
static channel_tag temp_extruder = NULL;
46+
static channel_tag temp_bed = NULL;
47+
4348

4449
void gcode_trace_move( void)
4550
{
@@ -525,16 +530,17 @@ void process_gcode_command() {
525530
//?
526531
//? Set the temperature of the current extruder to 190<sup>o</sup>C and return control to the host immediately (''i.e.'' before that temperature has been reached by the extruder). See also M109.
527532
//? Teacup supports an optional P parameter as a sensor index to address (eg M104 P1 S100 will set the bed temperature rather than the extruder temperature).
528-
int channel = -1;
533+
channel_tag heater;
529534
if (next_target.seen_P) {
530535
switch (next_target.P) {
531-
case 0: channel = e_heater_extruder; break;
532-
case 1: channel = e_heater_bed; break;
536+
case 0: heater = "heater_extruder"; break;
537+
case 1: heater = "heater_bed"; break;
538+
default: heater = NULL;
533539
}
534540
} else {
535-
channel = e_heater_extruder;
541+
heater = "heater_extruder";
536542
}
537-
heater_set_setpoint( channel, next_target.S);
543+
heater_set_setpoint( heater_lookup_by_name( heater), next_target.S);
538544
if (next_target.S) {
539545
// if setpoint is not null, turn power on
540546
power_on();
@@ -552,24 +558,25 @@ void process_gcode_command() {
552558
//? <tt>ok T:201 B:117</tt>
553559
//?
554560
//? Teacup supports an optional P parameter as a sensor index to address.
555-
int channel = -1;
556561
double celsius;
557562
#ifdef ENFORCE_ORDER
558563
// wait for all moves to complete
559564
dda_queue_wait();
560565
#endif
561566
if (next_target.seen_P) {
567+
channel_tag temp_source;
562568
switch (next_target.P) {
563-
case 0: channel = e_heater_extruder; break;
564-
case 1: channel = e_heater_bed; break;
569+
case 0: temp_source = heater_extruder; break;
570+
case 1: temp_source = heater_bed; break;
571+
default: temp_source = NULL;
565572
}
566-
if (temp_get_celsius( channel, &celsius) == 0) {
573+
if (heater_get_celsius( temp_source, &celsius) == 0) {
567574
printf( "\nT:%1.1lf", celsius);
568575
}
569576
} else {
570-
temp_get_celsius( e_heater_extruder, &celsius);
577+
heater_get_celsius( heater_extruder, &celsius);
571578
printf( "\nT:%1.1lf", celsius);
572-
temp_get_celsius( e_heater_bed, &celsius);
579+
heater_get_celsius( heater_bed, &celsius);
573580
printf( " B:%1.1lf", celsius);
574581
}
575582
break;
@@ -619,13 +626,13 @@ void process_gcode_command() {
619626
//?
620627
//? Teacup supports an optional P parameter as a sensor index to address.
621628
if (next_target.seen_S) {
622-
heater_set_setpoint( e_heater_extruder, next_target.S);
629+
heater_set_setpoint( heater_extruder, next_target.S);
623630
power_on();
624631
}
625632
if (next_target.S) {
626-
heater_enable( e_heater_extruder, 1);
633+
heater_enable( heater_extruder, 1);
627634
} else {
628-
heater_enable( e_heater_extruder, 0);
635+
heater_enable( heater_extruder, 0);
629636
}
630637
dda_queue_enqueue( NULL);
631638
break;
@@ -657,6 +664,7 @@ void process_gcode_command() {
657664
//? This command is only available in DEBUG builds of Teacup.
658665

659666
debug_flags = next_target.S;
667+
printf( "New debug_flags setting: 0x%04x\n", debug_flags);
660668
break;
661669
#endif
662670
// M113- extruder PWM
@@ -720,29 +728,30 @@ void process_gcode_command() {
720728
//? P1: set for bed
721729
//? Snnn.nn: factor to set
722730
if (next_target.seen_S) {
723-
pid_struct pid;
724-
int channel = -1;
731+
pid_settings pid;
732+
channel_tag channel;
725733
if (next_target.seen_P) {
726734
switch (next_target.P) {
727-
case 0: channel = e_heater_extruder; break;
728-
case 1: channel = e_heater_bed; break;
735+
case 0: channel = heater_extruder; break;
736+
case 1: channel = heater_bed; break;
737+
default: channel = NULL;
729738
}
730739
} else {
731-
channel = e_heater_extruder;
740+
channel = heater_extruder;
732741
}
733742
heater_get_pid_values( channel, &pid);
734743
switch (next_target.M) {
735744
case 130: // M130- heater P factor
736-
pid.p = next_target.S;
745+
pid.P = next_target.S;
737746
break;
738747
case 131: // M131- heater I factor
739-
pid.i = next_target.S;
748+
pid.I = next_target.S;
740749
break;
741750
case 132: // M132- heater D factor
742-
pid.d = next_target.S;
751+
pid.D = next_target.S;
743752
break;
744753
case 133: // M133- heater I limit
745-
pid.i_limit = next_target.S;
754+
pid.I_limit = next_target.S;
746755
break;
747756
}
748757
heater_set_pid_values( channel, &pid);
@@ -759,7 +768,13 @@ void process_gcode_command() {
759768
//? ==== M135: set heater output ====
760769
//? Undocumented.
761770
if (next_target.seen_S) {
762-
heater_set_raw_pwm( next_target.P, next_target.S);
771+
channel_tag heater;
772+
switch (next_target.P) {
773+
case 0: heater = heater_extruder; break;
774+
case 1: heater = heater_bed; break;
775+
default: heater = NULL;
776+
}
777+
heater_set_raw_pwm( heater, next_target.S);
763778
power_on();
764779
}
765780
break;
@@ -769,27 +784,28 @@ void process_gcode_command() {
769784
//? ==== M136: PRINT PID settings to host ====
770785
//? Undocumented.
771786
//? This comand is only available in DEBUG builds.
772-
pid_struct pid;
773-
int channel = -1;
787+
pid_settings pid;
788+
channel_tag heater;
774789
if (next_target.seen_P) {
775790
switch (next_target.P) {
776-
case 0: channel = e_heater_extruder; break;
777-
case 1: channel = e_heater_bed; break;
791+
case 0: heater = heater_extruder; break;
792+
case 1: heater = heater_bed; break;
793+
default: heater = NULL;
778794
}
779795
} else {
780-
channel = e_heater_extruder;
796+
heater = heater_extruder;
781797
}
782-
heater_get_pid_values( channel, &pid);
798+
heater_get_pid_values( heater, &pid);
783799
fprintf( stdout, "P:%1.3f I:%1.3f D:%1.3f Ilim:%1.3f",
784-
pid.p, pid.i, pid.d, pid.i_limit);
800+
pid.P, pid.I, pid.D, pid.I_limit);
785801
break;
786802
}
787803
#endif
788804

789805
case 140: //Set heated bed temperature
790806
//? ==== M140: Set heated bed temperature ====
791807
//? Undocumented.
792-
heater_set_setpoint( e_heater_bed, next_target.S);
808+
heater_set_setpoint( heater_bed, next_target.S);
793809
if (next_target.S) {
794810
power_on();
795811
}
@@ -947,4 +963,8 @@ void process_gcode_command() {
947963
void gcode_process_init( void)
948964
{
949965
traject_init();
966+
heater_extruder = heater_lookup_by_name( "heater_extruder");
967+
heater_bed = heater_lookup_by_name( "heater_bed");
968+
temp_extruder = temp_lookup_by_name( "temp_extruder");
969+
temp_bed = temp_lookup_by_name( "temp_bed");
950970
}

‎heater.c

+237-488
Large diffs are not rendered by default.

‎heater.h

+25-47
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,45 @@
11
#ifndef _HEATER_H
22
#define _HEATER_H
33

4-
#if 0
5-
6-
#include "config.h"
7-
#include <stdint.h>
8-
#include "temp.h"
9-
10-
#define enable_heater() heater_set(0, 64)
11-
#define disable_heater() heater_set(0, 0)
12-
13-
#undef DEFINE_HEATER
14-
#define DEFINE_HEATER(name, pin) HEATER_ ## name,
15-
typedef enum
16-
{
17-
#include "config.h"
18-
NUM_HEATERS,
19-
HEATER_noheater
20-
} heater_t;
21-
#undef DEFINE_HEATER
22-
23-
#define NUM_HEATERS 2
24-
#define HEATER_EXTRUDER 1
25-
#define HEATER_BED 0
26-
27-
#endif
284

295
#include "temp.h"
306
#include "pwm.h"
7+
#include "beaglebone.h"
8+
319

3210
typedef struct {
33-
double k;
34-
double p;
35-
double i;
36-
double d;
37-
double i_limit;
38-
} pid_struct;
11+
double K;
12+
double P;
13+
double I;
14+
double D;
15+
double I_limit;
16+
} pid_settings;
3917

40-
typedef enum {
41-
e_heater_extruder,
42-
e_heater_bed,
43-
e_heater_num_outputs
44-
} heater_e;
18+
typedef const struct {
19+
channel_tag tag;
20+
channel_tag analog_input;
21+
channel_tag analog_output;
22+
pid_settings pid;
23+
double setpoint;
24+
} heater_config_record;
4525

46-
typedef struct {
47-
heater_e heater;
48-
temp_sensor_e sensor;
49-
pwm_output_e pwm_output;
50-
} heater_config_struct;
5126

27+
extern channel_tag heater_lookup_by_name( const char* name);
5228

53-
extern int heater_config( const heater_config_struct* config_data, int nr_config_items);
29+
extern int heater_config( heater_config_record* config_data, int nr_config_items);
5430
extern int heater_init( void);
5531
extern int heater_save_settings( void);
5632
extern int heater_load_settings( void);
5733

58-
extern int heater_set_pid_values( int heater, const pid_struct* pid_settings);
59-
extern int heater_get_pid_values( int heater, pid_struct* pid_settings);
60-
extern int heater_set_setpoint( int heater, double setpoint);
61-
extern int heater_get_setpoint( int heater, double* setpoint);
34+
extern int heater_set_pid_values( channel_tag heater, const pid_settings* pid_settings);
35+
extern int heater_get_pid_values( channel_tag heater, pid_settings* pid_settings);
36+
extern int heater_set_setpoint( channel_tag heater, double setpoint);
37+
extern int heater_get_setpoint( channel_tag heater, double* setpoint);
38+
extern int heater_enable( channel_tag heater, int state);
39+
extern int heater_set_raw_pwm( channel_tag heater, double percentage);
40+
extern int heater_get_celsius( channel_tag heater_channel, double* pcelsius);
6241

63-
extern int heater_enable( heater_e heater, int state);
64-
extern int heater_set_raw_pwm( int heater, double percentage);
42+
extern channel_tag heater_lookup_by_name( const char* name);
6543

6644
#if 0
6745
void heater_set(heater_t index, uint8_t value);

‎pwm.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ int pwm_init( void)
1010
return 0;
1111
}
1212

13-
int pwm_set_output( double percentage)
13+
int pwm_set_output( channel_tag ch, unsigned int percentage)
1414
{
1515
return 0;
1616
}

‎pwm.h

+2-7
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
11
#ifndef _PWM_H
22
#define _PWM_H
33

4-
typedef enum {
5-
e_pwm_output_1,
6-
e_pwm_output_2,
7-
e_pwm_output_3,
8-
e_pwm_num_outputs
9-
} pwm_output_e;
4+
#include "beaglebone.h"
105

116
extern int pwm_init( void);
12-
extern int pwm_set_output( double percentage);
7+
extern int pwm_set_output( channel_tag ch, unsigned int percentage);
138

149
#endif

‎temp.c

+85-50
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <stdlib.h>
99
#include <stdio.h>
1010
#include <stdint.h>
11+
#include <string.h>
1112

1213
#include "temp.h"
1314
#include "analog.h"
@@ -28,45 +29,64 @@
2829

2930
static const int out_of_range_time = 15;
3031

31-
static struct {
32-
double value;
33-
double setpoint;
34-
double range_low;
35-
double range_high;
36-
int out_of_range;
37-
temp_conversion_f* conversion;
38-
} temp_sensors[ e_temp_num_sensors];
32+
struct temp_channel {
33+
channel_tag id;
34+
channel_tag source;
35+
temp_conversion_f* conversion;
36+
unsigned int out_of_range;
37+
double value;
38+
double setpoint;
39+
double range_low;
40+
double range_high;
41+
};
42+
43+
static struct temp_channel* temp_channels;
44+
static unsigned int num_temp_channels;
45+
46+
static int temp_index_lookup( channel_tag temp_channel)
47+
{
48+
for (int ix = 0 ; ix < num_temp_channels ; ++ix) {
49+
if (temp_channels[ ix].id == temp_channel) {
50+
return ix;
51+
}
52+
}
53+
if (debug_flags & DEBUG_TEMP) {
54+
fprintf( stderr, "temp_index_lookup failed for '%s'\n", tag_name( temp_channel));
55+
}
56+
return -1;
57+
}
3958

4059
/*
4160
* Callback, called from adc processing thread in analog.c
4261
*/
43-
static int temp_update( update_channel_t channel, int analog_value)
62+
static int temp_update( channel_tag temp_channel, int analog_value)
4463
{
45-
if (channel >= 0 && channel <= e_temp_num_sensors) {
64+
int ix = temp_index_lookup( temp_channel);
65+
if (ix >= 0) {
4666
double celsius;
4767
int result;
48-
temp_conversion_f* convert = temp_sensors[ channel].conversion;
68+
temp_conversion_f* convert = temp_channels[ ix].conversion;
4969
if (convert != NULL) {
5070
result = convert( analog_value, &celsius);
5171
} else {
5272
celsius = (double) analog_value;
5373
result = 0;
5474
}
5575
if (debug_flags & DEBUG_TEMP) {
56-
fprintf( stderr, "temp_update called for channel %d with value %d => celsius %1.1lf\n",
57-
channel, analog_value, celsius);
76+
fprintf( stderr, "temp_update was called for '%s' with value %d => celsius %1.1lf\n",
77+
tag_name( temp_channel), analog_value, celsius);
5878
}
5979
if (result == 0) {
60-
temp_sensors[ channel].value = celsius;
80+
temp_channels[ ix].value = celsius;
6181
}
6282
if (result == 0 &&
63-
temp_sensors[ channel].range_low <= celsius &&
64-
celsius <= temp_sensors[ channel].range_high) {
65-
if (temp_sensors[ channel].out_of_range > 0) {
66-
--temp_sensors[ channel].out_of_range;
83+
temp_channels[ ix].range_low <= celsius &&
84+
celsius <= temp_channels[ ix].range_high) {
85+
if (temp_channels[ ix].out_of_range > 0) {
86+
--temp_channels[ ix].out_of_range;
6787
}
6888
} else {
69-
temp_sensors[ channel].out_of_range = out_of_range_time;
89+
temp_channels[ ix].out_of_range = out_of_range_time;
7090
}
7191
}
7292
return -1;
@@ -77,13 +97,15 @@ static int temp_update( update_channel_t channel, int analog_value)
7797
* a configuration call is used to communicate these with this
7898
* code.
7999
*/
80-
static const temp_config_struct* temp_config_data = NULL;
100+
static temp_config_record* temp_config_data = NULL;
81101
static int temp_config_items = 0;
82102

83-
int temp_config( const temp_config_struct* config_data, int nr_config_items)
103+
int temp_config( temp_config_record* config_data, int nr_config_items)
84104
{
85105
temp_config_data = config_data;
86106
temp_config_items = nr_config_items;
107+
num_temp_channels = 0;
108+
temp_channels = calloc( nr_config_items, sizeof( struct temp_channel));
87109
return 0;
88110
}
89111

@@ -94,50 +116,54 @@ int temp_init( void)
94116
{
95117
if (temp_config_data != NULL) {
96118
analog_init();
97-
for (int i = 0 ; i < temp_config_items ; ++i) {
98-
unsigned int analog_channel = temp_config_data[ i].channel;
99-
temp_sensor_e sensor = temp_config_data[ i].sensor;
100-
temp_conversion_f* conversion = temp_config_data[ i].conversion;
101-
temp_sensors[ sensor].out_of_range = temp_config_data[ i].in_range_time;
102-
temp_sensors[ sensor].conversion = conversion;
103-
analog_set_update_callback( analog_channel, temp_update, (update_channel_t)sensor);
119+
for (int ix = 0 ; ix < temp_config_items ; ++ix) {
120+
temp_config_record* ps = &temp_config_data[ ix];
121+
struct temp_channel* pd = &temp_channels[ ix];
122+
pd->id = ps->tag;
123+
pd->source = ps->source;
124+
pd->conversion = ps->conversion;
125+
pd->out_of_range = ps->in_range_time;
126+
if (analog_set_update_callback( ps->source, temp_update, ps->tag) < 0) {
127+
fprintf( stderr, "temp_init: could not connect callback for '%s' to source '%s'\n", ps->tag, ps->source);
128+
}
129+
++num_temp_channels;
104130
}
105131
return 0;
106132
}
107133
fprintf( stderr, "temp_init: no configuration data!\n");
108134
return -1;
109135
}
110136

111-
int temp_set_setpoint( temp_sensor_e channel, double setpoint, double delta_low, double delta_high)
137+
int temp_set_setpoint( channel_tag temp_channel, double setpoint, double delta_low, double delta_high)
112138
{
113-
int result = -1;
114-
if (channel >= 0 && channel <= e_temp_num_sensors) {
115-
temp_sensors[ channel].setpoint = setpoint;
116-
temp_sensors[ channel].range_low = setpoint - delta_low;
117-
temp_sensors[ channel].range_high = setpoint + delta_high;
118-
result = 0;
139+
int ix = temp_index_lookup( temp_channel);
140+
if (ix >= 0) {
141+
temp_channels[ ix].setpoint = setpoint;
142+
temp_channels[ ix].range_low = setpoint - delta_low;
143+
temp_channels[ ix].range_high = setpoint + delta_high;
144+
return 0;
119145
}
120-
return result;
146+
return -1;
121147
}
122148

123-
int temp_get_celsius( temp_sensor_e channel, double* celsius)
149+
int temp_get_celsius( channel_tag temp_channel, double* pcelsius)
124150
{
125-
int result = -1;
126-
if (channel >= 0 && channel < e_temp_num_sensors && celsius != NULL) {
127-
*celsius = temp_sensors[ channel].value;
128-
result = 0;
151+
if (pcelsius != NULL) {
152+
int ix = temp_index_lookup( temp_channel);
153+
if (ix >= 0) {
154+
*pcelsius = temp_channels[ ix].value;
155+
return 0;
156+
}
129157
}
130-
return result;
158+
return -1;
131159
}
132160

133161
/// report whether all temp sensors are reading their target temperatures
134162
/// used for M109 and friends
135163
int temp_achieved( void)
136164
{
137-
temp_sensor_e i;
138-
139-
for (i = 0 ; i < e_temp_num_sensors ; ++i) {
140-
if (temp_sensors[ i].out_of_range > 0) {
165+
for (int ix = 0 ; ix < num_temp_channels ; ++ix) {
166+
if (temp_channels[ ix].out_of_range > 0) {
141167
return 0;
142168
}
143169
}
@@ -154,13 +180,22 @@ void temp_tick( void)
154180

155181
int temp_all_zero( void)
156182
{
157-
temp_sensor_e i;
158-
159-
for (i = 0 ; i < e_temp_num_sensors ; ++i) {
160-
if (temp_sensors[ i].setpoint != 0.0) {
183+
for (int ix = 0 ; ix < num_temp_channels ; ++ix) {
184+
if (temp_channels[ ix].setpoint != 0.0) {
161185
return 0;
162186
}
163187
}
164188
return 1;
165189
}
166190

191+
channel_tag temp_lookup_by_name( const char* name)
192+
{
193+
for (int ix = 0 ; ix < num_temp_channels ; ++ix) {
194+
channel_tag tag = temp_channels[ ix].id;
195+
if (strcmp( tag_name( tag), name) == 0) {
196+
return tag;
197+
}
198+
}
199+
return NULL;
200+
}
201+

‎temp.h

+16-18
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,32 @@
22
#define _TEMP_H
33

44

5-
#include "analog.h"
5+
#include "beaglebone.h"
66

77
/*
88
* This (temp.[ch]) code links an analog input channel and a conversion function to a temperature sensor.
99
* At least, a sensor for the extruder needs to be defined. A sensor for a heated bed is optional.
1010
* The sensors will be used by the heater code and might be used by other temperature sensing/logging code.
1111
*/
12-
typedef enum {
13-
e_temp_extruder,
14-
e_temp_bed,
15-
e_temp_num_sensors
16-
} temp_sensor_e;
17-
18-
typedef int (temp_conversion_f) (int in, double* out);
19-
20-
typedef struct {
21-
unsigned int channel;
22-
temp_sensor_e sensor;
23-
int in_range_time; // ms
12+
13+
typedef int (temp_conversion_f) (int in, double* pout);
14+
15+
typedef const struct {
16+
channel_tag tag;
17+
channel_tag source;
18+
unsigned int in_range_time; // ms
2419
temp_conversion_f* conversion;
25-
} temp_config_struct;
20+
} temp_config_record;
21+
22+
extern channel_tag temp_lookup_by_name( const char* name);
2623

27-
extern int temp_config( const temp_config_struct* config_data, int nr_config_items);
24+
extern int temp_config( temp_config_record* config_data, int nr_config_items);
2825
extern int temp_init( void);
29-
extern int temp_get_celsius( temp_sensor_e channel, double* celsius);
26+
//extern channel_tag temp_lookup_by_name( const char* id);
27+
extern int temp_get_celsius( channel_tag channel, double* pcelsius);
3028
extern int temp_achieved( void);
31-
extern int temp_set_setpoint( temp_sensor_e channel, double setpoint, double delta_low, double delta_high);
32-
extern int temp_get_setpoint( temp_sensor_e channel, double* setpoint);
29+
extern int temp_set_setpoint( channel_tag channel, double setpoint, double delta_low, double delta_high);
30+
extern int temp_get_setpoint( channel_tag channel, double* psetpoint);
3331
// TODO: remove the following two from all code:
3432
extern void temp_tick( void);
3533
extern int temp_all_zero( void);

0 commit comments

Comments
 (0)
Please sign in to comment.