From 70a3f309e2cd0a50c211e213e5640c059ac15adf Mon Sep 17 00:00:00 2001 From: Rob Giseburt Date: Mon, 19 Feb 2018 10:18:13 -0600 Subject: [PATCH] Major GOIO refactor --- g2core/board/gquadratic/board_gpio.cpp | 50 +- g2core/board/gquintic/board_gpio.cpp | 101 ++-- g2core/board/gquintic/board_gpio.h | 103 +++- g2core/config.cpp | 30 +- g2core/config.h | 4 +- g2core/config_app.cpp | 131 ++++- g2core/coolant.cpp | 53 +- g2core/device/max31865/max31865.h | 104 ++++ g2core/gpio.cpp | 172 ++++-- g2core/gpio.h | 778 +++++++++++++++++++++---- g2core/pwm.cpp | 50 +- g2core/settings/settings_default.h | 271 +++++++-- g2core/spindle.cpp | 54 +- g2core/temperature.cpp | 2 +- 14 files changed, 1557 insertions(+), 346 deletions(-) diff --git a/g2core/board/gquadratic/board_gpio.cpp b/g2core/board/gquadratic/board_gpio.cpp index 4daf011d..5033c3f1 100644 --- a/g2core/board/gquadratic/board_gpio.cpp +++ b/g2core/board/gquadratic/board_gpio.cpp @@ -56,32 +56,32 @@ /**** Setup Actual Objects ****/ -gpioDigitalInputPin> din1 {DI1_MODE, 1}; -gpioDigitalInputPin> din2 {DI2_MODE, 2}; -gpioDigitalInputPin> din3 {DI3_MODE, 3}; -gpioDigitalInputPin> din4 {DI4_MODE, 4}; -gpioDigitalInputPin> din5 {DI5_MODE, 5}; -gpioDigitalInputPin> din6 {DI6_MODE, 6}; -gpioDigitalInputPin> din7 {DI7_MODE, 7}; -gpioDigitalInputPin> din8 {DI8_MODE, 8}; -gpioDigitalInputPin> din9 {DI9_MODE, 9}; -// gpioDigitalInputPin> din10 {DI10_MODE, 10}; -// gpioDigitalInputPin> din11 {DI11_MODE, 11}; -// gpioDigitalInputPin> din12 {DI12_MODE, 12}; +gpioDigitalInputPin> din1 {DI1_ENABLED, DI1_POLARITY, 1}; +gpioDigitalInputPin> din2 {DI2_ENABLED, DI2_POLARITY, 2}; +gpioDigitalInputPin> din3 {DI3_ENABLED, DI3_POLARITY, 3}; +gpioDigitalInputPin> din4 {DI4_ENABLED, DI4_POLARITY, 4}; +gpioDigitalInputPin> din5 {DI5_ENABLED, DI5_POLARITY, 5}; +gpioDigitalInputPin> din6 {DI6_ENABLED, DI6_POLARITY, 6}; +gpioDigitalInputPin> din7 {DI7_ENABLED, DI7_POLARITY, 7}; +gpioDigitalInputPin> din8 {DI8_ENABLED, DI8_POLARITY, 8}; +gpioDigitalInputPin> din9 {DI9_ENABLED, DI9_POLARITY, 9}; +// gpioDigitalInputPin> din10 {DI10ENABLEDE, DI10_POLARITY, 10}; +// gpioDigitalInputPin> din11 {DI11ENABLEDE, DI11_POLARITY, 11}; +// gpioDigitalInputPin> din12 {DI12ENABLEDE, DI12_POLARITY, 12}; -gpioDigitalOutputPin> dout1 { DO1_MODE, (uint32_t)200000 }; -gpioDigitalOutputPin> dout2 { DO2_MODE, (uint32_t)200000 }; -gpioDigitalOutputPin> dout3 { DO3_MODE, (uint32_t)200000 }; -gpioDigitalOutputPin> dout4 { DO4_MODE, (uint32_t)200000 }; -gpioDigitalOutputPin> dout5 { DO5_MODE, (uint32_t)200000 }; -gpioDigitalOutputPin> dout6 { DO6_MODE, (uint32_t)200000 }; -gpioDigitalOutputPin> dout7 { DO7_MODE, (uint32_t)200000 }; -gpioDigitalOutputPin> dout8 { DO8_MODE, (uint32_t)200000 }; -gpioDigitalOutputPin> dout9 { DO9_MODE, (uint32_t)200000 }; -gpioDigitalOutputPin> dout10 { DO10_MODE, (uint32_t)200000 }; -gpioDigitalOutputPin> dout11 { DO11_MODE, (uint32_t)200000 }; -gpioDigitalOutputPin> dout12 { DO12_MODE, (uint32_t)200000 }; -gpioDigitalOutputPin> dout13 { DO13_MODE, (uint32_t)200000 }; +gpioDigitalOutputPin> dout1 { DO1_ENABLED, DO1_POLARITY, (uint32_t)200000 }; +gpioDigitalOutputPin> dout2 { DO2_ENABLED, DO2_POLARITY, (uint32_t)200000 }; +gpioDigitalOutputPin> dout3 { DO3_ENABLED, DO3_POLARITY, (uint32_t)200000 }; +gpioDigitalOutputPin> dout4 { DO4_ENABLED, DO4_POLARITY, (uint32_t)200000 }; +gpioDigitalOutputPin> dout5 { DO5_ENABLED, DO5_POLARITY, (uint32_t)200000 }; +gpioDigitalOutputPin> dout6 { DO6_ENABLED, DO6_POLARITY, (uint32_t)200000 }; +gpioDigitalOutputPin> dout7 { DO7_ENABLED, DO7_POLARITY, (uint32_t)200000 }; +gpioDigitalOutputPin> dout8 { DO8_ENABLED, DO8_POLARITY, (uint32_t)200000 }; +gpioDigitalOutputPin> dout9 { DO9_ENABLED, DO9_POLARITY, (uint32_t)200000 }; +gpioDigitalOutputPin> dout10 { DO10_ENABLED, DO10_POLARITY, (uint32_t)200000 }; +gpioDigitalOutputPin> dout11 { DO11_ENABLED, DO11_POLARITY, (uint32_t)200000 }; +gpioDigitalOutputPin> dout12 { DO12_ENABLED, DO12_POLARITY, (uint32_t)200000 }; +gpioDigitalOutputPin> dout13 { DO13_ENABLED, DO13_POLARITY, (uint32_t)200000 }; /**** Setup Arrays - these are extern and MUST match the board_gpio.h ****/ diff --git a/g2core/board/gquintic/board_gpio.cpp b/g2core/board/gquintic/board_gpio.cpp index 4daf011d..1ee6d9a9 100644 --- a/g2core/board/gquintic/board_gpio.cpp +++ b/g2core/board/gquintic/board_gpio.cpp @@ -56,53 +56,88 @@ /**** Setup Actual Objects ****/ -gpioDigitalInputPin> din1 {DI1_MODE, 1}; -gpioDigitalInputPin> din2 {DI2_MODE, 2}; -gpioDigitalInputPin> din3 {DI3_MODE, 3}; -gpioDigitalInputPin> din4 {DI4_MODE, 4}; -gpioDigitalInputPin> din5 {DI5_MODE, 5}; -gpioDigitalInputPin> din6 {DI6_MODE, 6}; -gpioDigitalInputPin> din7 {DI7_MODE, 7}; -gpioDigitalInputPin> din8 {DI8_MODE, 8}; -gpioDigitalInputPin> din9 {DI9_MODE, 9}; -// gpioDigitalInputPin> din10 {DI10_MODE, 10}; -// gpioDigitalInputPin> din11 {DI11_MODE, 11}; -// gpioDigitalInputPin> din12 {DI12_MODE, 12}; - -gpioDigitalOutputPin> dout1 { DO1_MODE, (uint32_t)200000 }; -gpioDigitalOutputPin> dout2 { DO2_MODE, (uint32_t)200000 }; -gpioDigitalOutputPin> dout3 { DO3_MODE, (uint32_t)200000 }; -gpioDigitalOutputPin> dout4 { DO4_MODE, (uint32_t)200000 }; -gpioDigitalOutputPin> dout5 { DO5_MODE, (uint32_t)200000 }; -gpioDigitalOutputPin> dout6 { DO6_MODE, (uint32_t)200000 }; -gpioDigitalOutputPin> dout7 { DO7_MODE, (uint32_t)200000 }; -gpioDigitalOutputPin> dout8 { DO8_MODE, (uint32_t)200000 }; -gpioDigitalOutputPin> dout9 { DO9_MODE, (uint32_t)200000 }; -gpioDigitalOutputPin> dout10 { DO10_MODE, (uint32_t)200000 }; -gpioDigitalOutputPin> dout11 { DO11_MODE, (uint32_t)200000 }; -gpioDigitalOutputPin> dout12 { DO12_MODE, (uint32_t)200000 }; -gpioDigitalOutputPin> dout13 { DO13_MODE, (uint32_t)200000 }; - -/**** Setup Arrays - these are extern and MUST match the board_gpio.h ****/ +gpioDigitalInputPin> din1 {DI1_ENABLED, DI1_POLARITY, 1}; +gpioDigitalInputPin> din2 {DI2_ENABLED, DI2_POLARITY, 2}; +gpioDigitalInputPin> din3 {DI3_ENABLED, DI3_POLARITY, 3}; +gpioDigitalInputPin> din4 {DI4_ENABLED, DI4_POLARITY, 4}; +gpioDigitalInputPin> din5 {DI5_ENABLED, DI5_POLARITY, 5}; +gpioDigitalInputPin> din6 {DI6_ENABLED, DI6_POLARITY, 6}; +gpioDigitalInputPin> din7 {DI7_ENABLED, DI7_POLARITY, 7}; +gpioDigitalInputPin> din8 {DI8_ENABLED, DI8_POLARITY, 8}; +gpioDigitalInputPin> din9 {DI9_ENABLED, DI9_POLARITY, 9}; +// gpioDigitalInputPin> din10 {DI10ENABLEDE, DI10_POLARITY, 10}; +// gpioDigitalInputPin> din11 {DI11ENABLEDE, DI11_POLARITY, 11}; +// gpioDigitalInputPin> din12 {DI12ENABLEDE, DI12_POLARITY, 12}; gpioDigitalInput* const d_in[] = {&din1, &din2, &din3, &din4, &din5, &din6, &din7, &din8, &din9}; + + +gpioDigitalOutputPin> dout1 { DO1_ENABLED, DO1_POLARITY, (uint32_t)200000 }; +gpioDigitalOutputPin> dout2 { DO2_ENABLED, DO2_POLARITY, (uint32_t)200000 }; +gpioDigitalOutputPin> dout3 { DO3_ENABLED, DO3_POLARITY, (uint32_t)200000 }; +gpioDigitalOutputPin> dout4 { DO4_ENABLED, DO4_POLARITY, (uint32_t)200000 }; +gpioDigitalOutputPin> dout5 { DO5_ENABLED, DO5_POLARITY, (uint32_t)200000 }; +gpioDigitalOutputPin> dout6 { DO6_ENABLED, DO6_POLARITY, (uint32_t)200000 }; +gpioDigitalOutputPin> dout7 { DO7_ENABLED, DO7_POLARITY, (uint32_t)200000 }; +gpioDigitalOutputPin> dout8 { DO8_ENABLED, DO8_POLARITY, (uint32_t)200000 }; +gpioDigitalOutputPin> dout9 { DO9_ENABLED, DO9_POLARITY, (uint32_t)200000 }; +gpioDigitalOutputPin> dout10 { DO10_ENABLED, DO10_POLARITY, (uint32_t)200000 }; +gpioDigitalOutputPin> dout11 { DO11_ENABLED, DO11_POLARITY, (uint32_t)200000 }; +gpioDigitalOutputPin> dout12 { DO12_ENABLED, DO12_POLARITY, (uint32_t)200000 }; +gpioDigitalOutputPin> dout13 { DO13_ENABLED, DO13_POLARITY, (uint32_t)200000 }; + gpioDigitalOutput* const d_out[] = {&dout1, &dout2, &dout3, &dout4, &dout5, &dout6, &dout7, &dout8, &dout9, &dout10, &dout11, &dout12, &dout13}; -// not yet used -// gpioAnalogInput* a_in[A_IN_CHANNELS]; -// gpioAnalogOutput* a_out[A_OUT_CHANNELS]; + + +#if QUINTIC_REVISION == 'C' + +gpioAnalogInputPin> ain1 {gpioAnalogInput::AIN_TYPE_EXTERNAL, 1, spiBus, spiCSPinMux.getCS(5)}; +gpioAnalogInputPin> ain2 {gpioAnalogInput::AIN_TYPE_EXTERNAL, 2, spiBus, spiCSPinMux.getCS(6)}; +gpioAnalogInputPin> ain3 {gpioAnalogInput::AIN_TYPE_INTERNAL, 3}; +gpioAnalogInputPin> ain4 {gpioAnalogInput::AIN_TYPE_INTERNAL, 4}; + +gpioAnalogInput* const a_in[] = {&ain1, &ain2, &ain3, &ain4}; + +#endif // 'C' + +#if QUINTIC_REVISION == 'D' + +gpioAnalogInputPin> ain1 {gpioAnalogInput::AIN_TYPE_INTERNAL, 1}; +gpioAnalogInputPin> ain2 {gpioAnalogInput::AIN_TYPE_INTERNAL, 2}; +gpioAnalogInputPin> ain3 {gpioAnalogInput::AIN_TYPE_INTERNAL, 3}; +gpioAnalogInputPin> ain4 {gpioAnalogInput::AIN_TYPE_INTERNAL, 4}; + +gpioAnalogInput* const a_in[] = {&ain1, &ain2, &ain3, &ain4}; + +#endif // 'D' + /************************************************************************************ **** CODE ************************************************************************** ************************************************************************************/ + + + // Register a SysTick event to call start_sampling every temperature_sample_freq ms + const int16_t ain_sample_freq = 10; + int16_t ain_sample_counter = ain_sample_freq; + Motate::SysTickEvent ain_tick_event {[&] { + if (!--ain_sample_counter) { + ain1.startSampling(); + ain2.startSampling(); + ain3.startSampling(); + ain4.startSampling(); + ain_sample_counter = ain_sample_freq; + } + }, nullptr}; + /* * gpio_reset() - reset inputs and outputs (no initialization) */ - void outputs_reset(void) { // nothing to do } void inputs_reset(void) { - // nothing to do + SysTickTimer.registerEvent(&ain_tick_event); } diff --git a/g2core/board/gquintic/board_gpio.h b/g2core/board/gquintic/board_gpio.h index 25a1cddc..ea418246 100644 --- a/g2core/board/gquintic/board_gpio.h +++ b/g2core/board/gquintic/board_gpio.h @@ -30,35 +30,30 @@ // this file is included from the bottom of gpio.h, but we do this for completeness #include "../../gpio.h" +#include "hardware.h" /* * GPIO defines */ //--- change as required for board and switch hardware ---// -#define D_IN_CHANNELS 9 // v9 // number of digital inputs supported -#define D_OUT_CHANNELS 13 // number of digital outputs supported -#define A_IN_CHANNELS 0 // number of analog inputs supported -#define A_OUT_CHANNELS 0 // number of analog outputs supported - #define INPUT_LOCKOUT_MS 10 // milliseconds to go dead after input firing /* * The GPIO objects themselves - this must match up with board_gpio.cpp! */ -extern gpioDigitalInput* const d_in[D_IN_CHANNELS]; -extern gpioDigitalOutput* const d_out[D_OUT_CHANNELS]; -// extern gpioAnalogInput* a_in[A_IN_CHANNELS]; -// extern gpioAnalogOutput* a_out[A_OUT_CHANNELS]; - // prepare the objects as externs (for config_app to not bloat) using Motate::IRQPin; using Motate::PWMOutputPin; using Motate::PWMLikeOutputPin; +using Motate::ADCPin; +using Motate::ADCDifferentialPair; template using OutputType = typename std::conditional, PWMLikeOutputPin>::type; +#define D_IN_CHANNELS 9 // number of digital inputs supported + extern gpioDigitalInputPin> din1; extern gpioDigitalInputPin> din2; extern gpioDigitalInputPin> din3; @@ -72,6 +67,11 @@ extern gpioDigitalInputPin> din9; // extern gpioDigitalInputPin> din11; // extern gpioDigitalInputPin> din12; +extern gpioDigitalInput* const d_in[D_IN_CHANNELS]; + + +#define D_OUT_CHANNELS 13 // number of digital outputs supported + extern gpioDigitalOutputPin> dout1; extern gpioDigitalOutputPin> dout2; extern gpioDigitalOutputPin> dout3; @@ -86,5 +86,88 @@ extern gpioDigitalOutputPin> dout12; extern gpioDigitalOutputPin> dout13; +extern gpioDigitalOutput* const d_out[D_OUT_CHANNELS]; + + +#if QUINTIC_REVISION == 'C' + +#define A_IN_CHANNELS 4 // number of analog inputs supported + +#include "device/max31865/max31865.h" +#define USING_A_MAX31865 1 + +#ifndef AI1_TYPE +#define AI1_TYPE gpioAnalogInput::AIN_TYPE_EXTERNAL +#endif +#ifndef AI1_CIRCUIT +#define AI1_CIRCUIT gpioAnalogInput::AIN_CIRCUIT_EXTERNAL +#endif +extern gpioAnalogInputPin> ain1; + +#ifndef AI2_TYPE +#define AI2_TYPE gpioAnalogInput::AIN_TYPE_EXTERNAL +#endif +#ifndef AI2_CIRCUIT +#define AI2_CIRCUIT gpioAnalogInput::AIN_CIRCUIT_EXTERNAL +#endif +extern gpioAnalogInputPin> ain2; + +#ifndef AI3_TYPE +#define AI3_TYPE gpioAnalogInput::AIN_TYPE_INTERNAL +#endif +#ifndef AI3_CIRCUIT +#define AI3_CIRCUIT gpioAnalogInput::AIN_CIRCUIT_PULLUP +#endif +extern gpioAnalogInputPin> ain3; + +#ifndef AI4_TYPE +#define AI4_TYPE gpioAnalogInput::AIN_TYPE_INTERNAL +#endif +#ifndef AI4_CIRCUIT +#define AI4_CIRCUIT gpioAnalogInput::AIN_CIRCUIT_PULLUP +#endif +extern gpioAnalogInputPin> ain4; + +#endif // 'C' + +#if QUINTIC_REVISION == 'D' + +#define A_IN_CHANNELS 4 // number of analog inputs supported + +#ifndef AI1_TYPE +#define AI1_TYPE gpioAnalogInput::AIN_TYPE_INTERNAL +#endif +#ifndef AI1_CIRCUIT +#define AI1_CIRCUIT gpioAnalogInput::AIN_CIRCUIT_CC_INV_OPAMP +#endif +extern gpioAnalogInputPin> ain1; + +#ifndef AI2_TYPE +#define AI2_TYPE gpioAnalogInput::AIN_TYPE_INTERNAL +#endif +#ifndef AI2_CIRCUIT +#define AI2_CIRCUIT gpioAnalogInput::AIN_CIRCUIT_CC_INV_OPAMP +#endif +extern gpioAnalogInputPin> ain2; + +#ifndef AI3_TYPE +#define AI3_TYPE gpioAnalogInput::AIN_TYPE_INTERNAL +#endif +#ifndef AI3_CIRCUIT +#define AI3_CIRCUIT gpioAnalogInput::AIN_CIRCUIT_INV_OPAMP +#endif +extern gpioAnalogInputPin> ain3; + +#ifndef AI4_TYPE +#define AI4_TYPE gpioAnalogInput::AIN_TYPE_INTERNAL +#endif +#ifndef AI4_CIRCUIT +#define AI4_CIRCUIT gpioAnalogInput::AIN_CIRCUIT_INV_OPAMP +#endif +extern gpioAnalogInputPin> ain4; + +#endif // 'D' + +extern gpioAnalogInput* const a_in[A_IN_CHANNELS]; #endif // End of include guard: BOARD_GPIO_H_ONCE diff --git a/g2core/config.cpp b/g2core/config.cpp index 596d34fb..26335686 100644 --- a/g2core/config.cpp +++ b/g2core/config.cpp @@ -256,7 +256,7 @@ stat_t set_noop(nvObj_t *nv) { return (STAT_OK); // hack until JSON is refactored } -stat_t set_nul(nvObj_t *nv) { +stat_t set_nul(nvObj_t *nv) { // nv->valuetype = TYPE_NULL; // return (STAT_PARAMETER_IS_READ_ONLY); // this is what it should be return (STAT_OK); // hack until JSON is refactored @@ -264,11 +264,11 @@ stat_t set_nul(nvObj_t *nv) { stat_t set_ro(nvObj_t *nv) { // hack. If setting an SR it doesn't fail - if (strcmp(nv_body->token, "sr") == 0) { - return (STAT_OK); + if (strcmp(nv_body->token, "sr") == 0) { + return (STAT_OK); } nv->valuetype = TYPE_NULL; - return (STAT_PARAMETER_IS_READ_ONLY); + return (STAT_PARAMETER_IS_READ_ONLY); } stat_t set_ui8(nvObj_t *nv) @@ -465,6 +465,14 @@ index_t nv_get_index(const char *group, const char *token) if (c != str[3]) continue; // 4th character mismatch if ((c = GET_TOKEN_BYTE(token[4])) == NUL) { if (str[4] == NUL) return(i);} // four character match if (c != str[4]) continue; // 5th character mismatch + if ((c = GET_TOKEN_BYTE(token[5])) == NUL) { if (str[5] == NUL) return(i);} // four character match + if (c != str[5]) continue; // 6th character mismatch + if ((c = GET_TOKEN_BYTE(token[6])) == NUL) { if (str[6] == NUL) return(i);} // four character match + if (c != str[6]) continue; // 7th character mismatch + if ((c = GET_TOKEN_BYTE(token[7])) == NUL) { if (str[7] == NUL) return(i);} // four character match + if (c != str[7]) continue; // 8th character mismatch + if ((c = GET_TOKEN_BYTE(token[8])) == NUL) { if (str[8] == NUL) return(i);} // four character match + if (c != str[8]) continue; // 9th character mismatch return (i); // five character match } return (NO_MATCH); @@ -617,7 +625,7 @@ nvObj_t *nv_add_object(const char *token) // add an object to the body usi if (nv->valuetype != TYPE_EMPTY) { if ((nv = nv->nx) == NULL) { // not supposed to find a NULL; here for safety return(NULL); - } + } continue; } // load the index from the token or die trying @@ -634,7 +642,7 @@ nvObj_t *nv_add_integer(const char *token, const uint32_t value)// add an intege for (uint8_t i=0; ivaluetype != TYPE_EMPTY) { if ((nv = nv->nx) == NULL) { // not supposed to find a NULL; here for safety - return(NULL); + return(NULL); } continue; } @@ -652,8 +660,8 @@ nvObj_t *nv_add_data(const char *token, const uint32_t value)// add an integer o for (uint8_t i=0; ivaluetype != TYPE_EMPTY) { if ((nv = nv->nx) == NULL) { // not supposed to find a NULL; here for safety - return(NULL); - } + return(NULL); + } continue; } strcpy(nv->token, token); @@ -672,7 +680,7 @@ nvObj_t *nv_add_float(const char *token, const float value) // add a float ob if (nv->valuetype != TYPE_EMPTY) { if ((nv = nv->nx) == NULL) { // not supposed to find a NULL; here for safety return(NULL); - } + } continue; } strncpy(nv->token, token, TOKEN_LEN); @@ -689,8 +697,8 @@ nvObj_t *nv_add_string(const char *token, const char *string) // add a string ob for (uint8_t i=0; ivaluetype != TYPE_EMPTY) { if ((nv = nv->nx) == NULL) { // not supposed to find a NULL; here for safety - return(NULL); - } + return(NULL); + } continue; } strncpy(nv->token, token, TOKEN_LEN); diff --git a/g2core/config.h b/g2core/config.h index a8b1ebdd..9fc56645 100644 --- a/g2core/config.h +++ b/g2core/config.h @@ -185,8 +185,8 @@ typedef uint32_t index_t; // use this because set/get_int is expec // Stuff you probably don't want to change -#define GROUP_LEN 4 // max length of group prefix -#define TOKEN_LEN 6 // mnemonic token string: group prefix + short token +#define GROUP_LEN 6 // max length of group prefix +#define TOKEN_LEN 9 // mnemonic token string: group prefix + short token #define NV_FOOTER_LEN 18 // sufficient space to contain a JSON footer array #define NV_LIST_LEN (NV_BODY_LEN+2) // +2 allows for a header and a footer #define NV_EXEC_FIRST (NV_BODY_LEN+2) // index of the first EXEC nv diff --git a/g2core/config_app.cpp b/g2core/config_app.cpp index ff417996..412217e1 100644 --- a/g2core/config_app.cpp +++ b/g2core/config_app.cpp @@ -483,54 +483,66 @@ const cfgItem_t cfgArray[] = { { "c","czb",_fip, 3, cm_print_zb, get_flt, set_flt, (float *)&cm.a[AXIS_C].zero_backoff, C_ZERO_BACKOFF }, // Digital input configs - { "di1","di1mo",_fip, 0, din_print_mo, din_get_mo, din_set_mo, (float *)&din1, DI1_MODE }, + { "di1","di1en",_fip, 0, din_print_en, din_get_en, din_set_en, (float *)&din1, DI1_ENABLED }, + { "di1","di1po",_fip, 0, din_print_po, din_get_po, din_set_po, (float *)&din1, DI1_POLARITY }, { "di1","di1ac",_fip, 0, din_print_ac, din_get_ac, din_set_ac, (float *)&din1, DI1_ACTION }, { "di1","di1fn",_fip, 0, din_print_fn, din_get_fn, din_set_fn, (float *)&din1, DI1_FUNCTION }, - { "di2","di2mo",_fip, 0, din_print_mo, din_get_mo, din_set_mo, (float *)&din2, DI2_MODE }, + { "di2","di2en",_fip, 0, din_print_en, din_get_en, din_set_en, (float *)&din2, DI2_ENABLED }, + { "di2","di2po",_fip, 0, din_print_po, din_get_po, din_set_po, (float *)&din2, DI2_POLARITY }, { "di2","di2ac",_fip, 0, din_print_ac, din_get_ac, din_set_ac, (float *)&din2, DI2_ACTION }, { "di2","di2fn",_fip, 0, din_print_fn, din_get_fn, din_set_fn, (float *)&din2, DI2_FUNCTION }, - { "di3","di3mo",_fip, 0, din_print_mo, din_get_mo, din_set_mo, (float *)&din3, DI3_MODE }, + { "di3","di3en",_fip, 0, din_print_en, din_get_en, din_set_en, (float *)&din3, DI3_ENABLED }, + { "di3","di3po",_fip, 0, din_print_po, din_get_po, din_set_po, (float *)&din3, DI3_POLARITY }, { "di3","di3ac",_fip, 0, din_print_ac, din_get_ac, din_set_ac, (float *)&din3, DI3_ACTION }, { "di3","di3fn",_fip, 0, din_print_fn, din_get_fn, din_set_fn, (float *)&din3, DI3_FUNCTION }, - { "di4","di4mo",_fip, 0, din_print_mo, din_get_mo, din_set_mo, (float *)&din4, DI4_MODE }, + { "di4","di4en",_fip, 0, din_print_en, din_get_en, din_set_en, (float *)&din4, DI4_ENABLED }, + { "di4","di4po",_fip, 0, din_print_po, din_get_po, din_set_po, (float *)&din4, DI4_POLARITY }, { "di4","di4ac",_fip, 0, din_print_ac, din_get_ac, din_set_ac, (float *)&din4, DI4_ACTION }, { "di4","di4fn",_fip, 0, din_print_fn, din_get_fn, din_set_fn, (float *)&din4, DI4_FUNCTION }, - { "di5","di5mo",_fip, 0, din_print_mo, din_get_mo, din_set_mo, (float *)&din5, DI5_MODE }, + { "di5","di5en",_fip, 0, din_print_en, din_get_en, din_set_en, (float *)&din5, DI5_ENABLED }, + { "di5","di5po",_fip, 0, din_print_po, din_get_po, din_set_po, (float *)&din5, DI5_POLARITY }, { "di5","di5ac",_fip, 0, din_print_ac, din_get_ac, din_set_ac, (float *)&din5, DI5_ACTION }, { "di5","di5fn",_fip, 0, din_print_fn, din_get_fn, din_set_fn, (float *)&din5, DI5_FUNCTION }, - { "di6","di6mo",_fip, 0, din_print_mo, din_get_mo, din_set_mo, (float *)&din6, DI6_MODE }, + { "di6","di6en",_fip, 0, din_print_en, din_get_en, din_set_en, (float *)&din6, DI6_ENABLED }, + { "di6","di6po",_fip, 0, din_print_po, din_get_po, din_set_po, (float *)&din6, DI6_POLARITY }, { "di6","di6ac",_fip, 0, din_print_ac, din_get_ac, din_set_ac, (float *)&din6, DI6_ACTION }, { "di6","di6fn",_fip, 0, din_print_fn, din_get_fn, din_set_fn, (float *)&din6, DI6_FUNCTION }, - { "di7","di7mo",_fip, 0, din_print_mo, din_get_mo, din_set_mo, (float *)&din7, DI7_MODE }, + { "di7","di7en",_fip, 0, din_print_en, din_get_en, din_set_en, (float *)&din7, DI7_ENABLED }, + { "di7","di7po",_fip, 0, din_print_po, din_get_po, din_set_po, (float *)&din7, DI7_POLARITY }, { "di7","di7ac",_fip, 0, din_print_ac, din_get_ac, din_set_ac, (float *)&din7, DI7_ACTION }, { "di7","di7fn",_fip, 0, din_print_fn, din_get_fn, din_set_fn, (float *)&din7, DI7_FUNCTION }, - { "di8","di8mo",_fip, 0, din_print_mo, din_get_mo, din_set_mo, (float *)&din8, DI8_MODE }, + { "di8","di8en",_fip, 0, din_print_en, din_get_en, din_set_en, (float *)&din8, DI8_ENABLED }, + { "di3","di8po",_fip, 0, din_print_po, din_get_po, din_set_po, (float *)&din8, DI8_POLARITY }, { "di8","di8ac",_fip, 0, din_print_ac, din_get_ac, din_set_ac, (float *)&din8, DI8_ACTION }, { "di8","di8fn",_fip, 0, din_print_fn, din_get_fn, din_set_fn, (float *)&din8, DI8_FUNCTION }, #if (D_IN_CHANNELS >= 9) - { "di9","di9mo",_fip, 0, din_print_mo, din_get_mo, din_set_mo, (float *)&din9, DI9_MODE }, + { "di9","di9en",_fip, 0, din_print_en, din_get_en, din_set_en, (float *)&din9, DI9_ENABLED }, + { "di9","di9po",_fip, 0, din_print_po, din_get_po, din_set_po, (float *)&din9, DI9_POLARITY }, { "di9","di9ac",_fip, 0, din_print_ac, din_get_ac, din_set_ac, (float *)&din9, DI9_ACTION }, { "di9","di9fn",_fip, 0, din_print_fn, din_get_fn, din_set_fn, (float *)&din9, DI9_FUNCTION }, #endif #if (D_IN_CHANNELS >= 10) - { "di10","di10mo",_fip, 0, din_print_mo, din_get_mo, din_set_mo, (float *)&din10, DI10_MODE }, + { "di10","di10en",_fip, 0, din_print_en, din_get_en, din_set_en, (float *)&din10, DI10_ENABLED }, + { "di10","di10po",_fip, 0, din_print_po, din_get_po, din_set_po, (float *)&din10, DI10_POLARITY }, { "di10","di10ac",_fip, 0, din_print_ac, din_get_ac, din_set_ac, (float *)&din10, DI10_ACTION }, { "di10","di10fn",_fip, 0, din_print_fn, din_get_fn, din_set_fn, (float *)&din10, DI10_FUNCTION }, #endif #if (D_IN_CHANNELS >= 11) - { "di11","di11mo",_fip, 0, din_print_mo, din_get_mo, din_set_mo, (float *)&din11, DI11_MODE }, + { "di11","di11en",_fip, 0, din_print_en, din_get_en, din_set_en, (float *)&din11, DI11_ENABLED }, + { "di11","di11po",_fip, 0, din_print_po, din_get_po, din_set_po, (float *)&din11, DI11_POLARITY }, { "di11","di11ac",_fip, 0, din_print_ac, din_get_ac, din_set_ac, (float *)&din11, DI11_ACTION }, { "di11","di11fn",_fip, 0, din_print_fn, din_get_fn, din_set_fn, (float *)&din11, DI11_FUNCTION }, #endif #if (D_IN_CHANNELS >= 12) - { "di12","di12mo",_fip, 0, din_print_mo, din_get_mo, din_set_mo, (float *)&din12, DI12_MODE }, + { "di12","di12en",_fip, 0, din_print_en, din_get_en, din_set_en, (float *)&din12, DI12_ENABLED }, + { "di12","di12po",_fip, 0, din_print_po, din_get_po, din_set_po, (float *)&din12, DI12_POLARITY }, { "di12","di12ac",_fip, 0, din_print_ac, din_get_ac, din_set_ac, (float *)&din12, DI12_ACTION }, { "di12","di12fn",_fip, 0, din_print_fn, din_get_fn, din_set_fn, (float *)&din12, DI12_FUNCTION }, #endif @@ -558,19 +570,30 @@ const cfgItem_t cfgArray[] = { #endif // digital output configs - { "do1", "do1mo", _fip, 0, dout_print_mo, dout_get_mo, dout_set_mo, (float *)&dout1, DO1_MODE }, - { "do2", "do2mo", _fip, 0, dout_print_mo, dout_get_mo, dout_set_mo, (float *)&dout2, DO2_MODE }, - { "do3", "do3mo", _fip, 0, dout_print_mo, dout_get_mo, dout_set_mo, (float *)&dout3, DO3_MODE }, - { "do4", "do4mo", _fip, 0, dout_print_mo, dout_get_mo, dout_set_mo, (float *)&dout4, DO4_MODE }, - { "do5", "do5mo", _fip, 0, dout_print_mo, dout_get_mo, dout_set_mo, (float *)&dout5, DO5_MODE }, - { "do6", "do6mo", _fip, 0, dout_print_mo, dout_get_mo, dout_set_mo, (float *)&dout6, DO6_MODE }, - { "do7", "do7mo", _fip, 0, dout_print_mo, dout_get_mo, dout_set_mo, (float *)&dout7, DO7_MODE }, - { "do8", "do8mo", _fip, 0, dout_print_mo, dout_get_mo, dout_set_mo, (float *)&dout8, DO8_MODE }, - { "do9", "do9mo", _fip, 0, dout_print_mo, dout_get_mo, dout_set_mo, (float *)&dout9, DO9_MODE }, - { "do10","do10mo",_fip, 0, dout_print_mo, dout_get_mo, dout_set_mo, (float *)&dout10, DO10_MODE }, - { "do11","do11mo",_fip, 0, dout_print_mo, dout_get_mo, dout_set_mo, (float *)&dout11, DO11_MODE }, - { "do12","do12mo",_fip, 0, dout_print_mo, dout_get_mo, dout_set_mo, (float *)&dout12, DO12_MODE }, - { "do13","do13mo",_fip, 0, dout_print_mo, dout_get_mo, dout_set_mo, (float *)&dout13, DO13_MODE }, + { "do1", "do1en", _fip, 0, dout_print_en, dout_get_en, dout_set_en, (float *)&dout1, DO1_ENABLED }, + { "do1", "do1po", _fip, 0, dout_print_po, dout_get_po, dout_set_po, (float *)&dout1, DO1_POLARITY }, + { "do2", "do2en", _fip, 0, dout_print_en, dout_get_en, dout_set_en, (float *)&dout2, DO2_ENABLED }, + { "do2", "do2po", _fip, 0, dout_print_po, dout_get_po, dout_set_po, (float *)&dout2, DO2_POLARITY }, + { "do3", "do3en", _fip, 0, dout_print_en, dout_get_en, dout_set_en, (float *)&dout3, DO3_ENABLED }, + { "do3", "do3po", _fip, 0, dout_print_po, dout_get_po, dout_set_po, (float *)&dout3, DO3_POLARITY }, + { "do4", "do4en", _fip, 0, dout_print_en, dout_get_en, dout_set_en, (float *)&dout4, DO4_ENABLED }, + { "do5", "do5po", _fip, 0, dout_print_po, dout_get_po, dout_set_po, (float *)&dout5, DO5_POLARITY }, + { "do5", "do5en", _fip, 0, dout_print_en, dout_get_en, dout_set_en, (float *)&dout5, DO5_ENABLED }, + { "do6", "do6po", _fip, 0, dout_print_po, dout_get_po, dout_set_po, (float *)&dout6, DO6_POLARITY }, + { "do7", "do7en", _fip, 0, dout_print_en, dout_get_en, dout_set_en, (float *)&dout7, DO7_ENABLED }, + { "do7", "do7po", _fip, 0, dout_print_po, dout_get_po, dout_set_po, (float *)&dout7, DO7_POLARITY }, + { "do8", "do8en", _fip, 0, dout_print_en, dout_get_en, dout_set_en, (float *)&dout8, DO8_ENABLED }, + { "do8", "do8po", _fip, 0, dout_print_po, dout_get_po, dout_set_po, (float *)&dout8, DO8_POLARITY }, + { "do9", "do9en", _fip, 0, dout_print_en, dout_get_en, dout_set_en, (float *)&dout9, DO9_ENABLED }, + { "do9", "do9po", _fip, 0, dout_print_po, dout_get_po, dout_set_po, (float *)&dout9, DO9_POLARITY }, + { "do10","do10en",_fip, 0, dout_print_en, dout_get_en, dout_set_en, (float *)&dout10, DO10_ENABLED }, + { "do10","do10po",_fip, 0, dout_print_po, dout_get_po, dout_set_po, (float *)&dout10, DO10_POLARITY }, + { "do11","do11en",_fip, 0, dout_print_en, dout_get_en, dout_set_en, (float *)&dout11, DO11_ENABLED }, + { "do11","do11po",_fip, 0, dout_print_po, dout_get_po, dout_set_po, (float *)&dout11, DO11_POLARITY }, + { "do12","do12en",_fip, 0, dout_print_en, dout_get_en, dout_set_en, (float *)&dout12, DO12_ENABLED }, + { "do12","do12po",_fip, 0, dout_print_po, dout_get_po, dout_set_po, (float *)&dout12, DO12_POLARITY }, + { "do13","do13en",_fip, 0, dout_print_en, dout_get_en, dout_set_en, (float *)&dout13, DO13_ENABLED }, + { "do13","do13po",_fip, 0, dout_print_po, dout_get_po, dout_set_po, (float *)&dout13, DO13_POLARITY }, // Digital output state readers (default to non-active) { "out","out1", _f0, 2, dout_print_out, dout_get_output, dout_set_output, (float *)&dout1, 0 }, @@ -587,6 +610,47 @@ const cfgItem_t cfgArray[] = { { "out","out12", _f0, 2, dout_print_out, dout_get_output, dout_set_output, (float *)&dout12, 0 }, { "out","out13", _f0, 2, dout_print_out, dout_get_output, dout_set_output, (float *)&dout13, 0 }, + // Analog input configs + { "ain1","ain1ty",_fip, 0, ain_print_type, ain_get_type, ain_set_type, (float *)&ain1, AI1_TYPE }, + { "ain1","ain1ct",_fip, 0, ain_print_circuit, ain_get_circuit, ain_set_circuit, (float *)&ain1, AI1_CIRCUIT }, + { "ain1","ain1p1",_fip, 4, ain_print_p, ain_get_p1, ain_set_p1, (float *)&ain1, AI1_P1 }, + { "ain1","ain1p2",_fip, 4, ain_print_p, ain_get_p2, ain_set_p2, (float *)&ain1, AI1_P2 }, + { "ain1","ain1p3",_fip, 4, ain_print_p, ain_get_p3, ain_set_p3, (float *)&ain1, AI1_P3 }, + { "ain1","ain1p4",_fip, 4, ain_print_p, ain_get_p4, ain_set_p4, (float *)&ain1, AI1_P4 }, + { "ain1","ain1p5",_fip, 4, ain_print_p, ain_get_p5, ain_set_p5, (float *)&ain1, AI1_P5 }, + { "ain1","ain1vv",_f0, 4, ain_print_value, ain_get_value, set_ro, (float *)&ain1, 0 }, + { "ain1","ain1rv",_f0, 2, ain_print_resistance, ain_get_resistance, set_ro, (float *)&ain1, 0 }, + + { "ain2","ain2ty",_fip, 0, ain_print_type, ain_get_type, ain_set_type, (float *)&ain2, AI2_TYPE }, + { "ain2","ain2ct",_fip, 0, ain_print_circuit, ain_get_circuit, ain_set_circuit, (float *)&ain2, AI2_CIRCUIT }, + { "ain2","ain2p1",_fip, 4, ain_print_p, ain_get_p1, ain_set_p1, (float *)&ain2, AI2_P1 }, + { "ain2","ain2p2",_fip, 4, ain_print_p, ain_get_p2, ain_set_p2, (float *)&ain2, AI2_P2 }, + { "ain2","ain2p3",_fip, 4, ain_print_p, ain_get_p3, ain_set_p3, (float *)&ain2, AI2_P3 }, + { "ain2","ain2p4",_fip, 4, ain_print_p, ain_get_p4, ain_set_p4, (float *)&ain2, AI2_P4 }, + { "ain2","ain2p5",_fip, 4, ain_print_p, ain_get_p5, ain_set_p5, (float *)&ain2, AI2_P5 }, + { "ain2","ain2vv",_f0, 4, ain_print_value, ain_get_value, set_ro, (float *)&ain2, 0 }, + { "ain2","ain2rv",_f0, 2, ain_print_resistance, ain_get_resistance, set_ro, (float *)&ain2, 0 }, + + { "ain3","ain3ty",_fip, 0, ain_print_type, ain_get_type, ain_set_type, (float *)&ain3, AI3_TYPE }, + { "ain3","ain3ct",_fip, 0, ain_print_circuit, ain_get_circuit, ain_set_circuit, (float *)&ain3, AI3_CIRCUIT }, + { "ain3","ain3p1",_fip, 4, ain_print_p, ain_get_p1, ain_set_p1, (float *)&ain3, AI3_P1 }, + { "ain3","ain3p2",_fip, 4, ain_print_p, ain_get_p2, ain_set_p2, (float *)&ain3, AI3_P2 }, + { "ain3","ain3p3",_fip, 4, ain_print_p, ain_get_p3, ain_set_p3, (float *)&ain3, AI3_P3 }, + { "ain3","ain3p4",_fip, 4, ain_print_p, ain_get_p4, ain_set_p4, (float *)&ain3, AI3_P4 }, + { "ain3","ain3p5",_fip, 4, ain_print_p, ain_get_p5, ain_set_p5, (float *)&ain3, AI3_P5 }, + { "ain3","ain3vv",_f0, 4, ain_print_value, ain_get_value, set_ro, (float *)&ain3, 0 }, + { "ain3","ain3rv",_f0, 2, ain_print_resistance, ain_get_resistance, set_ro, (float *)&ain3, 0 }, + + { "ain4","ain4ty",_fip, 0, ain_print_type, ain_get_type, ain_set_type, (float *)&ain4, AI4_TYPE }, + { "ain4","ain4ct",_fip, 0, ain_print_circuit, ain_get_circuit, ain_set_circuit, (float *)&ain4, AI4_CIRCUIT }, + { "ain4","ain4p1",_fip, 4, ain_print_p, ain_get_p1, ain_set_p1, (float *)&ain4, AI4_P1 }, + { "ain4","ain4p2",_fip, 4, ain_print_p, ain_get_p2, ain_set_p2, (float *)&ain4, AI4_P2 }, + { "ain4","ain4p3",_fip, 4, ain_print_p, ain_get_p3, ain_set_p3, (float *)&ain4, AI4_P3 }, + { "ain4","ain4p4",_fip, 4, ain_print_p, ain_get_p4, ain_set_p4, (float *)&ain4, AI4_P4 }, + { "ain4","ain4p5",_fip, 4, ain_print_p, ain_get_p5, ain_set_p5, (float *)&ain4, AI4_P5 }, + { "ain4","ain4vv",_f0, 4, ain_print_value, ain_get_value, set_ro, (float *)&ain4, 0 }, + { "ain4","ain4rv",_f0, 2, ain_print_resistance, ain_get_resistance, set_ro, (float *)&ain4, 0 }, + // PWM settings { "p1","p1frq",_fip, 0, pwm_print_p1frq, get_flt, pwm_set_pwm,(float *)&pwm.c[PWM_1].frequency, P1_PWM_FREQUENCY }, { "p1","p1csl",_fip, 0, pwm_print_p1csl, get_flt, pwm_set_pwm,(float *)&pwm.c[PWM_1].cw_speed_lo, P1_CW_SPEED_LO }, @@ -1244,6 +1308,11 @@ const cfgItem_t cfgArray[] = { { "","do12", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, { "","do13", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // +14 = 36 + { "","ain1", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // analog input configs + { "","ain2", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, + { "","ain3", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, + { "","ain4", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, + // +4 = 40 { "","g54",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // coord offset groups { "","g55",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, { "","g56",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, @@ -1253,7 +1322,7 @@ const cfgItem_t cfgArray[] = { { "","g92",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // origin offsets { "","g28",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // g28 home position { "","g30",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // g30 home position - // +9 = 45 + // +9 = 49 { "","tof",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tool offsets { "","tt1",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets { "","tt2",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets @@ -1271,7 +1340,7 @@ const cfgItem_t cfgArray[] = { { "","tt14",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets { "","tt15",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets { "","tt16",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // tt offsets - // +17 = 62 + // +17 = 66 { "","mpo",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // machine position group { "","pos",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // work position group { "","ofs",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // work offset group @@ -1280,14 +1349,14 @@ const cfgItem_t cfgArray[] = { { "","pwr",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // motor power enagled group { "","jog",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // axis jogging state group { "","jid",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // job ID group - // +8 = 70 + // +8 = 74 { "","he1", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // heater 1 group { "","he2", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // heater 2 group { "","he3", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // heater 3 group { "","pid1",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // PID 1 group { "","pid2",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // PID 2 group { "","pid3",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // PID 3 group - // +6 = 76 + // +6 = 80 #ifdef __USER_DATA { "","uda", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0 }, // user data group @@ -1524,6 +1593,10 @@ static stat_t _do_inputs(nvObj_t *nv) // print parameters for all input groups sprintf(group, "di%d", i); _do_group(nv, group); } + for (uint8_t i=1; i < A_IN_CHANNELS+1; i++) { + sprintf(group, "ain%d", i); + _do_group(nv, group); + } return (STAT_COMPLETE); // STAT_COMPLETE suppresses the normal response line } diff --git a/g2core/coolant.cpp b/g2core/coolant.cpp index f19cea95..c553c6a6 100755 --- a/g2core/coolant.cpp +++ b/g2core/coolant.cpp @@ -30,6 +30,7 @@ #include "canonical_machine.h" // #3 #include "text_parser.h" // #4 +#include "gpio.h" #include "coolant.h" #include "planner.h" #include "hardware.h" @@ -39,6 +40,17 @@ cmCoolantSingleton_t coolant; +gpioDigitalOutput *mist_enable_output = nullptr; +gpioDigitalOutput *flood_enable_output = nullptr; + +#ifndef MIST_ENABLE_OUTPUT_NUMBER +#define MIST_ENABLE_OUTPUT_NUMBER 6 +#endif + +#ifndef FLOOD_ENABLE_OUTPUT_NUMBER +#define FLOOD_ENABLE_OUTPUT_NUMBER 7 +#endif + /**** Static functions ****/ static void _exec_coolant_control(float* value, bool* flags); @@ -48,6 +60,17 @@ static void _exec_coolant_control(float* value, bool* flags); * coolant_reset() */ void coolant_init() { + if (MIST_ENABLE_OUTPUT_NUMBER > 0) { + mist_enable_output = d_out[MIST_ENABLE_OUTPUT_NUMBER-1]; + mist_enable_output->setEnabled(IO_ENABLED); + mist_enable_output->setPolarity((ioPolarity)COOLANT_MIST_POLARITY); + } + if (FLOOD_ENABLE_OUTPUT_NUMBER > 0) { + flood_enable_output = d_out[FLOOD_ENABLE_OUTPUT_NUMBER-1]; + flood_enable_output->setEnabled(IO_ENABLED); + flood_enable_output->setPolarity((ioPolarity)COOLANT_FLOOD_POLARITY); + } + coolant.mist_enable = COOLANT_OFF; coolant.flood_enable = COOLANT_OFF; } @@ -129,26 +152,32 @@ stat_t cm_mist_coolant_control(uint8_t mist_enable) { } // NOTE: flood and mist coolants are mapped to the same pin - see hardware.h -#define _set_flood_enable_bit_hi() flood_enable_pin.set() -#define _set_flood_enable_bit_lo() flood_enable_pin.clear() -#define _set_mist_enable_bit_hi() mist_enable_pin.set() -#define _set_mist_enable_bit_lo() mist_enable_pin.clear() +//#define _set_flood_enable_bit_hi() flood_enable_pin.set() +//#define _set_flood_enable_bit_lo() flood_enable_pin.clear() +//#define _set_mist_enable_bit_hi() mist_enable_pin.set() +//#define _set_mist_enable_bit_lo() mist_enable_pin.clear() static void _exec_coolant_control(float* value, bool* flags) { if (flags[COOLANT_FLOOD]) { coolant.flood_enable = (cmCoolantEnable)value[COOLANT_FLOOD]; - if (!((coolant.flood_enable & 0x01) ^ coolant.flood_polarity)) { // inverted XOR - _set_flood_enable_bit_hi(); - } else { - _set_flood_enable_bit_lo(); +// if (!((coolant.flood_enable & 0x01) ^ coolant.flood_polarity)) { // inverted XOR +// _set_flood_enable_bit_hi(); +// } else { +// _set_flood_enable_bit_lo(); +// } + if (flood_enable_output != nullptr) { + flood_enable_output->setValue(coolant.flood_enable); } } if (flags[COOLANT_MIST]) { coolant.mist_enable = (cmCoolantEnable)value[COOLANT_MIST]; - if (!((coolant.mist_enable & 0x01) ^ coolant.mist_polarity)) { - _set_mist_enable_bit_hi(); - } else { - _set_mist_enable_bit_lo(); +// if (!((coolant.mist_enable & 0x01) ^ coolant.mist_polarity)) { +// _set_mist_enable_bit_hi(); +// } else { +// _set_mist_enable_bit_lo(); +// } + if (mist_enable_output != nullptr) { + mist_enable_output->setValue(coolant.mist_enable); } } } diff --git a/g2core/device/max31865/max31865.h b/g2core/device/max31865/max31865.h index 9908860f..4f89144c 100644 --- a/g2core/device/max31865/max31865.h +++ b/g2core/device/max31865/max31865.h @@ -405,6 +405,13 @@ struct MAX31865 final { return _rtd_value; }; + float getPullupResistance() { + return _pullup_resistance; + } + void setPullupResistance(const float r) { + _pullup_resistance = r; + } + // getValue is supposed to request a new value, block, and then return the result // PUNT - return the same as getRaw() int32_t getValue() { @@ -463,4 +470,101 @@ struct MAX31865 final { }; + +// A gpioAnalogInputPin subclass for the MAX31865 + +template +struct gpioAnalogInputPin> : gpioAnalogInput { +protected: // so we know if anyone tries to reach in + AnalogInputType_t type; + + uint8_t ext_pin_number; // the number used externally for this pin ("in" + ext_pin_number) + + using ADCPin_t = MAX31865; + + ADCPin_t pin; // the actual pin object itself + +public: + // In constructor, simply forward all values to the pin + // To get a different behavior, override this object. + template + gpioAnalogInputPin(const AnalogInputType_t _type, const uint8_t _ext_pin_number, T&&... additional_values) : + gpioAnalogInput{}, + type{_type}, + ext_pin_number{_ext_pin_number}, + pin{Motate::kNormal, [&](bool e){this->adc_has_new_value(e);}, additional_values...} + { + // nothing to do here + }; + + // functions for use by other parts of the code, and are overridden + + float getValue() override + { + if (type == AIN_TYPE_DISABLED) { + return 0; + } + return pin.getVoltage(); + }; + float getResistance() override + { + if (type == AIN_TYPE_DISABLED) { + return -1; + } + return pin.getResistance(); + }; + + AnalogInputType_t getType() override + { + return type; + }; + bool setType(const AnalogInputType_t t) override + { + // NOTE: Only AIN_TYPE_EXTERNAL and AIN_TYPE_DISABLED are handled here! + if (t == AIN_TYPE_INTERNAL) { + return false; + } + type = t; + return true; + }; + + AnalogCircuit_t getCircuit() override + { + return AIN_CIRCUIT_EXTERNAL; + }; + bool setCircuit(const AnalogCircuit_t c) override + { + // prevent setting circuit - it's always AIN_CIRCUIT_EXTERNAL + return false; + }; + + float getParameter(const uint8_t p) override + { + if (p == 0) { + return pin.getPullupResistance(); + } + return 0; + }; + bool setParameter(const uint8_t p, const float v) override + { + if (p == 0) { + pin.setPullupResistance(v); + return true; + } + return false; + }; + + + void startSampling() override { + pin.startSampling(); + }; + + // support function for pin value update interrupt handling + + void adc_has_new_value(bool err) { +// float raw_adc_value = pin.getRaw(); +// history.add_sample(raw_adc_value); + }; +}; + #endif // max31865_h diff --git a/g2core/gpio.cpp b/g2core/gpio.cpp index 02d1b480..0cb6e9ae 100644 --- a/g2core/gpio.cpp +++ b/g2core/gpio.cpp @@ -118,7 +118,7 @@ void gpio_set_probing_mode(const uint8_t input_num_ext, const bool is_probing) int8_t gpio_get_probing_input(void) { - for (uint8_t i = 0; i <= D_IN_CHANNELS; i++) { + for (uint8_t i = 1; i <= D_IN_CHANNELS; i++) { if (d_in[i-1]->getFunction() == INPUT_FUNCTION_PROBE) { return (i); } @@ -151,42 +151,31 @@ type* _io(const nvObj_t *nv) { gpioDigitalInput* _i(const nvObj_t *nv) { return _io(nv); } gpioDigitalOutput* _o(const nvObj_t *nv) { return _io(nv); } +gpioAnalogInput* _ai(const nvObj_t *nv) { return _io(nv); } -// static stat_t _input_set_helper(nvObj_t *nv, const int8_t lower_bound, const int8_t upper_bound) -// { -// if ((nv->value < lower_bound) || (nv->value >= upper_bound)) { -// return (STAT_INPUT_VALUE_RANGE_ERROR); -// } -// set_ui8(nv); // will this work in -1 is a valid value? -// if (cm_get_machine_state() != MACHINE_INITIALIZING) { -// inputs_reset(); -// } -// return (STAT_OK); -// } -// -// static stat_t _output_set_helper(nvObj_t *nv, const int8_t lower_bound, const int8_t upper_bound) -// { -// if ((nv->value < lower_bound) || (nv->value >= upper_bound)) { -// return (STAT_INPUT_VALUE_RANGE_ERROR); -// } -// set_ui8(nv); // will this work in -1 is a valid value? -// if (cm_get_machine_state() != MACHINE_INITIALIZING) { -// outputs_reset(); -// } -// return (STAT_OK); -// } - /* - * Get/set input mode + * Get/set enabled */ -stat_t din_get_mo(nvObj_t *nv) +stat_t din_get_en(nvObj_t *nv) { - return _i(nv)->getMode(nv); + return _i(nv)->getEnabled(nv); } -stat_t din_set_mo(nvObj_t *nv) +stat_t din_set_en(nvObj_t *nv) { - return _i(nv)->setMode(nv); + return _i(nv)->setEnabled(nv); +} + +/* + * Get/set input polarity + */ +stat_t din_get_po(nvObj_t *nv) +{ + return _i(nv)->getPolarity(nv); +} +stat_t din_set_po(nvObj_t *nv) +{ + return _i(nv)->setPolarity(nv); } /* @@ -223,13 +212,28 @@ stat_t din_get_input(nvObj_t *nv) } -stat_t dout_get_mo(nvObj_t *nv) +/* + * Get/set enabled + */ +stat_t dout_get_en(nvObj_t *nv) { - return _o(nv)->getMode(nv); + return _o(nv)->getEnabled(nv); } -stat_t dout_set_mo(nvObj_t *nv) +stat_t dout_set_en(nvObj_t *nv) { - return _o(nv)->setMode(nv); + return _o(nv)->setEnabled(nv); +} + +/* + * Get/set input polarity + */ +stat_t dout_get_po(nvObj_t *nv) +{ + return _o(nv)->getPolarity(nv); +} +stat_t dout_set_po(nvObj_t *nv) +{ + return _o(nv)->setPolarity(nv); } /* @@ -244,6 +248,59 @@ stat_t dout_set_output(nvObj_t *nv) return _o(nv)->setValue(nv); } + +/* + * ain_get_value() - get the measured voltage level of the analog input + */ +stat_t ain_get_value(nvObj_t *nv) { + return _ai(nv)->getValue(nv); +} +// no ain_set_value + +/* + * ain_get_resistance() - get the measured resistance of the analog input + * NOTE: Requires the circuit type to be configured and the relevant parameters set + */ +stat_t ain_get_resistance(nvObj_t *nv) { + return _ai(nv)->getResistance(nv); +} +// no ain_set_resistance + +/* + * ain_get_type() - get the measured voltage level of the analog input + */ +stat_t ain_get_type(nvObj_t *nv) { + return _ai(nv)->getType(nv); +} +stat_t ain_set_type(nvObj_t *nv) { + return _ai(nv)->setType(nv); +} + +stat_t ain_get_circuit(nvObj_t *nv) { + return _ai(nv)->getCircuit(nv); +} +stat_t ain_set_circuit(nvObj_t *nv) { + return _ai(nv)->setCircuit(nv); +} + +stat_t ain_get_parameter(nvObj_t *nv, const uint8_t p) { + return _ai(nv)->getParameter(nv, p); +} +stat_t ain_set_parameter(nvObj_t *nv, const uint8_t p) { + return _ai(nv)->setParameter(nv, p); +} + +stat_t ain_get_p1(nvObj_t *nv) { return ain_get_parameter(nv, 0); }; +stat_t ain_set_p1(nvObj_t *nv) { return ain_set_parameter(nv, 0); }; +stat_t ain_get_p2(nvObj_t *nv) { return ain_get_parameter(nv, 1); }; +stat_t ain_set_p2(nvObj_t *nv) { return ain_set_parameter(nv, 1); }; +stat_t ain_get_p3(nvObj_t *nv) { return ain_get_parameter(nv, 2); }; +stat_t ain_set_p3(nvObj_t *nv) { return ain_set_parameter(nv, 2); }; +stat_t ain_get_p4(nvObj_t *nv) { return ain_get_parameter(nv, 3); }; +stat_t ain_set_p4(nvObj_t *nv) { return ain_set_parameter(nv, 3); }; +stat_t ain_get_p5(nvObj_t *nv) { return ain_get_parameter(nv, 4); }; +stat_t ain_set_p5(nvObj_t *nv) { return ain_set_parameter(nv, 4); }; + /*********************************************************************************** * TEXT MODE SUPPORT * Functions to print variables from the cfgArray table @@ -251,20 +308,29 @@ stat_t dout_set_output(nvObj_t *nv) #ifdef __TEXT_MODE - static const char fmt_gpio_mo[] = "[%smo] input mode%17d [0=active-low,1=active-hi,2=disabled]\n"; + static const char fmt_gpio_in_en[] = "[%smo] input enabled%13d [-1=unavailable,0=disabled,1=enabled]\n"; + static const char fmt_gpio_in_po[] = "[%smo] input polarity%13d [0=normal/active-high,1=inverted/active-low]\n"; static const char fmt_gpio_ac[] = "[%sac] input action%15d [0=none,1=stop,2=fast_stop,3=halt,4=alarm,5=shutdown,6=panic,7=reset]\n"; static const char fmt_gpio_fn[] = "[%sfn] input function%13d [0=none,1=limit,2=interlock,3=shutdown,4=probe]\n"; static const char fmt_gpio_in[] = "Input %s state: %5d\n"; - static const char fmt_gpio_domode[] = "[%smo] output mode%16d [0=active low,1=active high,2=disabled]\n"; + static const char fmt_gpio_out_en[] = "[%smo] output enabled%12d [-1=unavailable,0=disabled,1=enabled]\n"; + static const char fmt_gpio_out_po[] = "[%smo] output polarity%12d [0=normal/active-high,1=inverted/active-low]\n"; static const char fmt_gpio_out[] = "Output %s state: %5d\n"; + static const char fmt_ain_value[] = "Analog input %s voltage: %5.2fV\n"; + static const char fmt_ain_resistance[] = "Analog input %s resistance: %5.2fohm\n"; + static const char fmt_ain_type[] = "[%s] input type%17d [0=disabled,1=internal,2=external]\n"; + static const char fmt_ain_circuit[] = "[%s] analog circuit%13d [0=disabled,1=pull-up,2=external,3=inverted op-amp,4=constant current inverted op-amp]\n"; + static const char fmt_ain_parameter[] = "[%s] circuit parameter%6.4f [usage varies by circuit type]\n"; + static void _print_di(nvObj_t *nv, const char *format) { sprintf(cs.out_buf, format, nv->group, (int)nv->value); xio_writeline(cs.out_buf); } - void din_print_mo(nvObj_t *nv) {_print_di(nv, fmt_gpio_mo);} + void din_print_en(nvObj_t *nv) {_print_di(nv, fmt_gpio_in_en);} + void din_print_po(nvObj_t *nv) {_print_di(nv, fmt_gpio_in_po);} void din_print_ac(nvObj_t *nv) {_print_di(nv, fmt_gpio_ac);} void din_print_fn(nvObj_t *nv) {_print_di(nv, fmt_gpio_fn);} void din_print_in(nvObj_t *nv) { @@ -272,9 +338,39 @@ stat_t dout_set_output(nvObj_t *nv) xio_writeline(cs.out_buf); } - void dout_print_mo(nvObj_t *nv) {_print_di(nv, fmt_gpio_domode);} + void dout_print_en(nvObj_t *nv) {_print_di(nv, fmt_gpio_out_en);} + void dout_print_po(nvObj_t *nv) {_print_di(nv, fmt_gpio_out_po);} void dout_print_out(nvObj_t *nv) { sprintf(cs.out_buf, fmt_gpio_out, nv->token, (int)nv->value); xio_writeline(cs.out_buf); } + + void ain_print_value(nvObj_t *nv) + { + sprintf(cs.out_buf, fmt_ain_value, nv->token, (float)nv->value); + xio_writeline(cs.out_buf); + } + void ain_print_resistance(nvObj_t *nv) + { + sprintf(cs.out_buf, fmt_ain_resistance, nv->token, (float)nv->value); + xio_writeline(cs.out_buf); + } + void ain_print_type(nvObj_t *nv) + { + sprintf(cs.out_buf, fmt_ain_type, nv->token, (int)nv->value); + xio_writeline(cs.out_buf); + } + + void ain_print_circuit(nvObj_t *nv) + { + sprintf(cs.out_buf, fmt_ain_circuit, nv->token, (int)nv->value); + xio_writeline(cs.out_buf); + } + + void ain_print_p(nvObj_t *nv) + { + sprintf(cs.out_buf, fmt_ain_parameter, nv->token, (float)nv->value); + xio_writeline(cs.out_buf); + } + #endif diff --git a/g2core/gpio.h b/g2core/gpio.h index cc5390b0..b782863f 100644 --- a/g2core/gpio.h +++ b/g2core/gpio.h @@ -42,6 +42,7 @@ #include "MotatePins.h" using Motate::kPullUp; using Motate::kDebounce; +using Motate::kStartHigh; using Motate::kStartLow; using Motate::kPWMPinInverted; @@ -54,13 +55,17 @@ using Motate::kPWMPinInverted; //--- do not change from here down ---// typedef enum { - IO_ACTIVE_LOW = 0, // input/output is active low (aka normally open) - IO_ACTIVE_HIGH = 1, // input/output is active high (aka normally closed) - IO_MODE_DISABLED = 2 // input/output is disabled -} ioMode; + IO_UNAVAILABLE = -1, // input/output is missing/used/unavailable + IO_DISABLED = 0, // input/output is disabled + IO_ENABLED = 1 // input/output enabled +} ioEnabled; + +typedef enum { + IO_ACTIVE_HIGH = 0, // input/output is active high (aka normally closed) + IO_ACTIVE_LOW = 1, // input/output is active low (aka normally open) +} ioPolarity; #define NORMALLY_OPEN IO_ACTIVE_LOW // equivalent #define NORMALLY_CLOSED IO_ACTIVE_HIGH // equivalent -#define IO_MODE_MAX IO_MODE_DISABLED // for range checking typedef enum { // actions are initiated from within the input's ISR INPUT_ACTION_NONE = 0, @@ -97,10 +102,11 @@ typedef enum { } inputEdgeFlag; /* - * GPIO structures + * gpioDigitalInput - digital input base class */ struct gpioDigitalInput { - // this is the implementation for a non-existant pin - see gpioDigitalInputPin for a real pin + // this is the generic implementation for a "any"" digital input pin + // see gpioDigitalInputPin for a real pin // functions for use by other parts of the code @@ -112,8 +118,11 @@ struct gpioDigitalInput { virtual inputAction getAction(); virtual bool setAction(const inputAction); - virtual ioMode getMode(); - virtual bool setMode(const ioMode); + virtual ioEnabled getEnabled(); + virtual bool setEnabled(const ioEnabled); + + virtual ioPolarity getPolarity(); + virtual bool setPolarity(const ioPolarity); virtual void setExternalNumber(const uint8_t); virtual void setIsHoming(const bool); @@ -124,8 +133,7 @@ struct gpioDigitalInput { stat_t getState(nvObj_t *nv) { - if (getMode() == IO_MODE_DISABLED) { - nv->value = IO_MODE_DISABLED; // historical consistency + if (getEnabled() <= IO_DISABLED) { nv->valuetype = TYPE_NULL; return (STAT_OK); } @@ -135,18 +143,35 @@ struct gpioDigitalInput { }; // no setState - stat_t getMode(nvObj_t *nv) + stat_t getEnabled(nvObj_t *nv) { - nv->value = getMode(); + nv->value = getEnabled(); nv->valuetype = TYPE_INT; return (STAT_OK); }; - stat_t setMode(nvObj_t *nv) + stat_t setEnabled(nvObj_t *nv) { - if ((nv->value < IO_ACTIVE_LOW) || (nv->value >= IO_MODE_MAX)) { + if ((nv->value < IO_DISABLED) || (nv->value > IO_ENABLED)) { return (STAT_INPUT_VALUE_RANGE_ERROR); } - if (!setMode((ioMode)nv->value)) { + if (!setEnabled((ioEnabled)nv->value)) { + return STAT_PARAMETER_IS_READ_ONLY; + } + return (STAT_OK); + }; + + stat_t getPolarity(nvObj_t *nv) + { + nv->value = getPolarity(); + nv->valuetype = TYPE_INT; + return (STAT_OK); + }; + stat_t setPolarity(nvObj_t *nv) + { + if ((nv->value < IO_ACTIVE_HIGH) || (nv->value > IO_ACTIVE_LOW)) { + return (STAT_INPUT_VALUE_RANGE_ERROR); + } + if (!setPolarity((ioPolarity)nv->value)) { return STAT_PARAMETER_IS_READ_ONLY; } return (STAT_OK); @@ -160,7 +185,7 @@ struct gpioDigitalInput { }; stat_t setAction(nvObj_t *nv) { - if ((nv->value < INPUT_ACTION_NONE) || (nv->value >= INPUT_ACTION_MAX)) { + if ((nv->value < INPUT_ACTION_NONE) || (nv->value > INPUT_ACTION_MAX)) { return (STAT_INPUT_VALUE_RANGE_ERROR); } if (!setAction((inputAction)nv->value)) { @@ -177,7 +202,7 @@ struct gpioDigitalInput { }; stat_t setFunction(nvObj_t *nv) { - if ((nv->value < INPUT_FUNCTION_NONE) || (nv->value >= INPUT_FUNCTION_MAX)) { + if ((nv->value < INPUT_FUNCTION_NONE) || (nv->value > INPUT_FUNCTION_MAX)) { return (STAT_INPUT_VALUE_RANGE_ERROR); } if (!setFunction((inputFunc)nv->value)) { @@ -187,12 +212,15 @@ struct gpioDigitalInput { }; }; -template +/* + * gpioDigitalInputPin - concrete child of gpioDigitalInput + */ +template struct gpioDigitalInputPin : gpioDigitalInput { -protected: // so we know if anyone tries to reach in - ioMode mode; // 0=active low (NO), 1= active high (NC), 2=disabled + ioEnabled enabled; // -1=unavailable, 0=disabled, 1=enabled + ioPolarity polarity; // 0=normal/active high, 1=inverted/active low inputAction action; // 0=none, 1=stop, 2=halt, 3=stop_steps, 4=reset - inputFunc function; // function to perform when activated / deactivated + inputFunc input_function; // function to perform when activated / deactivated inputEdgeFlag edge; // keeps a transient record of edges for immediate inquiry @@ -204,44 +232,41 @@ protected: // so we know if anyone tries to reach in uint16_t lockout_ms; // number of milliseconds for debounce lockout Motate::Timeout lockout_timer; // time to expire current debounce lockout, or 0 if no lockout - pinType pin; // the actual pin object itself + Pin_t pin; // the actual pin object itself -public: - // In constructor, simply forward all values to the pinType + // In constructor, simply forward all values to the Pin_t // To get a different behavior, override this object. template - gpioDigitalInputPin(const ioMode _mode, const uint8_t _ext_pin_number, T&&... V) : + gpioDigitalInputPin(const ioEnabled _enabled, const ioPolarity _polarity, const uint8_t _ext_pin_number, T&&... V) : gpioDigitalInput{}, - mode{_mode}, + enabled{_enabled}, + polarity{_polarity}, ext_pin_number{_ext_pin_number}, - pin{((mode == IO_ACTIVE_LOW) ? kPullUp|kDebounce : kDebounce), [&]{this->pin_changed();}, std::forward(V)...} - {}; - - // gpioDigitalInputPin(const ioMode _mode, const uint8_t _ext_pin_number) : - // gpioDigitalInput{}, - // mode{_mode}, - // ext_pin_number{_ext_pin_number}, - // pin{((mode == IO_ACTIVE_LOW) ? kPullUp|kDebounce : kDebounce), [&]{this->pin_changed();}} - // {}; + pin{((polarity == IO_ACTIVE_LOW) ? kPullUp|kDebounce : kDebounce), [&]{this->pin_changed();}, std::forward(V)...} + { + if (pin.isNull()) { + enabled = IO_UNAVAILABLE; + } + }; // functions for use by other parts of the code, and are overridden bool getState() override { - if (mode == IO_MODE_DISABLED) { + if (enabled <= IO_DISABLED) { return false; } const bool v = (const bool)pin; - return (mode == IO_ACTIVE_HIGH) ? v : !v; + return (polarity == IO_ACTIVE_HIGH) ? v : !v; }; inputFunc getFunction() override { - return function; + return input_function; } bool setFunction(const inputFunc f) override { - function = f; + input_function = f; return true; }; @@ -255,14 +280,27 @@ public: return true; }; - ioMode getMode() override + ioEnabled getEnabled() override { - return mode; + return enabled; }; - bool setMode(const ioMode m) override + bool setEnabled(const ioEnabled m) override { - mode = m; - pin.setOptions((mode == IO_ACTIVE_LOW) ? kPullUp|kDebounce : kDebounce); + if (enabled == IO_UNAVAILABLE) { + return false; + } + enabled = m; + return true; + }; + + ioPolarity getPolarity() override + { + return polarity; + }; + bool setPolarity(const ioPolarity new_polarity) override + { + polarity = new_polarity; + pin.setOptions((polarity == IO_ACTIVE_LOW) ? kPullUp|kDebounce : kDebounce); return true; }; @@ -287,7 +325,7 @@ public: void pin_changed() { // return if input is disabled - if (mode == IO_MODE_DISABLED) { + if (enabled == IO_DISABLED) { return; } @@ -297,7 +335,7 @@ public: } ioState pin_value = (ioState)(bool)pin; - ioState pin_value_corrected = (ioState)(pin_value ^ ((bool)mode ^ 1)); // correct for NO or NC mode + ioState pin_value_corrected = (ioState)(pin_value ^ ((bool)polarity)); // correct for NO or NC mode // This shouldn't be necessary - the processor shouldn't call without an edge // if (state == (ioState)pin_value_corrected) { @@ -370,74 +408,89 @@ public: // these functions also trigger on the leading edge - if (function == INPUT_FUNCTION_LIMIT) { + if (input_function == INPUT_FUNCTION_LIMIT) { cm.limit_requested = ext_pin_number; - } else if (function == INPUT_FUNCTION_SHUTDOWN) { + } else if (input_function == INPUT_FUNCTION_SHUTDOWN) { cm.shutdown_requested = ext_pin_number; - } else if (function == INPUT_FUNCTION_INTERLOCK) { + } else if (input_function == INPUT_FUNCTION_INTERLOCK) { cm.safety_interlock_disengaged = ext_pin_number; } } // if (edge == INPUT_EDGE_LEADING) // trigger interlock release on trailing edge if (edge == INPUT_EDGE_TRAILING) { - if (function == INPUT_FUNCTION_INTERLOCK) { + if (input_function == INPUT_FUNCTION_INTERLOCK) { cm.safety_interlock_reengaged = ext_pin_number; } } sr_request_status_report(SR_REQUEST_TIMED); //+++++ Put this one back in. }; - }; +/* + * gpioDigitalOutput - digital/PWM output base class + */ struct gpioDigitalOutput { + // this is the generic implementation for a "any"" output pin (PWM or Digital) + // see gpioDigitalOutputPin for a real pin // functions for use by other parts of the code, and are what to override - virtual ioMode getMode() - { - return IO_MODE_DISABLED; - }; - virtual bool setMode(const ioMode) - { - return false; - }; + virtual ioEnabled getEnabled(); + virtual bool setEnabled(const ioEnabled); - virtual float getValue() - { - return -1; - }; - virtual bool setValue(const float) - { - return false; - }; + virtual ioPolarity getPolarity(); + virtual bool setPolarity(const ioPolarity); + + virtual float getValue(); + virtual bool setValue(const float); + + virtual float getFrequency(); + virtual bool setFrequency(const float); // functions that take nvObj_t* and return stat_t, NOT overridden - virtual stat_t getMode(nvObj_t *nv) + stat_t getEnabled(nvObj_t *nv) { - nv->value = getMode(); + nv->value = getEnabled(); nv->valuetype = TYPE_INT; return (STAT_OK); }; - virtual stat_t setMode(nvObj_t *nv) + stat_t setEnabled(nvObj_t *nv) { - if ((nv->value < IO_ACTIVE_LOW) || (nv->value >= IO_MODE_MAX)) { + if ((nv->value < IO_DISABLED) || (nv->value > IO_ENABLED)) { return (STAT_INPUT_VALUE_RANGE_ERROR); } - if (!setMode((ioMode)nv->value)) { - return STAT_INPUT_VALUE_RANGE_ERROR; + if (!setEnabled((ioEnabled)nv->value)) { + return STAT_PARAMETER_IS_READ_ONLY; + } + return (STAT_OK); + }; + + stat_t getPolarity(nvObj_t *nv) + { + nv->value = getPolarity(); + nv->valuetype = TYPE_INT; + return (STAT_OK); + }; + stat_t setPolarity(nvObj_t *nv) + { + if ((nv->value < IO_ACTIVE_HIGH) || (nv->value > IO_ACTIVE_LOW)) { + return (STAT_INPUT_VALUE_RANGE_ERROR); + } + if (!setPolarity((ioPolarity)nv->value)) { + return STAT_PARAMETER_IS_READ_ONLY; } return (STAT_OK); }; virtual stat_t getValue(nvObj_t *nv) { - auto mode = getMode(); - if (mode == IO_MODE_DISABLED) { + auto enabled = getEnabled(); + if (enabled <= IO_DISABLED) { nv->value = 0; nv->valuetype = TYPE_NULL; // reports back as NULL } else { @@ -445,7 +498,7 @@ struct gpioDigitalOutput { nv->precision = 2; nv->value = getValue(); // read it as a float - bool invert = (mode == 0); + bool invert = (getPolarity() == IO_ACTIVE_LOW); if (invert) { nv->value = 1.0 - nv->value; } @@ -454,13 +507,13 @@ struct gpioDigitalOutput { }; virtual stat_t setValue(nvObj_t *nv) { - auto mode = getMode(); - if (mode == IO_MODE_DISABLED) { + auto enabled = getEnabled(); + if (enabled <= IO_DISABLED) { nv->valuetype = TYPE_NULL; // reports back as NULL } else { float value = nv->value; // read it as a float - bool invert = (mode == 0); + bool invert = (getPolarity() == IO_ACTIVE_LOW); if (invert) { value = 1.0 - value; } @@ -474,33 +527,53 @@ struct gpioDigitalOutput { }; -template +/* + * gpioDigitalOutputPin - concrete child of gpioDigitalOutput + */ +template struct gpioDigitalOutputPin : gpioDigitalOutput { - ioMode mode; // 0=active low (NO), 1= active high (NC), 2=disabled - pinType pin; + ioEnabled enabled; // -1=unavailable, 0=disabled, 1=enabled + ioPolarity polarity; // 0=normal/active high, 1=inverted/active low + Pin_t pin; - // In constructor, simply forward all values to the pinType + // In constructor, simply forward all values to the Pin_t template - gpioDigitalOutputPin(const ioMode _mode, T&&... V) : + gpioDigitalOutputPin(const ioEnabled _enabled, const ioPolarity _polarity, T&&... V) : gpioDigitalOutput{}, - mode{ _mode }, - pin{((mode == IO_ACTIVE_LOW) ? kStartHigh|kPWMPinInverted : kStartLow), std::forward(V)...} - {}; + enabled{ _enabled }, + polarity{ _polarity }, + pin{((polarity == IO_ACTIVE_LOW) ? kStartHigh|kPWMPinInverted : kStartLow), std::forward(V)...} + { + if (pin.isNull()) { + enabled = IO_UNAVAILABLE; + } + }; // functions for use by other parts of the code, and are overridden - ioMode getMode() override + ioEnabled getEnabled() override { - return mode; + return enabled; }; - bool setMode(const ioMode m) override + bool setEnabled(const ioEnabled m) override { - mode = m; - pin.setOptions((mode == IO_ACTIVE_LOW) ? kPullUp|kDebounce : kDebounce); // prepare the pin - pin = ((mode == IO_ACTIVE_LOW) ? true : false); // set the output to inactive + if (enabled == IO_UNAVAILABLE) { + return false; + } + enabled = m; return true; }; + ioPolarity getPolarity() override + { + return polarity; + }; + bool setPolarity(const ioPolarity new_polarity) override + { + polarity = new_polarity; + pin.setOptions((polarity == IO_ACTIVE_LOW) ? kPullUp|kDebounce : kDebounce); + return true; + }; float getValue() override { @@ -515,14 +588,368 @@ struct gpioDigitalOutputPin : gpioDigitalOutput { return true; }; + float _last_set_frequency = 0; + // it must be set through this interface at least once before it can be read back + float getFrequency() override + { + return _last_set_frequency; + }; + bool setFrequency(const float freq) override + { + pin.setFrequency(freq); + _last_set_frequency = freq; + return true; + }; + }; -struct gpioAnalogInput { // one struct per analog input - ioMode mode; +/* + * gpioAnalogInput - analog (ADC) input base class + */ +struct gpioAnalogInput { + // type of analog input source - read only - defined by the board + enum AnalogInputType_t { + AIN_TYPE_DISABLED = 0, // the whole input is disabled + AIN_TYPE_INTERNAL = 1, // single-ended or differential + AIN_TYPE_EXTERNAL = 2, // for externally (SPI) connected inputs + }; + + // type of circuit connected - for use in determining the resistance + enum AnalogCircuit_t { + AIN_CIRCUIT_DISABLED = 0, // there is no circuit, resistance will read -1 + // no additional configuration + AIN_CIRCUIT_PULLUP = 1, // resistance being measured is pulling up to VCC + // the pull-up resistance is measured (rt) + // p1 is the set pull-down resistance (r1) + AIN_CIRCUIT_EXTERNAL = 2, // for externally (SPI) connected inputs + // no additional configuration + AIN_CIRCUIT_INV_OPAMP = 3, // inverted op-amp connected + // the pull-up resistance is measured (rt) + // p1 is the set pull-down resistance of the bias(+) (r1) + // p2 is the set pull-up resistance of the gain(-) (r2) + // p3 is the set pull-down to output of the gain(-) (r3) + AIN_CIRCUIT_CC_INV_OPAMP = 4, // for externally (SPI) connected inputs + // the pull-up resistance to the current source is measured (rt) + // p4 is the set pull-up resistance of the bias(+) (r4) + // p1 is the set pull-down resistance of the bias(+) (r1) + // p2 is the set pull-up resistance of the gain(-) (r2) + // p3 is the set pull-down to output of the gain(-) (r3) + // p5 is the set constant current in millivolts (c1) + }; + static const auto AIN_CIRCUIT_MAX = AIN_CIRCUIT_CC_INV_OPAMP; + + // this is the generic implementation for a "any"" analog input pin + // see gpioAnalogInputPin for a real pin + + // functions for use by other parts of the code + + virtual float getValue(); + virtual float getResistance(); + + virtual AnalogInputType_t getType(); + virtual bool setType(const AnalogInputType_t); + + virtual AnalogCircuit_t getCircuit(); + virtual bool setCircuit(const AnalogCircuit_t); + + virtual float getParameter(const uint8_t p); + virtual bool setParameter(const uint8_t p, const float v); + + virtual void startSampling(); + + // functions that take nvObj_t* and return stat_t, NOT overridden + + stat_t getValue(nvObj_t *nv) + { + if (getType() == AIN_TYPE_DISABLED) { + nv->valuetype = TYPE_NULL; + return (STAT_OK); + } + nv->value = getValue(); + nv->valuetype = TYPE_FLOAT; + return (STAT_OK); + }; + // no setValue + + stat_t getResistance(nvObj_t *nv) + { + if (getType() == AIN_TYPE_DISABLED || getCircuit() == AIN_CIRCUIT_DISABLED) { + nv->valuetype = TYPE_NULL; + return (STAT_OK); + } + nv->value = getResistance(); + nv->valuetype = TYPE_FLOAT; + return (STAT_OK); + }; + // no setResistance + + stat_t getType(nvObj_t *nv) + { + nv->value = getType(); + nv->valuetype = TYPE_INT; + return (STAT_OK); + }; + stat_t setType(nvObj_t *nv) + { + if ((nv->value < AIN_TYPE_DISABLED) || (nv->value > AIN_TYPE_EXTERNAL)) { + return (STAT_INPUT_VALUE_RANGE_ERROR); + } + if (!setType((AnalogInputType_t)nv->value)) { + return STAT_PARAMETER_IS_READ_ONLY; + } + return (STAT_OK); + }; + + stat_t getCircuit(nvObj_t *nv) + { + nv->value = getCircuit(); + nv->valuetype = TYPE_INT; + return (STAT_OK); + }; + stat_t setCircuit(nvObj_t *nv) + { + if ((nv->value < AIN_CIRCUIT_DISABLED) || (nv->value > AIN_CIRCUIT_MAX)) { + return (STAT_INPUT_VALUE_RANGE_ERROR); + } + if (!setCircuit((AnalogCircuit_t)nv->value)) { + return STAT_PARAMETER_IS_READ_ONLY; + } + return (STAT_OK); + }; + + stat_t getParameter(nvObj_t *nv, const uint8_t p) + { + nv->value = getParameter(p); + nv->valuetype = TYPE_FLOAT; + return (STAT_OK); + }; + stat_t setParameter(nvObj_t *nv, const uint8_t p) + { + if (!setParameter(p, nv->value)) { + return STAT_PARAMETER_IS_READ_ONLY; + } + return (STAT_OK); + }; }; -struct gpioAnalogOutput { // one struct per analog output - ioMode mode; +// statistical sampling utility class +template +struct ValueHistory { + + float variance_max = 2.0; + ValueHistory() {}; + ValueHistory(float v_max) : variance_max{v_max} {}; + + struct sample_t { + float value; + float value_sq; + void set(float v) { value = v; value_sq = v*v; } + }; + sample_t samples[sample_count]; + uint16_t next_sample = 0; + void _bump_index(uint16_t &v) { + ++v; + if (v == sample_count) { + v = 0; + } + }; + uint16_t sampled = 0; + + float rolling_sum = 0; + float rolling_sum_sq = 0; + float rolling_mean = 0; + void add_sample(float t) { + rolling_sum -= samples[next_sample].value; + rolling_sum_sq -= samples[next_sample].value_sq; + + samples[next_sample].set(t); + + rolling_sum += samples[next_sample].value; + rolling_sum_sq += samples[next_sample].value_sq; + + _bump_index(next_sample); + if (sampled < sample_count) { ++sampled; } + + rolling_mean = rolling_sum/(float)sampled; + }; + + float get_std_dev() { + // Important note: this is a POPULATION standard deviation, not a population standard deviation + float variance = (rolling_sum_sq/(float)sampled) - (rolling_mean*rolling_mean); + return sqrt(std::abs(variance)); + }; + + float value() { + // we'll shoot through the samples and ignore the outliers + uint16_t samples_kept = 0; + float temp = 0; + float std_dev = get_std_dev(); + + for (uint16_t i=0; i +struct gpioAnalogInputPin : gpioAnalogInput { +protected: // so we know if anyone tries to reach in + AnalogInputType_t type; + AnalogCircuit_t circuit; + float parameters[6]; + + uint8_t ext_pin_number; // the number used externally for this pin ("in" + ext_pin_number) + + const float variance_max = 1.1; + ValueHistory<20> history {variance_max}; + + float last_raw_value; + + ADCPin_t pin; // the actual pin object itself + +public: + // In constructor, simply forward all values to the pin + // To get a different behavior, override this object. + template + gpioAnalogInputPin(const AnalogInputType_t _type, const uint8_t _ext_pin_number, T&&... additional_values) : + gpioAnalogInput{}, + type{_type}, + ext_pin_number{_ext_pin_number}, + pin{Motate::kNormal, [&]{this->adc_has_new_value();}, std::forward(additional_values)...} + { + pin.setInterrupts(Motate::kPinInterruptOnChange|Motate::kInterruptPriorityLow); + pin.setVoltageRange(3.29, 0.0, 3.29, 1000000.0); + }; + + // functions for use by other parts of the code, and are overridden + + float getValue() override + { + if (type == AIN_TYPE_DISABLED) { + return 0; + } + return history.value(); + }; + float getResistance() override + { + // NOTE: AIN_CIRCUIT_EXTERNAL is NOT handled here! + // That needs to be handled in a separate override! + if (type == AIN_TYPE_DISABLED || circuit == AIN_CIRCUIT_DISABLED) { + return -1; + } + const float v = history.value(); + const float s = pin.getTopVoltage(); + switch (circuit) { + + case AIN_CIRCUIT_PULLUP: + { + float r1 = parameters[0]; // pull-up + + if (ADCPin_t::is_differential) { + return (v * 2.0 * r1)/(s - v); + } else { + return (v * r1)/(s - v); + } + break; + } + + case AIN_CIRCUIT_INV_OPAMP: + { + float r1 = parameters[0]; // pull-down from bias(+) side of op-amp + float r2 = parameters[1]; // pull-up from gain(-) side of op-amp + float r3 = parameters[2]; // pull-to-output from gain(-) side of op-amp + + return (r1 * r2 * (s - v))/(r2 * v + r3 * s); + break; + } + + case AIN_CIRCUIT_CC_INV_OPAMP: + { + // the pull-up resistance to the current source is measured (rt) + float r4 = parameters[3]; // pull-up resistance of the bias(+) side of op-amp + float r1 = parameters[0]; // pull-down from bias(+) side of op-amp + float r2 = parameters[1]; // pull-up from gain(-) side of op-amp + float r3 = parameters[2]; // pull-to-output from gain(-) side of op-amp + float c = parameters[4]; // constant current in volts (c1) + + // r_0 = (r_1 (r_2 (s - v) + r_3 s) - v r_2 r_4)/(c r_3 (r_1 + r_4)) + return (r1 * (r2 * (s - v) + r3 * s) - v * r2 * r4)/(c * r3 * (r1 + r4)); + break; + } + + // AIN_CIRCUIT_EXTERNAL is specifically missing! + + default: + return -1; + } + + }; + + AnalogInputType_t getType() override + { + return type; + }; + bool setType(const AnalogInputType_t t) override + { + // NOTE: AIN_TYPE_EXTERNAL is NOT handled here! + // That needs to be handled in a separate override! + if (t == AIN_TYPE_EXTERNAL) { + return false; + } + type = t; + return true; + }; + + AnalogCircuit_t getCircuit() override + { + return circuit; + }; + bool setCircuit(const AnalogCircuit_t c) override + { + // prevent setting circuit to AIN_CIRCUIT_EXTERNAL + if (c == AIN_CIRCUIT_EXTERNAL) { + return false; + } + circuit = c; + return true; + }; + + float getParameter(const uint8_t p) override + { + if (p < 0 || p >= 6) { + return 0; + } + return parameters[p]; + }; + bool setParameter(const uint8_t p, const float v) override + { + if (p < 0 || p >= 6) { + return false; + } + parameters[p] = v; + return true; + }; + + void startSampling() override { + pin.startSampling(); + }; + + // support function for pin value update interrupt handling + + void adc_has_new_value() { + last_raw_value = pin.getRaw(); + history.add_sample(pin.getVoltage()); + }; }; /* @@ -539,36 +966,167 @@ void gpio_set_homing_mode(const uint8_t input_num, const bool is_homing); void gpio_set_probing_mode(const uint8_t input_num, const bool is_probing); int8_t gpio_get_probing_input(void); -stat_t din_get_mo(nvObj_t *nv); -stat_t din_set_mo(nvObj_t *nv); -stat_t din_get_ac(nvObj_t *nv); +stat_t din_get_en(nvObj_t *nv); // enabled +stat_t din_set_en(nvObj_t *nv); +stat_t din_get_po(nvObj_t *nv); // input sense +stat_t din_set_po(nvObj_t *nv); +stat_t din_get_ac(nvObj_t *nv); // input action stat_t din_set_ac(nvObj_t *nv); -stat_t din_get_fn(nvObj_t *nv); +stat_t din_get_fn(nvObj_t *nv); // input function stat_t din_set_fn(nvObj_t *nv); - stat_t din_get_input(nvObj_t *nv); -stat_t dout_get_mo(nvObj_t *nv); // output sense -stat_t dout_set_mo(nvObj_t *nv); // output sense -stat_t dout_get_output(nvObj_t *nv); +stat_t dout_get_en(nvObj_t *nv); // enabled +stat_t dout_set_en(nvObj_t *nv); +stat_t dout_get_po(nvObj_t *nv); // output sense +stat_t dout_set_po(nvObj_t *nv); +stat_t dout_get_output(nvObj_t *nv); // actual output value (float) stat_t dout_set_output(nvObj_t *nv); +stat_t ain_get_value(nvObj_t *nv); // get the voltage level +// no ain_set_value +stat_t ain_get_resistance(nvObj_t *nv); // get the resistance in ohms +// no ain_set_resistance +stat_t ain_get_type(nvObj_t *nv); // get the ADC type (or disabled) +stat_t ain_set_type(nvObj_t *nv); // set the type (used to disable/enable) +stat_t ain_get_circuit(nvObj_t *nv); // get the circuit type +stat_t ain_set_circuit(nvObj_t *nv); // set the circuit type +stat_t ain_get_parameter(nvObj_t *nv, const uint8_t p); // get the value of parameter p +stat_t ain_set_parameter(nvObj_t *nv, const uint8_t p); // set the value of parameter p +stat_t ain_get_p1(nvObj_t *nv); +stat_t ain_set_p1(nvObj_t *nv); +stat_t ain_get_p2(nvObj_t *nv); +stat_t ain_set_p2(nvObj_t *nv); +stat_t ain_get_p3(nvObj_t *nv); +stat_t ain_set_p3(nvObj_t *nv); +stat_t ain_get_p4(nvObj_t *nv); +stat_t ain_set_p4(nvObj_t *nv); +stat_t ain_get_p5(nvObj_t *nv); +stat_t ain_set_p5(nvObj_t *nv); + #ifdef __TEXT_MODE - void din_print_mo(nvObj_t *nv); + void din_print_en(nvObj_t *nv); + void din_print_po(nvObj_t *nv); void din_print_ac(nvObj_t *nv); void din_print_fn(nvObj_t *nv); void din_print_in(nvObj_t *nv); - void dout_print_mo(nvObj_t *nv); + + void dout_print_en(nvObj_t *nv); + void dout_print_po(nvObj_t *nv); void dout_print_out(nvObj_t *nv); + + void ain_print_value(nvObj_t *nv); + void ain_print_resistance(nvObj_t *nv); + void ain_print_type(nvObj_t *nv); + void ain_print_circuit(nvObj_t *nv); + void ain_print_p(nvObj_t *nv); #else - #define din_print_mo tx_print_stub + #define din_print_en tx_print_stub + #define din_print_po tx_print_stub #define din_print_ac tx_print_stub #define din_print_fn tx_print_stub #define din_print_in tx_print_stub - #define dout_print_mo tx_print_stub + + #define dout_print_en tx_print_stub + #define dout_print_po tx_print_stub #define dout_print_out tx_print_stub + + #define ain_print_value tx_print_stub + #define ain_print_resistance tx_print_stub + #define ain_print_type tx_print_stub + #define ain_print_circuit tx_print_stub + #define ain_print_p tx_print_stub #endif // __TEXT_MODE #include "board_gpio.h" +#ifndef AI1_TYPE +#define AI1_TYPE AIN_TYPE_DISABLED +#endif +#ifndef AI1_CIRCUIT +#define AI1_CIRCUIT AIN_CIRCUIT_DISABLED +#endif +#ifndef AI1_P1 +#define AI1_P1 0.0 +#endif +#ifndef AI1_P2 +#define AI1_P2 0.0 +#endif +#ifndef AI1_P3 +#define AI1_P3 0.0 +#endif +#ifndef AI1_P4 +#define AI1_P4 0.0 +#endif +#ifndef AI1_P5 +#define AI1_P5 0.0 +#endif + + +#ifndef AI2_TYPE +#define AI2_TYPE AIN_TYPE_DISABLED +#endif +#ifndef AI2_CIRCUIT +#define AI2_CIRCUIT AIN_CIRCUIT_DISABLED +#endif +#ifndef AI2_P1 +#define AI2_P1 0.0 +#endif +#ifndef AI2_P2 +#define AI2_P2 0.0 +#endif +#ifndef AI2_P3 +#define AI2_P3 0.0 +#endif +#ifndef AI2_P4 +#define AI2_P4 0.0 +#endif +#ifndef AI2_P5 +#define AI2_P5 0.0 +#endif + +#ifndef AI3_TYPE +#define AI3_TYPE AIN_TYPE_DISABLED +#endif +#ifndef AI3_CIRCUIT +#define AI3_CIRCUIT AIN_CIRCUIT_DISABLED +#endif +#ifndef AI3_P1 +#define AI3_P1 0.0 +#endif +#ifndef AI3_P2 +#define AI3_P2 0.0 +#endif +#ifndef AI3_P3 +#define AI3_P3 0.0 +#endif +#ifndef AI3_P4 +#define AI3_P4 0.0 +#endif +#ifndef AI3_P5 +#define AI3_P5 0.0 +#endif + +#ifndef AI4_TYPE +#define AI4_TYPE AIN_TYPE_DISABLED +#endif +#ifndef AI4_CIRCUIT +#define AI4_CIRCUIT AIN_CIRCUIT_DISABLED +#endif +#ifndef AI4_P1 +#define AI4_P1 0.0 +#endif +#ifndef AI4_P2 +#define AI4_P2 0.0 +#endif +#ifndef AI4_P3 +#define AI4_P3 0.0 +#endif +#ifndef AI4_P4 +#define AI4_P4 0.0 +#endif +#ifndef AI4_P5 +#define AI4_P5 0.0 +#endif + #endif // End of include guard: GPIO_H_ONCE diff --git a/g2core/pwm.cpp b/g2core/pwm.cpp index ecc5212b..fe91d3f2 100755 --- a/g2core/pwm.cpp +++ b/g2core/pwm.cpp @@ -28,6 +28,7 @@ #include "g2core.h" // #1 #include "config.h" // #2 #include "hardware.h" +#include "gpio.h" #include "spindle.h" #include "text_parser.h" #include "pwm.h" @@ -40,8 +41,19 @@ pwmSingleton_t pwm; // Setup motate PWM pins -Motate::PWMOutputPin spindle_pwm_pin {Motate::kNormal, P1_PWM_FREQUENCY}; -Motate::PWMOutputPin secondary_pwm_pin {Motate::kNormal, P1_PWM_FREQUENCY}; // assume the same frequency, to start with at least +//Motate::PWMOutputPin spindle_pwm_pin {Motate::kNormal, P1_PWM_FREQUENCY}; +//Motate::PWMOutputPin secondary_pwm_pin {Motate::kNormal, P1_PWM_FREQUENCY}; // assume the same frequency, to start with at least + +gpioDigitalOutput *spindle_pwm_output = nullptr; +gpioDigitalOutput *secondary_pwm_output = nullptr; + +#ifndef SPINDLE_OUTPUT_NUMBER +#define SPINDLE_OUTPUT_NUMBER 6 +#endif + +#ifndef SECONDARY_PWM_OUTPUT_NUMBER +#define SECONDARY_PWM_OUTPUT_NUMBER 0 +#endif /***** PWM code *****/ /* @@ -53,7 +65,17 @@ Motate::PWMOutputPin secondary_pwm_pin {Motate:: * - See system.h for timer and port assignments * - Don't do this: memset(&TIMER_PWM1, 0, sizeof(PWM_TIMER_t)); // zero out the timer registers */ -void pwm_init() {} +void pwm_init() { + if (SPINDLE_OUTPUT_NUMBER > 0) { + spindle_pwm_output = d_out[SPINDLE_OUTPUT_NUMBER-1]; + spindle_pwm_output->setFrequency(P1_PWM_FREQUENCY); + + } + if (SECONDARY_PWM_OUTPUT_NUMBER > 0) { + secondary_pwm_output = d_out[SECONDARY_PWM_OUTPUT_NUMBER-1]; + secondary_pwm_output->setFrequency(P1_PWM_FREQUENCY); + } +} /* * pwm_set_freq() - set PWM channel frequency @@ -72,9 +94,13 @@ stat_t pwm_set_freq(uint8_t chan, float freq) //if (freq > PWM_MAX_FREQ) { return (STAT_INPUT_EXCEEDS_MAX_VALUE);} if (chan == PWM_1) { - spindle_pwm_pin.setFrequency(freq); + if (spindle_pwm_output != nullptr) { + spindle_pwm_output->setFrequency(freq); + } } else if (chan == PWM_2) { - secondary_pwm_pin.setFrequency(freq); + if (secondary_pwm_output != nullptr) { + secondary_pwm_output->setFrequency(freq); + } } return (STAT_OK); @@ -99,15 +125,13 @@ stat_t pwm_set_duty(uint8_t chan, float duty) if (duty > 1.0) { return (STAT_INPUT_EXCEEDS_MAX_VALUE);} if (chan == PWM_1) { -// if (spindle_pwm_pin.isNull()) { -// cm_alarm(STAT_ALARM, "attempt to turn on a non-existant spindle"); -// } - spindle_pwm_pin = duty; + if (spindle_pwm_output != nullptr) { + spindle_pwm_output->setValue(duty); + } } else if (chan == PWM_2) { -// if (secondary_pwm_pin.isNull()) { -// cm_alarm(STAT_ALARM, "attempt to turn on a non-existant spindle"); -// } - secondary_pwm_pin = duty; + if (secondary_pwm_output != nullptr) { + secondary_pwm_output->setValue(duty); + } } return (STAT_OK); diff --git a/g2core/settings/settings_default.h b/g2core/settings/settings_default.h index 24aa3b20..000539cd 100644 --- a/g2core/settings/settings_default.h +++ b/g2core/settings/settings_default.h @@ -817,6 +817,12 @@ #ifndef A_ZERO_BACKOFF #define A_ZERO_BACKOFF 2.0 #endif +#ifndef A_SPRING_OFFSET_FACTOR +#define A_SPRING_OFFSET_FACTOR 0 +#endif +#ifndef A_SPRING_OFFSET_MAX +#define A_SPRING_OFFSET_MAX 0 +#endif // B AXIS #ifndef B_AXIS_MODE @@ -934,8 +940,11 @@ */ // Xmin on v9 board -#ifndef DI1_MODE -#define DI1_MODE IO_ACTIVE_LOW // Normally open +#ifndef DI1_ENABLED +#define DI1_ENABLED IO_ENABLED +#endif +#ifndef DI1_POLARITY +#define DI1_POLARITY IO_ACTIVE_LOW // Normally open #endif #ifndef DI1_ACTION #define DI1_ACTION INPUT_ACTION_NONE @@ -945,8 +954,11 @@ #endif // Xmax -#ifndef DI2_MODE -#define DI2_MODE IO_ACTIVE_LOW // Normally open +#ifndef DI2_ENABLED +#define DI2_ENABLED IO_ENABLED +#endif +#ifndef DI2_POLARITY +#define DI2_POLARITY IO_ACTIVE_LOW // Normally open #endif #ifndef DI2_ACTION #define DI2_ACTION INPUT_ACTION_NONE @@ -956,8 +968,11 @@ #endif // Ymin -#ifndef DI3_MODE -#define DI3_MODE IO_ACTIVE_LOW // Normally open +#ifndef DI3_ENABLED +#define DI3_ENABLED IO_ENABLED +#endif +#ifndef DI3_POLARITY +#define DI3_POLARITY IO_ACTIVE_LOW // Normally open #endif #ifndef DI3_ACTION #define DI3_ACTION INPUT_ACTION_NONE @@ -967,8 +982,11 @@ #endif // Ymax -#ifndef DI4_MODE -#define DI4_MODE IO_ACTIVE_LOW // Normally open +#ifndef DI4_ENABLED +#define DI4_ENABLED IO_ENABLED +#endif +#ifndef DI4_POLARITY +#define DI4_POLARITY IO_ACTIVE_LOW // Normally open #endif #ifndef DI4_ACTION #define DI4_ACTION INPUT_ACTION_NONE @@ -978,8 +996,11 @@ #endif // Zmin -#ifndef DI5_MODE -#define DI5_MODE IO_ACTIVE_LOW // Normally open +#ifndef DI5_ENABLED +#define DI5_ENABLED IO_ENABLED +#endif +#ifndef DI5_POLARITY +#define DI5_POLARITY IO_ACTIVE_LOW // Normally open #endif #ifndef DI5_ACTION #define DI5_ACTION INPUT_ACTION_NONE @@ -989,8 +1010,11 @@ #endif // Zmax -#ifndef DI6_MODE -#define DI6_MODE IO_ACTIVE_LOW // Normally open +#ifndef DI6_ENABLED +#define DI6_ENABLED IO_ENABLED +#endif +#ifndef DI6_POLARITY +#define DI6_POLARITY IO_ACTIVE_LOW // Normally open #endif #ifndef DI6_ACTION #define DI6_ACTION INPUT_ACTION_NONE @@ -1000,8 +1024,11 @@ #endif // Amin -#ifndef DI7_MODE -#define DI7_MODE IO_ACTIVE_LOW // Normally open +#ifndef DI7_ENABLED +#define DI7_ENABLED IO_ENABLED +#endif +#ifndef DI7_POLARITY +#define DI7_POLARITY IO_ACTIVE_LOW // Normally open #endif #ifndef DI7_ACTION #define DI7_ACTION INPUT_ACTION_NONE @@ -1011,8 +1038,11 @@ #endif // Amax -#ifndef DI8_MODE -#define DI8_MODE IO_ACTIVE_LOW // Normally open +#ifndef DI8_ENABLED +#define DI8_ENABLED IO_ENABLED +#endif +#ifndef DI8_POLARITY +#define DI8_POLARITY IO_ACTIVE_LOW // Normally open #endif #ifndef DI8_ACTION #define DI8_ACTION INPUT_ACTION_NONE @@ -1022,8 +1052,11 @@ #endif // Safety line -#ifndef DI9_MODE -#define DI9_MODE IO_ACTIVE_HIGH // Normally closed +#ifndef DI9_ENABLED +#define DI9_ENABLED IO_ENABLED +#endif +#ifndef DI9_POLARITY +#define DI9_POLARITY IO_ACTIVE_HIGH // Normally closed #endif #ifndef DI9_ACTION #define DI9_ACTION INPUT_ACTION_NONE @@ -1032,8 +1065,11 @@ #define DI9_FUNCTION INPUT_FUNCTION_NONE #endif -#ifndef DI10_MODE -#define DI10_MODE IO_ACTIVE_LOW // Normally open +#ifndef DI10_ENABLED +#define DI10_ENABLED IO_ENABLED +#endif +#ifndef DI10_POLARITY +#define DI10_POLARITY IO_ACTIVE_LOW // Normally open #endif #ifndef DI10_ACTION #define DI10_ACTION INPUT_ACTION_NONE @@ -1042,8 +1078,11 @@ #define DI10_FUNCTION INPUT_FUNCTION_NONE #endif -#ifndef DI11_MODE -#define DI11_MODE IO_ACTIVE_LOW // Normally open +#ifndef DI11_ENABLED +#define DI11_ENABLED IO_ENABLED +#endif +#ifndef DI11_POLARITY +#define DI11_POLARITY IO_ACTIVE_LOW // Normally open #endif #ifndef DI11_ACTION #define DI11_ACTION INPUT_ACTION_NONE @@ -1052,8 +1091,11 @@ #define DI11_FUNCTION INPUT_FUNCTION_NONE #endif -#ifndef DI12_MODE -#define DI12_MODE IO_ACTIVE_LOW // Normally open +#ifndef DI12_ENABLED +#define DI12_ENABLED IO_ENABLED +#endif +#ifndef DI12_POLARITY +#define DI12_POLARITY IO_ACTIVE_LOW // Normally open #endif #ifndef DI12_ACTION #define DI12_ACTION INPUT_ACTION_NONE @@ -1065,60 +1107,189 @@ // DIGITAL OUTPUTS - Currently these are hard-wired to extruders //Extruder1_PWM -#ifndef DO1_MODE -#define DO1_MODE IO_ACTIVE_HIGH +#ifndef DO1_ENABLED +#define DO1_ENABLED IO_ENABLED +#endif +#ifndef DO1_POLARITY +#define DO1_POLARITY IO_ACTIVE_HIGH #endif //Extruder2_PWM -#ifndef DO2_MODE -#define DO2_MODE IO_ACTIVE_HIGH +#ifndef DO2_ENABLED +#define DO2_ENABLED IO_ENABLED +#endif +#ifndef DO2_POLARITY +#define DO2_POLARITY IO_ACTIVE_HIGH #endif //Fan1A_PWM -#ifndef DO3_MODE -#define DO3_MODE IO_ACTIVE_HIGH +#ifndef DO3_ENABLED +#define DO3_ENABLED IO_ENABLED +#endif +#ifndef DO3_POLARITY +#define DO3_POLARITY IO_ACTIVE_HIGH #endif //Fan1B_PWM -#ifndef DO4_MODE -#define DO4_MODE IO_ACTIVE_HIGH +#ifndef DO4_ENABLED +#define DO4_ENABLED IO_ENABLED +#endif +#ifndef DO4_POLARITY +#define DO4_POLARITY IO_ACTIVE_HIGH #endif -#ifndef DO5_MODE -#define DO5_MODE IO_ACTIVE_HIGH +#ifndef DO5_ENABLED +#define DO5_ENABLED IO_ENABLED #endif -#ifndef DO6_MODE -#define DO6_MODE IO_ACTIVE_HIGH +#ifndef DO5_POLARITY +#define DO5_POLARITY IO_ACTIVE_HIGH #endif -#ifndef DO7_MODE -#define DO7_MODE IO_ACTIVE_HIGH +#ifndef DO6_ENABLED +#define DO6_ENABLED IO_ENABLED #endif -#ifndef DO8_MODE -#define DO8_MODE IO_ACTIVE_HIGH +#ifndef DO6_POLARITY +#define DO6_POLARITY IO_ACTIVE_HIGH +#endif +#ifndef DO7_ENABLED +#define DO7_ENABLED IO_ENABLED +#endif +#ifndef DO7_POLARITY +#define DO7_POLARITY IO_ACTIVE_HIGH +#endif +#ifndef DO8_ENABLED +#define DO8_ENABLED IO_ENABLED +#endif +#ifndef DO8_POLARITY +#define DO8_POLARITY IO_ACTIVE_HIGH #endif //SAFEin (Output) signal -#ifndef DO9_MODE -#define DO9_MODE IO_ACTIVE_HIGH +#ifndef DO9_ENABLED +#define DO9_ENABLED IO_ENABLED +#endif +#ifndef DO9_POLARITY +#define DO9_POLARITY IO_ACTIVE_HIGH #endif -#ifndef DO10_MODE -#define DO10_MODE IO_ACTIVE_HIGH +#ifndef DO10_ENABLED +#define DO10_ENABLED IO_ENABLED +#endif +#ifndef DO10_POLARITY +#define DO10_POLARITY IO_ACTIVE_HIGH #endif //Header Bed FET -#ifndef DO11_MODE -#define DO11_MODE IO_ACTIVE_HIGH +#ifndef DO11_ENABLED +#define DO11_ENABLED IO_ENABLED +#endif +#ifndef DO11_POLARITY +#define DO11_POLARITY IO_ACTIVE_HIGH #endif //Indicator_LED -#ifndef DO12_MODE -#define DO12_MODE IO_ACTIVE_HIGH +#ifndef DO12_ENABLED +#define DO12_ENABLED IO_ENABLED +#endif +#ifndef DO12_POLARITY +#define DO12_POLARITY IO_ACTIVE_HIGH #endif -#ifndef DO13_MODE -#define DO13_MODE IO_ACTIVE_HIGH +#ifndef DO13_ENABLED +#define DO13_ENABLED IO_ENABLED #endif +#ifndef DO13_POLARITY +#define DO13_POLARITY IO_ACTIVE_HIGH +#endif + +// foind in gpio.h: +// #ifndef AI1_TYPE +// #define AI1_TYPE AIN_TYPE_DISABLED +// #endif +// #ifndef AI1_CIRCUIT +// #define AI1_CIRCUIT AIN_CIRCUIT_DISABLED +// #endif +// #ifndef AI1_P1 +// #define AI1_P1 0.0 +// #endif +// #ifndef AI1_P2 +// #define AI1_P2 0.0 +// #endif +// #ifndef AI1_P3 +// #define AI1_P3 0.0 +// #endif +// #ifndef AI1_P4 +// #define AI1_P4 0.0 +// #endif +// #ifndef AI1_P5 +// #define AI1_P5 0.0 +// #endif +// +// +// #ifndef AI2_TYPE +// #define AI2_TYPE AIN_TYPE_DISABLED +// #endif +// #ifndef AI2_CIRCUIT +// #define AI2_CIRCUIT AIN_CIRCUIT_DISABLED +// #endif +// #ifndef AI2_P1 +// #define AI2_P1 0.0 +// #endif +// #ifndef AI2_P2 +// #define AI2_P2 0.0 +// #endif +// #ifndef AI2_P3 +// #define AI2_P3 0.0 +// #endif +// #ifndef AI2_P4 +// #define AI2_P4 0.0 +// #endif +// #ifndef AI2_P5 +// #define AI2_P5 0.0 +// #endif +// +// #ifndef AI3_TYPE +// #define AI3_TYPE AIN_TYPE_DISABLED +// #endif +// #ifndef AI3_CIRCUIT +// #define AI3_CIRCUIT AIN_CIRCUIT_DISABLED +// #endif +// #ifndef AI3_P1 +// #define AI3_P1 0.0 +// #endif +// #ifndef AI3_P2 +// #define AI3_P2 0.0 +// #endif +// #ifndef AI3_P3 +// #define AI3_P3 0.0 +// #endif +// #ifndef AI3_P4 +// #define AI3_P4 0.0 +// #endif +// #ifndef AI3_P5 +// #define AI3_P5 0.0 +// #endif +// +// #ifndef AI4_TYPE +// #define AI4_TYPE AIN_TYPE_DISABLED +// #endif +// #ifndef AI4_CIRCUIT +// #define AI4_CIRCUIT AIN_CIRCUIT_DISABLED +// #endif +// #ifndef AI4_P1 +// #define AI4_P1 0.0 +// #endif +// #ifndef AI4_P2 +// #define AI4_P2 0.0 +// #endif +// #ifndef AI4_P3 +// #define AI4_P3 0.0 +// #endif +// #ifndef AI4_P4 +// #define AI4_P4 0.0 +// #endif +// #ifndef AI4_P5 +// #define AI4_P5 0.0 +// #endif // *** PWM Settings *** // diff --git a/g2core/spindle.cpp b/g2core/spindle.cpp index e61e1ee4..a24891a9 100644 --- a/g2core/spindle.cpp +++ b/g2core/spindle.cpp @@ -30,6 +30,7 @@ #include "canonical_machine.h" // #3 #include "text_parser.h" // #4 +#include "gpio.h" #include "spindle.h" #include "planner.h" #include "hardware.h" @@ -40,6 +41,18 @@ cmSpindleton_t spindle; + +gpioDigitalOutput *spindle_enable_output = nullptr; +gpioDigitalOutput *spindle_direction_output = nullptr; + +#ifndef SPINDLE_ENABLE_OUTPUT_NUMBER +#define SPINDLE_ENABLE_OUTPUT_NUMBER 4 +#endif + +#ifndef SPINDLE_DIRECTION_OUTPUT_NUMBER +#define SPINDLE_DIRECTION_OUTPUT_NUMBER 5 +#endif + /**** Static functions ****/ static void _exec_spindle_speed(float *value, bool *flag); @@ -52,6 +65,17 @@ static float _get_spindle_pwm (cmSpindleEnable enable, cmSpindleDir direction); */ void spindle_init() { + if (SPINDLE_ENABLE_OUTPUT_NUMBER > 0) { + spindle_enable_output = d_out[SPINDLE_ENABLE_OUTPUT_NUMBER-1]; + spindle_enable_output->setEnabled(IO_ENABLED); + spindle_enable_output->setPolarity((ioPolarity)SPINDLE_ENABLE_POLARITY); + } + if (SPINDLE_DIRECTION_OUTPUT_NUMBER > 0) { + spindle_direction_output = d_out[SPINDLE_DIRECTION_OUTPUT_NUMBER-1]; + spindle_direction_output->setEnabled(IO_ENABLED); + spindle_direction_output->setPolarity((ioPolarity)SPINDLE_DIR_POLARITY); + } + if( pwm.c[PWM_1].frequency < 0 ) { pwm.c[PWM_1].frequency = 0; } @@ -153,10 +177,10 @@ stat_t cm_spindle_control(uint8_t control) // requires SPINDLE_CONTROL_xxx styl return(STAT_OK); } - #define _set_spindle_enable_bit_hi() spindle_enable_pin.set() - #define _set_spindle_enable_bit_lo() spindle_enable_pin.clear() - #define _set_spindle_direction_bit_hi() spindle_dir_pin.set() - #define _set_spindle_direction_bit_lo() spindle_dir_pin.clear() +// #define _set_spindle_enable_bit_hi() spindle_enable_pin.set() +// #define _set_spindle_enable_bit_lo() spindle_enable_pin.clear() +// #define _set_spindle_direction_bit_hi() spindle_dir_pin.set() +// #define _set_spindle_direction_bit_lo() spindle_dir_pin.clear() static void _exec_spindle_control(float *value, bool *flag) { @@ -164,10 +188,13 @@ static void _exec_spindle_control(float *value, bool *flag) if (flag[1]) { spindle.direction = (cmSpindleDir)value[1]; // record spindle direction in the struct - if (spindle.direction ^ spindle.dir_polarity) { - _set_spindle_direction_bit_hi(); - } else { - _set_spindle_direction_bit_lo(); +// if (spindle.direction ^ spindle.dir_polarity) { +// _set_spindle_direction_bit_hi(); +// } else { +// _set_spindle_direction_bit_lo(); +// } + if (spindle_direction_output != nullptr) { + spindle_direction_output->setValue(spindle.direction); } } @@ -175,10 +202,13 @@ static void _exec_spindle_control(float *value, bool *flag) { // set on/off. Mask out PAUSE and consider it OFF spindle.enable = (cmSpindleEnable)value[0]; // record spindle enable in the struct - if ((spindle.enable & 0x01) ^ spindle.enable_polarity) { - _set_spindle_enable_bit_lo(); - } else { - _set_spindle_enable_bit_hi(); +// if ((spindle.enable & 0x01) ^ spindle.enable_polarity) { +// _set_spindle_enable_bit_lo(); +// } else { +// _set_spindle_enable_bit_hi(); +// } + if (spindle_enable_output != nullptr) { + spindle_enable_output->setValue(spindle.enable); } } diff --git a/g2core/temperature.cpp b/g2core/temperature.cpp index 2c323b99..d668baf2 100755 --- a/g2core/temperature.cpp +++ b/g2core/temperature.cpp @@ -313,7 +313,7 @@ struct Thermistor { template Thermistor(const float temp_low, const float temp_med, const float temp_high, const float res_low, const float res_med, const float res_high, const ADCCircuit *_circuit, Ts&&... additional_values) : circuit{_circuit}, - adc_pin{kNormal, [&]{this->adc_has_new_value();}, additional_values...} + adc_pin{kNormal, [&]{this->adc_has_new_value();}, std::forward(additional_values)...} { setup(temp_low, temp_med, temp_high, res_low, res_med, res_high); adc_pin.setInterrupts(kPinInterruptOnChange|kInterruptPriorityLow);