Merge remote-tracking branch 'upstream/edge' into add/universal-panel-adapter
[clinton/Smoothieware.git] / src / libs / Config.cpp
CommitLineData
df27a6a3 1/*
4cff3ded
AW
2 This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
3 Smoothie is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
4 Smoothie is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
df27a6a3 5 You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>.
4cff3ded
AW
6*/
7
3c132bd0
AW
8using namespace std;
9#include <vector>
4cff3ded 10#include <string>
3c132bd0 11
4cff3ded
AW
12#include "libs/Kernel.h"
13#include "Config.h"
c295905f
AW
14#include "ConfigValue.h"
15#include "ConfigSource.h"
16#include "ConfigCache.h"
4eb9c745
AW
17#include "libs/nuts_bolts.h"
18#include "libs/utils.h"
6268c527 19#include "libs/SerialMessage.h"
c295905f 20#include "libs/ConfigSources/FileConfigSource.h"
33110301 21#include "libs/ConfigSources/FirmConfigSource.h"
a2f7633f 22#include "StreamOutputPool.h"
4cff3ded 23
93694d6b
AW
24// Add various config sources. Config can be fetched from several places.
25// All values are read into a cache, that is then used by modules to read their configuration
577414f6
JM
26Config::Config()
27{
a2f7633f 28 this->config_cache = NULL;
fc82a1ee 29
33110301 30 // Config source for firm config found in src/config.default
577414f6 31 this->config_sources.push_back( new FirmConfigSource("firm") );
33110301 32
c295905f 33 // Config source for */config files
577414f6 34 FileConfigSource *fcs = NULL;
40a7c6c0 35 if( file_exists("/local/config") )
577414f6 36 fcs = new FileConfigSource("/local/config", "local");
40a7c6c0 37 else if( file_exists("/local/config.txt") )
577414f6
JM
38 fcs = new FileConfigSource("/local/config.txt", "local");
39 if( fcs != NULL ) {
40a7c6c0 40 this->config_sources.push_back( fcs );
247f7afd
L
41 fcs = NULL;
42 }
40a7c6c0 43 if( file_exists("/sd/config") )
577414f6 44 fcs = new FileConfigSource("/sd/config", "sd");
40a7c6c0 45 else if( file_exists("/sd/config.txt") )
577414f6 46 fcs = new FileConfigSource("/sd/config.txt", "sd");
40a7c6c0
L
47 if( fcs != NULL )
48 this->config_sources.push_back( fcs );
cebe90b6
AW
49}
50
577414f6 51void Config::on_module_loaded() {}
26806df9 52
577414f6 53void Config::on_console_line_received( void *argument ) {}
ced5fce8 54
93694d6b 55// Set a value in the config cache, but not in any config source
577414f6
JM
56void Config::set_string( string setting, string value )
57{
a2f7633f
JM
58 if(!is_config_cache_loaded()) return;
59
577414f6 60 ConfigValue *cv = new ConfigValue;
ced5fce8 61 cv->found = true;
4464301d 62 get_checksums(cv->check_sums, setting);
ced5fce8
L
63 cv->value = value;
64
a2f7633f 65 this->config_cache->replace_or_push_back(cv);
ced5fce8 66
314ab8f7 67 THEKERNEL->call_event(ON_CONFIG_RELOAD);
ced5fce8
L
68}
69
93694d6b 70// Get a list of modules, used by module "pools" that look for the "enable" keyboard to find things like "moduletype.modulename.enable" as the marker of a new instance of a module
577414f6
JM
71void Config::get_module_list(vector<uint16_t> *list, uint16_t family)
72{
a2f7633f 73 this->config_cache->collect(family, CHECKSUM("enable"), list);
26c569a2 74}
26806df9 75
d272dd3c 76// Command to load config cache into buffer for multiple reads during init
a2f7633f 77void Config::config_cache_load(bool parse)
577414f6 78{
93694d6b 79 // First clear the cache
d272dd3c 80 this->config_cache_clear();
c295905f 81
a2f7633f
JM
82 this->config_cache= new ConfigCache;
83 if(parse) {
84 // For each ConfigSource in our stack
85 for( ConfigSource *source : this->config_sources ) {
86 source->transfer_values_to_cache(this->config_cache);
87 }
c295905f 88 }
d272dd3c
L
89}
90
91// Command to clear the config cache after init
577414f6
JM
92void Config::config_cache_clear()
93{
a2f7633f
JM
94 delete this->config_cache;
95 this->config_cache= NULL;
da24d6ae
AW
96}
97
93694d6b 98// Three ways to read a value from the config, depending on adress length
577414f6
JM
99ConfigValue *Config::value(uint16_t check_sum_a, uint16_t check_sum_b, uint16_t check_sum_c )
100{
df27a6a3
MM
101 uint16_t check_sums[3];
102 check_sums[0] = check_sum_a;
4464301d
AW
103 check_sums[1] = check_sum_b;
104 check_sums[2] = check_sum_c;
3c132bd0 105 return this->value(check_sums);
df27a6a3 106}
3c132bd0 107
d41a043b
JM
108static ConfigValue dummyValue;
109
4cff3ded
AW
110// Get a value from the configuration as a string
111// Because we don't like to waste space in Flash with lengthy config parameter names, we take a checksum instead so that the name does not have to be stored
112// See get_checksum
577414f6
JM
113ConfigValue *Config::value(uint16_t check_sums[])
114{
a2f7633f
JM
115 if( !is_config_cache_loaded() ) {
116 THEKERNEL->streams->printf("ERROR: calling value after config cache has been cleared\n");
117 // note this will cause whatever called it to blow up!
118 return NULL;
d272dd3c 119 }
2b56b363 120
a2f7633f
JM
121 ConfigValue *result = this->config_cache->lookup(check_sums);
122
123 if(result == NULL) {
124 // create a dummy value for this to play with, each call requires it's own value not a shared one
d41a043b
JM
125 // result= new ConfigValue(check_sums);
126 // config_cache->add(result);
127 dummyValue.clear();
128 result = &dummyValue;
d272dd3c 129 }
a2f7633f 130
b66fb830 131 return result;
4cff3ded
AW
132}
133
3c132bd0 134
4cff3ded 135