From 93694d6b1ef4738d2d43377537c69340f6f3a758 Mon Sep 17 00:00:00 2001 From: Arthur Wolf Date: Tue, 16 Apr 2013 16:57:48 +0200 Subject: [PATCH] Added comments to most files in libs/ --- src/libs/Adc.cpp | 6 ++++++ src/libs/Config.cpp | 8 ++++++-- src/libs/Hook.cpp | 2 ++ src/libs/Hook.h | 2 ++ src/libs/Kernel.cpp | 14 ++++++++++---- src/libs/MRI_Hooks.cpp | 3 +++ src/libs/Module.cpp | 3 +++ src/libs/Pauser.cpp | 10 ++++++++-- src/libs/Pin.cpp | 27 +++++++++++++-------------- src/libs/Pwm.cpp | 2 ++ src/libs/SlowTicker.cpp | 36 +++++++++++++++++++++--------------- src/libs/StepTicker.cpp | 15 ++------------- src/libs/StepperMotor.cpp | 18 ++++++++++-------- src/libs/StreamOutput.h | 4 ++++ src/libs/Watchdog.cpp | 3 +++ 15 files changed, 95 insertions(+), 58 deletions(-) diff --git a/src/libs/Adc.cpp b/src/libs/Adc.cpp index d19ca134..5ba020a6 100644 --- a/src/libs/Adc.cpp +++ b/src/libs/Adc.cpp @@ -14,10 +14,14 @@ using namespace std; #include "libs/ADC/adc.h" #include "libs/Pin.h" +// This is an interface to the mbed.org ADC library you can find in libs/ADC/adc.h +// TODO : Having the same name is confusing, should change that + Adc::Adc(){ this->adc = new ADC(1000, 1); } +// Enables ADC on a given pin void Adc::enable_pin(Pin* pin){ PinName pin_name = this->_pin_to_pinname(pin); this->adc->burst(1); @@ -25,10 +29,12 @@ void Adc::enable_pin(Pin* pin){ this->adc->interrupt_state(pin_name,1); } +// Read the last value ( burst mode ) on a given pin unsigned int Adc::read(Pin* pin){ return this->adc->read(this->_pin_to_pinname(pin)); } +// Convert a smoothie Pin into a mBed Pin PinName Adc::_pin_to_pinname(Pin* pin){ if( pin->port == LPC_GPIO0 && pin->pin == 23 ){ return p15; diff --git a/src/libs/Config.cpp b/src/libs/Config.cpp index 0d97dfb7..b2d9bc0e 100644 --- a/src/libs/Config.cpp +++ b/src/libs/Config.cpp @@ -5,7 +5,6 @@ You should have received a copy of the GNU General Public License along with Smoothie. If not, see . */ - using namespace std; #include #include @@ -21,6 +20,8 @@ using namespace std; #include "libs/ConfigSources/FileConfigSource.h" #include "libs/ConfigSources/FirmConfigSource.h" +// Add various config sources. Config can be fetched from several places. +// All values are read into a cache, that is then used by modules to read their configuration Config::Config(){ this->config_cache_loaded = false; @@ -53,6 +54,7 @@ void Config::on_module_loaded(){} void Config::on_console_line_received( void* argument ){} +// Set a value in the config cache, but not in any config source void Config::set_string( string setting, string value ){ ConfigValue* cv = new ConfigValue; cv->found = true; @@ -64,6 +66,7 @@ void Config::set_string( string setting, string value ){ this->kernel->call_event(ON_CONFIG_RELOAD); } +// 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 void Config::get_module_list(vector* list, uint16_t family){ for( unsigned int i=1; iconfig_cache.size(); i++){ ConfigValue* value = this->config_cache.at(i); @@ -79,6 +82,7 @@ void Config::get_module_list(vector* list, uint16_t family){ // Command to load config cache into buffer for multiple reads during init void Config::config_cache_load(){ + // First clear the cache this->config_cache_clear(); // First element is a special empty ConfigValue for values not found @@ -103,7 +107,7 @@ void Config::config_cache_clear(){ this->config_cache_loaded = false; } - +// Three ways to read a value from the config, depending on adress length ConfigValue* Config::value(uint16_t check_sum_a, uint16_t check_sum_b, uint16_t check_sum_c ){ uint16_t check_sums[3]; check_sums[0] = check_sum_a; diff --git a/src/libs/Hook.cpp b/src/libs/Hook.cpp index 6657a76d..6fda110c 100644 --- a/src/libs/Hook.cpp +++ b/src/libs/Hook.cpp @@ -3,4 +3,6 @@ extern "C"{ } #include "Hook.h" +// Hook is just a glorified FPointer + Hook::Hook(){} diff --git a/src/libs/Hook.h b/src/libs/Hook.h index b7d65c8a..69d10ec6 100644 --- a/src/libs/Hook.h +++ b/src/libs/Hook.h @@ -2,6 +2,8 @@ #define HOOK_H #include "libs/FPointer.h" +// Hook is just a glorified FPointer + class Hook : public FPointer { public: Hook(); diff --git a/src/libs/Kernel.cpp b/src/libs/Kernel.cpp index 4f38c0fb..c1e06472 100644 --- a/src/libs/Kernel.cpp +++ b/src/libs/Kernel.cpp @@ -29,8 +29,8 @@ #define baud_rate_setting_checksum CHECKSUM("baud_rate") #define uart0_checksum CHECKSUM("uart0") -static int isDebugMonitorUsingUart0() -{ +// This is used to configure UARTs depending on the MRI configuration, see Kernel::Kernel() +static int isDebugMonitorUsingUart0(){ return NVIC_GetPriority(UART0_IRQn) == 0; } @@ -43,14 +43,15 @@ Kernel::Kernel(){ this->streams = new StreamOutputPool(); // Configure UART depending on MRI config + // If MRI is using UART0, we want to use UART1, otherwise, we want to use UART0. This makes it easy to use only one UART for both debug and actual commands. NVIC_SetPriorityGrouping(0); if( !isDebugMonitorUsingUart0() ){ this->serial = new SerialConsole(USBTX, USBRX, this->config->value(uart0_checksum,baud_rate_setting_checksum)->by_default(9600)->as_number()); }else{ this->serial = new SerialConsole(p13, p14, this->config->value(uart0_checksum,baud_rate_setting_checksum)->by_default(9600)->as_number()); } - this->add_module( this->config ); + this->add_module( this->config ); this->add_module( this->serial ); // HAL stuff @@ -58,6 +59,7 @@ Kernel::Kernel(){ this->step_ticker = new StepTicker(); this->adc = new Adc(); + // TODO : These should go into platform-specific files // LPC17xx-specific NVIC_SetPriorityGrouping(0); NVIC_SetPriority(TIMER0_IRQn, 2); @@ -85,8 +87,8 @@ Kernel::Kernel(){ int base_stepping_frequency = this->config->value(base_stepping_frequency_checksum )->by_default(100000)->as_number(); double microseconds_per_step_pulse = this->config->value(microseconds_per_step_pulse_checksum )->by_default(5 )->as_number(); + // Configure the step ticker ( TODO : shouldnt this go into stepticker's code ? ) this->step_ticker->set_reset_delay( microseconds_per_step_pulse / 1000000L ); - this->step_ticker->set_frequency( base_stepping_frequency ); // Core modules @@ -99,21 +101,25 @@ Kernel::Kernel(){ } +// Add a module to Kernel. We don't actually hold a list of modules, we just tell it where Kernel is void Kernel::add_module(Module* module){ module->kernel = this; module->on_module_loaded(); } +// Adds a hook for a given module and event void Kernel::register_for_event(_EVENT_ENUM id_event, Module* module){ this->hooks[id_event].push_back(module); } +// Call a specific event without arguments void Kernel::call_event(_EVENT_ENUM id_event){ for (Module* current : hooks[id_event]) { (current->*kernel_callback_functions[id_event])(this); } } +// Call a specific event with an argument void Kernel::call_event(_EVENT_ENUM id_event, void * argument){ for (Module* current : hooks[id_event]) { (current->*kernel_callback_functions[id_event])(argument); diff --git a/src/libs/MRI_Hooks.cpp b/src/libs/MRI_Hooks.cpp index c16a8ebe..f0e6db95 100644 --- a/src/libs/MRI_Hooks.cpp +++ b/src/libs/MRI_Hooks.cpp @@ -3,6 +3,9 @@ #include #include +// This is used by MRI to turn pins on and off when entering and leaving MRI. Useful for not burning everything down +// See http://smoothieware.org/mri-debugging + extern "C" { static uint32_t _set_high_on_debug[5] = { // (1 << 4) | (1 << 10) | (1 << 19) | (1 << 21), // smoothieboard stepper EN pins diff --git a/src/libs/Module.cpp b/src/libs/Module.cpp index c3182800..b53487f5 100644 --- a/src/libs/Module.cpp +++ b/src/libs/Module.cpp @@ -8,6 +8,9 @@ #include "libs/Module.h" #include "libs/Kernel.h" +// Events are the basic building blocks of Smoothie. They register for events, and then do stuff when those events are called. +// You add things to Smoothie by making a new class that inherits the Module class. See http://smoothieware.org/moduleexample for a crude introduction + const ModuleCallback kernel_callback_functions[NUMBER_OF_DEFINED_EVENTS] = { #define EVENT(name, func) &Module::func , #include "Event.h" diff --git a/src/libs/Pauser.cpp b/src/libs/Pauser.cpp index 01b93ae4..6630b148 100644 --- a/src/libs/Pauser.cpp +++ b/src/libs/Pauser.cpp @@ -5,12 +5,17 @@ #include using namespace std; +// The Pauser module is the core of the pausing subsystem in smoothie. Basically we want several modules to be able to pause smoothie at the same time +// ( think both the user with a button, and the temperature control because a temperature is not reached ). To do that, modules call the take() methode, +// a pause event is called, and the pause does not end before all modules have called the release() method. +// Please note : Modules should keep track of their pause status themselves Pauser::Pauser(){} void Pauser::on_module_loaded(){ this->counter = 0; } +// Pause smoothie if nobody else is currently doing so void Pauser::take(){ this->counter++; //this->kernel->streams->printf("take: %u \r\n", this->counter ); @@ -19,6 +24,7 @@ void Pauser::take(){ } } +// Unpause smoothie unless something else is pausing it too void Pauser::release(){ this->counter--; //this->kernel->streams->printf("release: %u \r\n", this->counter ); @@ -27,7 +33,7 @@ void Pauser::release(){ } } -bool Pauser::paused() -{ +// Return wether smoothie is paused +bool Pauser::paused(){ return (counter != 0); } diff --git a/src/libs/Pin.cpp b/src/libs/Pin.cpp index faded396..f658c129 100644 --- a/src/libs/Pin.cpp +++ b/src/libs/Pin.cpp @@ -4,8 +4,10 @@ Pin::Pin(){} -Pin* Pin::from_string(std::string value) -{ +// Make a new pin object from a string +// TODO : Comment this more, how does it work ? +// TODO : Make this able to configure pull-up, pull-down, and open-drain +Pin* Pin::from_string(std::string value){ LPC_GPIO_TypeDef* gpios[5] ={LPC_GPIO0,LPC_GPIO1,LPC_GPIO2,LPC_GPIO3,LPC_GPIO4}; // cs is the current position in the string @@ -14,15 +16,12 @@ Pin* Pin::from_string(std::string value) char* cn = NULL; this->port_number = strtol(cs, &cn, 10); - if ((cn > cs) && (port_number <= 4)) - { + if ((cn > cs) && (port_number <= 4)){ this->port = gpios[(unsigned int) this->port_number]; - if (*cn == '.') - { + if (*cn == '.'){ cs = ++cn; this->pin = strtol(cs, &cn, 10); - if ((cn > cs) & (pin < 32)) - { + if ((cn > cs) & (pin < 32)){ while (is_whitespace(*cn)) cn++; this->inverting = (*cn == '!'); @@ -40,8 +39,8 @@ Pin* Pin::from_string(std::string value) return this; } -Pin* Pin::as_open_drain() -{ +// Configure this pin as OD +Pin* Pin::as_open_drain(){ if (this->pin >= 32) return this; if( this->port_number == 0 ){ LPC_PINCON->PINMODE_OD0 |= (1<pin); } if( this->port_number == 1 ){ LPC_PINCON->PINMODE_OD1 |= (1<pin); } @@ -51,8 +50,8 @@ Pin* Pin::as_open_drain() return this; } -Pin* Pin::pull_up() -{ +// Configure this pin as a pullup +Pin* Pin::pull_up(){ if (this->pin >= 32) return this; // Set the two bits for this pin as 00 if( this->port_number == 0 && this->pin < 16 ){ LPC_PINCON->PINMODE0 &= ~(3<<( this->pin *2)); } @@ -65,8 +64,8 @@ Pin* Pin::pull_up() return this; } -Pin* Pin::pull_down() -{ +// Configure this pin as a pulldown +Pin* Pin::pull_down(){ if (this->pin >= 32) return this; // Set the two bits for this pin as 11 if( this->port_number == 0 && this->pin < 16 ){ LPC_PINCON->PINMODE0 |= (3<<( this->pin *2)); } diff --git a/src/libs/Pwm.cpp b/src/libs/Pwm.cpp index 55e70d70..dd9888e2 100644 --- a/src/libs/Pwm.cpp +++ b/src/libs/Pwm.cpp @@ -4,6 +4,8 @@ #define PID_PWM_MAX 256 +// What ? + Pwm::Pwm() { _max = PID_PWM_MAX - 1; diff --git a/src/libs/SlowTicker.cpp b/src/libs/SlowTicker.cpp index 721a5a89..c0a80be3 100644 --- a/src/libs/SlowTicker.cpp +++ b/src/libs/SlowTicker.cpp @@ -16,19 +16,26 @@ using namespace std; #include +// This module uses a Timer to periodically call hooks +// Modules register with a function ( callback ) and a frequency, and we then call that function at the given frequency. + SlowTicker* global_slow_ticker; SlowTicker::SlowTicker(){ max_frequency = 0; global_slow_ticker = this; + + // Configure the actual timer LPC_SC->PCONP |= (1 << 22); // Power Ticker ON - LPC_TIM2->MR0 = 10000; // Initial dummy value for Match Register + LPC_TIM2->MR0 = 10000; // Initial dummy value for Match Register LPC_TIM2->MCR = 3; // Match on MR0, reset on MR0 LPC_TIM2->TCR = 1; // Enable interrupt NVIC_EnableIRQ(TIMER2_IRQn); // Enable interrupt handler + // ISP button ispbtn.from_string("2.10")->as_input()->pull_up(); + // TODO: What is this ?? flag_1s_flag = 0; flag_1s_count = SystemCoreClock; @@ -42,6 +49,7 @@ void SlowTicker::on_module_loaded(){ register_for_event(ON_GCODE_EXECUTE); } +// Set the base frequency we use for all sub-frequencies void SlowTicker::set_frequency( int frequency ){ this->interval = (SystemCoreClock >> 2) / frequency; // SystemCoreClock/4 = Timer increments in a second LPC_TIM2->MR0 = this->interval; @@ -49,9 +57,10 @@ void SlowTicker::set_frequency( int frequency ){ LPC_TIM2->TCR = 1; // Reset } +// The actual interrupt being called by the timer, this is where work is done void SlowTicker::tick(){ - _isr_context = true; - + + // Call all hooks that need to be called ( bresenham ) for (uint32_t i=0; ihooks.size(); i++){ Hook* hook = this->hooks.at(i); hook->countdown -= this->interval; @@ -77,12 +86,11 @@ void SlowTicker::tick(){ g4_ticks = 0; } - LPC_GPIO1->FIOCLR = 1<<20; - + // Enter MRI mode if the ISP button is pressed + // TODO : This should have it's own module if (ispbtn.get() == 0) __debugbreak(); - _isr_context = false; } bool SlowTicker::flag_1s(){ @@ -110,6 +118,7 @@ void SlowTicker::on_idle(void*) } } +// When a G4-type gcode is received, add it to the queue so we can execute it in time void SlowTicker::on_gcode_received(void* argument){ Gcode* gcode = static_cast(argument); // Add the gcode to the queue ourselves if we need it @@ -122,14 +131,13 @@ void SlowTicker::on_gcode_received(void* argument){ } } } - + +// When a G4-type gcode is executed, start the pause void SlowTicker::on_gcode_execute(void* argument){ Gcode* gcode = static_cast(argument); - if (gcode->has_g) - { - if (gcode->g == 4) - { + if (gcode->has_g){ + if (gcode->g == 4){ bool updated = false; if (gcode->has_letter('P')) { updated = true; @@ -139,12 +147,10 @@ void SlowTicker::on_gcode_execute(void* argument){ updated = true; g4_ticks += gcode->get_int('S') * (SystemCoreClock >> 2); } - if (updated) - { + if (updated){ // G4 Smm Pnn should pause for mm seconds + nn milliseconds // at 120MHz core clock, the longest possible delay is (2^32 / (120MHz / 4)) = 143 seconds - if (!g4_pause) - { + if (!g4_pause){ g4_pause = true; kernel->pauser->take(); } diff --git a/src/libs/StepTicker.cpp b/src/libs/StepTicker.cpp index da35c42e..1e78737e 100644 --- a/src/libs/StepTicker.cpp +++ b/src/libs/StepTicker.cpp @@ -22,10 +22,11 @@ using namespace std; // They then do Bresenham stuff themselves StepTicker* global_step_ticker; -int debug_counter; StepTicker::StepTicker(){ global_step_ticker = this; + + // Configure the timer LPC_TIM0->MR0 = 10000000; // Initial dummy value for Match Register LPC_TIM0->MCR = 3; // Match on MR0, reset on MR0, match on MR1 LPC_TIM0->TCR = 0; // Disable interrupt @@ -48,8 +49,6 @@ StepTicker::StepTicker(){ } this->active_motor_bm = 0; - debug_counter = 0; - NVIC_EnableIRQ(TIMER0_IRQn); // Enable interrupt handler NVIC_EnableIRQ(TIMER1_IRQn); // Enable interrupt handler } @@ -137,11 +136,6 @@ extern "C" void TIMER1_IRQHandler (void){ global_step_ticker->reset_tick(); } - -//#pragma GCC push_options -//#pragma GCC optimize ("O0") - - // The actual interrupt handler where we do all the work extern "C" void TIMER0_IRQHandler (void){ @@ -149,15 +143,12 @@ extern "C" void TIMER0_IRQHandler (void){ LPC_TIM0->IR |= 1 << 0; // Step pins - //global_step_ticker->tick(); - _isr_context = true; uint16_t bitmask = 1; for (uint8_t motor = 0; motor < 12; motor++, bitmask <<= 1){ if (global_step_ticker->active_motor_bm & bitmask){ global_step_ticker->active_motors[motor]->tick(); } } - _isr_context = false; // We may have set a pin on in this tick, now we start the timer to set it off if( global_step_ticker->reset_step_pins ){ @@ -230,8 +221,6 @@ extern "C" void TIMER0_IRQHandler (void){ } -//#pragma GCC pop_options - // We make a list of steppers that want to be called so that we don't call them for nothing void StepTicker::add_motor_to_active_list(StepperMotor* motor) { diff --git a/src/libs/StepperMotor.cpp b/src/libs/StepperMotor.cpp index 860b0c00..7013126b 100644 --- a/src/libs/StepperMotor.cpp +++ b/src/libs/StepperMotor.cpp @@ -9,6 +9,9 @@ #include "StepperMotor.h" #include "MRI_Hooks.h" +// A StepperMotor represents an actual stepper motor. It is used to generate steps that move the actual motor at a given speed +// TODO : Abstract this into Actuator + StepperMotor::StepperMotor(){ this->moving = false; this->paused = false; @@ -37,9 +40,10 @@ StepperMotor::StepperMotor(Pin* step, Pin* dir, Pin* en) : step_pin(step), dir_p set_high_on_debug(en->port_number, en->pin); } +// This is called ( see the .h file, we had to put a part of things there for obscure inline reasons ) when a step has to be generated +// we also here check if the move is finished etc ... void StepperMotor::step(){ - // output to pins 37t this->step_pin->set( 1 ); this->step_ticker->reset_step_pins = true; @@ -55,13 +59,14 @@ void StepperMotor::step(){ this->step_signal_hook->call(); } - // is this move finished ? 11t + // Is this move finished ? if( this->stepped == this->steps_to_move ){ + // Mark it as finished, then StepTicker will call signal_mode_finished() + // This is so we don't call that before all the steps have been generated for this tick() this->is_move_finished = true; this->step_ticker->moves_finished = true; } - } @@ -123,9 +128,6 @@ void StepperMotor::move( bool direction, unsigned int steps ){ } -//#pragma GCC push_options -//#pragma GCC optimize ("O0") - // Set the speed at which this steper moves void StepperMotor::set_speed( double speed ){ @@ -142,13 +144,13 @@ void StepperMotor::set_speed( double speed ){ } -//#pragma GCC pop_options - +// Pause this stepper motor void StepperMotor::pause(){ this->paused = true; this->update_exit_tick(); } +// Unpause this stepper motor void StepperMotor::unpause(){ this->paused = false; this->update_exit_tick(); diff --git a/src/libs/StreamOutput.h b/src/libs/StreamOutput.h index 492fb3d8..417c6453 100644 --- a/src/libs/StreamOutput.h +++ b/src/libs/StreamOutput.h @@ -12,6 +12,10 @@ #include #include +// This is a base class for all StreamOutput objects. +// StreamOutputs are basically "things you can sent strings to". They are passed along with gcodes for example so modules can answer to those gcodes. +// They are usually associated with a command source, but can also be a NullStreamOutput if we just want to ignore whatever is sent + class NullStreamOutput; class StreamOutput : public mbed::Stream { diff --git a/src/libs/Watchdog.cpp b/src/libs/Watchdog.cpp index 4aa414a1..38eda930 100644 --- a/src/libs/Watchdog.cpp +++ b/src/libs/Watchdog.cpp @@ -4,6 +4,9 @@ #include +// TODO : comment this +// Basically, when stuff stop answering, reset, or enter MRI mode, or something + Watchdog::Watchdog(uint32_t timeout, WDT_ACTION action) { WDT_Init(WDT_CLKSRC_IRC, (action == WDT_MRI)?WDT_MODE_INT_ONLY:WDT_MODE_RESET); -- 2.20.1