promote Pwm functions to a new class that overloads Pin, alter use of Pwm in Temperat...
[clinton/Smoothieware.git] / src / libs / Kernel.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
4cff3ded
AW
8#include "libs/Kernel.h"
9#include "libs/Module.h"
10#include "libs/Config.h"
4cff3ded 11#include "libs/nuts_bolts.h"
ded56b35 12#include "libs/SlowTicker.h"
3c132bd0 13#include "libs/Adc.h"
0e8b102e 14#include "libs/Digipot.h"
81b547a1 15#include "libs/Pauser.h"
38d375e7 16#include "libs/StreamOutputPool.h"
4c4a372a 17#include <mri.h>
4cff3ded
AW
18
19#include "modules/communication/SerialConsole.h"
20#include "modules/communication/GcodeDispatch.h"
21#include "modules/robot/Planner.h"
22#include "modules/robot/Robot.h"
23#include "modules/robot/Stepper.h"
3a4fa0c1 24#include "modules/robot/Player.h"
a39e1557 25#include <malloc.h>
ded56b35 26
4464301d
AW
27
28
4cff3ded 29// List of callback functions, ordered as their corresponding events
df27a6a3
MM
30const ModuleCallback kernel_callback_functions[NUMBER_OF_DEFINED_EVENTS] = {
31 &Module::on_main_loop,
4cff3ded 32 &Module::on_console_line_received,
df27a6a3 33 &Module::on_gcode_received,
4cff3ded
AW
34 &Module::on_stepper_wake_up,
35 &Module::on_gcode_execute,
36 &Module::on_speed_change,
37 &Module::on_block_begin,
da24d6ae 38 &Module::on_block_end,
befcf5cc
AW
39 &Module::on_config_reload,
40 &Module::on_play,
70c25627
L
41 &Module::on_pause,
42 &Module::on_idle
4cff3ded
AW
43};
44
8c309ca9 45#define baud_rate_setting_checksum 10922
3c132bd0 46#define uart0_checksum 16877
4cff3ded 47
7b49793d 48// The kernel is the central point in Smoothie : it stores modules, and handles event calls
4cff3ded 49Kernel::Kernel(){
e6b5ae25 50 // Value init for the arrays
df27a6a3 51 for( uint8_t i=0; i<NUMBER_OF_DEFINED_EVENTS; i++ ){
db453125 52 for( uint8_t index=0; index<32; index++ ){
df27a6a3
MM
53 this->hooks[i][index] = NULL;
54 }
db453125 55 }
e6b5ae25 56
df27a6a3 57 // Config first, because we need the baud_rate setting before we start serial
4cff3ded 58 this->config = new Config();
a39e1557 59
4cff3ded 60 // Serial second, because the other modules might want to say something
38d375e7 61 this->streams = new StreamOutputPool();
4cff3ded 62
b2b0b56d
AW
63 // Configure UART depending on MRI config
64 NVIC_SetPriorityGrouping(0);
4c4a372a 65 /*
b2b0b56d
AW
66 if (strstr(MRI_UART, "MRI_UART_MBED_USB")){
67 if (strstr(MRI_UART, "MRI_UART_SHARED")){
68 this->serial = new SerialConsole(USBTX, USBRX, this->config->value(uart0_checksum,baud_rate_setting_checksum)->by_default(9600)->as_number());
69 }else{
70 this->serial = new SerialConsole(p13, p14, this->config->value(uart0_checksum,baud_rate_setting_checksum)->by_default(9600)->as_number());
71 }
72 }else{
73 this->serial = new SerialConsole(USBTX, USBRX, this->config->value(uart0_checksum,baud_rate_setting_checksum)->by_default(9600)->as_number());
74 }
4c4a372a 75 */
504030f9
MM
76 if( NVIC_GetPriority(UART0_IRQn) > 0 ){
77 this->serial = new SerialConsole(USBTX, USBRX, this->config->value(uart0_checksum,baud_rate_setting_checksum)->by_default(9600)->as_number());
78 }else{
79 this->serial = new SerialConsole(p13, p14, this->config->value(uart0_checksum,baud_rate_setting_checksum)->by_default(9600)->as_number());
80 }
4cff3ded 81 this->add_module( this->config );
f5f88509 82
4cff3ded 83 this->add_module( this->serial );
38d375e7 84
df27a6a3 85 // HAL stuff
3c132bd0 86 this->slow_ticker = new SlowTicker();
3c132bd0
AW
87 this->step_ticker = new StepTicker();
88 this->adc = new Adc();
0e8b102e 89 this->digipot = new Digipot();
650ed0a8 90
df27a6a3 91 // LPC17xx-specific
813727fb 92 NVIC_SetPriorityGrouping(0);
df27a6a3
MM
93 NVIC_SetPriority(TIMER0_IRQn, 2);
94 NVIC_SetPriority(TIMER1_IRQn, 1);
95 NVIC_SetPriority(TIMER2_IRQn, 3);
feb204be 96
b2b0b56d 97 // Set other priorities lower than the timers
df27a6a3
MM
98 NVIC_SetPriority(ADC_IRQn, 4);
99 NVIC_SetPriority(USB_IRQn, 4);
f5f88509 100
df27a6a3 101 // If MRI is enabled
b2b0b56d 102 if( MRI_ENABLE ){
df27a6a3
MM
103 if( NVIC_GetPriority(UART0_IRQn) > 0 ){ NVIC_SetPriority(UART0_IRQn, 4); }
104 if( NVIC_GetPriority(UART1_IRQn) > 0 ){ NVIC_SetPriority(UART1_IRQn, 4); }
105 if( NVIC_GetPriority(UART2_IRQn) > 0 ){ NVIC_SetPriority(UART2_IRQn, 4); }
106 if( NVIC_GetPriority(UART3_IRQn) > 0 ){ NVIC_SetPriority(UART3_IRQn, 4); }
b2b0b56d 107 }else{
df27a6a3
MM
108 NVIC_SetPriority(UART0_IRQn, 4);
109 NVIC_SetPriority(UART1_IRQn, 4);
110 NVIC_SetPriority(UART2_IRQn, 4);
111 NVIC_SetPriority(UART3_IRQn, 4);
b2b0b56d
AW
112 }
113
feb204be
AW
114 // Configure the step ticker
115 int base_stepping_frequency = this->config->value(base_stepping_frequency_checksum )->by_default(100000)->as_number();
116 double microseconds_per_step_pulse = this->config->value(microseconds_per_step_pulse_checksum )->by_default(5 )->as_number();
f5f88509 117
b7eae4fa 118 this->step_ticker->set_reset_delay( microseconds_per_step_pulse / 1000000L );
f5f88509 119
b7eae4fa 120 this->step_ticker->set_frequency( base_stepping_frequency );
3c132bd0 121
df27a6a3 122 // Core modules
81b547a1 123 this->add_module( this->gcode_dispatch = new GcodeDispatch() );
5357f9c5 124 this->add_module( this->robot = new Robot() );
81b547a1
AW
125 this->add_module( this->stepper = new Stepper() );
126 this->add_module( this->planner = new Planner() );
127 this->add_module( this->player = new Player() );
128 this->add_module( this->pauser = new Pauser() );
4cff3ded
AW
129}
130
131void Kernel::add_module(Module* module){
132 module->kernel = this;
133 module->on_module_loaded();
b66fb830 134 module->register_for_event(ON_CONFIG_RELOAD);
4cff3ded
AW
135}
136
137void Kernel::register_for_event(unsigned int id_event, Module* module){
df27a6a3 138 uint8_t current_id = 0;
e6b5ae25
AW
139 Module* current = this->hooks[id_event][0];
140 while(current != NULL ){
141 if( current == module ){ return; }
142 current_id++;
143 current = this->hooks[id_event][current_id];
144 }
145 this->hooks[id_event][current_id] = module;
146 this->hooks[id_event][current_id+1] = NULL;
4cff3ded
AW
147}
148
149void Kernel::call_event(unsigned int id_event){
e6b5ae25
AW
150 uint8_t current_id = 0; Module* current = this->hooks[id_event][0];
151 while(current != NULL ){ // For each active stepper
152 (current->*kernel_callback_functions[id_event])(this);
153 current_id++;
154 current = this->hooks[id_event][current_id];
4cff3ded
AW
155 }
156}
157
158void Kernel::call_event(unsigned int id_event, void * argument){
e6b5ae25
AW
159 uint8_t current_id = 0; Module* current = this->hooks[id_event][0];
160 while(current != NULL ){ // For each active stepper
161 (current->*kernel_callback_functions[id_event])(argument);
162 current_id++;
163 current = this->hooks[id_event][current_id];
4cff3ded
AW
164 }
165}