*/
#include "tinyg.h" // #1
-#include "config.h" // #2
+#include "config.h" // #2
#include "report.h"
#include "help.h"
-// help helper functions (snicker)
stat_t help_stub(nvObj_t *nv) {return STAT_OK;}
#ifdef __HELP_SCREENS
-static void _status_report_advisory()
-{
-fprintf_P(stderr, PSTR("\n\
-Note: TinyG generates automatic status reports by default\n\
-This can be disabled by entering $sv=0\n\
-See the wiki below for more details.\n\
-"));
+
+static void _status_report_advisory() {
+ fprintf_P(stderr, PSTR
+ ("\n"
+ "Note: TinyG generates automatic status reports by default\n"
+ "This can be disabled by entering $sv=0\n"
+ "See the wiki below for more details.\n"));
}
-static void _postscript()
-{
-fprintf_P(stderr, PSTR("\n\
-For detailed TinyG info see: https://github.com/synthetos/TinyG/wiki/\n\
-For the latest firmware see: https://github.com/synthetos/TinyG\n\
-Please log any issues at http://www.synthetos.com/forums\n\
-Have fun\n"));
+
+static void _postscript() {
+ fprintf_P(stderr, PSTR
+ ("\n"
+ "For detailed TinyG info see: https://github.com/synthetos/TinyG/wiki/\n"
+ "For the latest firmware see: https://github.com/synthetos/TinyG\n"
+ "Please log any issues at http://www.synthetos.com/forums\n"
+ "Have fun\n"));
}
-/*
- * help_general() - help invoked as h from the command line
- */
-uint8_t help_general(nvObj_t *nv)
-{
-fprintf_P(stderr, PSTR("\n\n\n### TinyG Help ###\n"));
-fprintf_P(stderr, PSTR("\
-These commands are active from the command line:\n\
- ^x Reset (control x) - software reset\n\
- ? Machine position and gcode model state\n\
- $ Show and set configuration settings\n\
- ! Feedhold - stop motion without losing position\n\
- ~ Cycle Start - restart from feedhold\n\
- h Show this help screen\n\
- $h Show configuration help screen\n\
- $test List self-tests\n\
- $test=N Run self-test N\n\
- $home=1 Run a homing cycle\n\
- $defa=1 Restore all settings to \"factory\" defaults\n\
-"));
-_status_report_advisory();
-_postscript();
-rpt_print_system_ready_message();
-return STAT_OK;
+
+/// Help invoked as h from the command line
+uint8_t help_general(nvObj_t *nv) {
+ fprintf_P(stderr, PSTR("\n\n\n### TinyG Help ###\n"));
+ fprintf_P(stderr, PSTR
+ ("\n"
+ "These commands are active from the command line:\n"
+ " ^x Reset (control x) - software reset\n"
+ " ? Machine position and gcode model state\n"
+ " $ Show and set configuration settings\n"
+ " ! Feedhold - stop motion without losing position\n"
+ " ~ Cycle Start - restart from feedhold\n"
+ " h Show this help screen\n"
+ " $h Show configuration help screen\n"
+ " $test List self-tests\n"
+ " $test=N Run self-test N\n"
+ " $home=1 Run a homing cycle\n"
+ " $defa=1 Restore all settings to \"factory\" defaults\n"));
+ _status_report_advisory();
+ _postscript();
+ rpt_print_system_ready_message();
+ return STAT_OK;
}
-/*
- * help_config() - help invoked as $h
- */
-stat_t help_config(nvObj_t *nv)
-{
-fprintf_P(stderr, PSTR("\n\n\n### TinyG CONFIGURATION Help ###\n"));
-fprintf_P(stderr, PSTR("\
-These commands are active for configuration:\n\
- $sys Show system (general) settings\n\
- $1 Show motor 1 settings (or whatever motor you want 1,2,3,4)\n\
- $x Show X axis settings (or whatever axis you want x,y,z,a,b,c)\n\
- $m Show all motor settings\n\
- $q Show all axis settings\n\
- $o Show all offset settings\n\
- $$ Show all settings\n\
- $h Show this help screen\n\n\
-"));
-
-fprintf_P(stderr, PSTR("\
-Each $ command above also displays the token for each setting in [ ] brackets\n\
-To view settings enter a token:\n\n\
- $<token>\n\n\
-For example $yfr to display the Y max feed rate\n\n\
-To update settings enter token equals value:\n\n\
- $<token>=<value>\n\n\
-For example $yfr=800 to set the Y max feed rate to 800 mm/minute\n\
-For configuration details see: https://github.com/synthetos/TinyG/wiki/TinyG-Configuration\n\
-"));
-_status_report_advisory();
-_postscript();
-return STAT_OK;
+
+/// elp invoked as $h
+stat_t help_config(nvObj_t *nv) {
+ fprintf_P(stderr, PSTR("\n\n\n### TinyG CONFIGURATION Help ###\n"));
+ fprintf_P(stderr, PSTR
+ ("These commands are active for configuration:\n"
+ " $sys Show system (general) settings\n"
+ " $1 Show motor 1 settings (or whatever motor you want 1,2,3,4)\n"
+ " $x Show X axis settings (or whatever axis you want x,y,z,a,b,c)\n"
+ " $m Show all motor settings\n"
+ " $q Show all axis settings\n"
+ " $o Show all offset settings\n"
+ " $$ Show all settings\n"
+ " $h Show this help screen\n\n"));
+
+ fprintf_P(stderr, PSTR
+ ("Each $ command above also displays the token for each setting in [ ] brackets\n "
+ "To view settings enter a token:\n\n"
+ " $<token>\n\n"
+ "For example $yfr to display the Y max feed rate\n\n"
+ "To update settings enter token equals value:\n\n"
+ " $<token>=<value>\n\n"
+ "For example $yfr=800 to set the Y max feed rate to 800 mm/minute\n"
+ "For configuration details see: https://github.com/synthetos/TinyG/wiki/TinyG-Configuration\n"));
+ _status_report_advisory();
+ _postscript();
+
+ return STAT_OK;
}
-/*
- * help_test() - help invoked for tests
- */
-stat_t help_test(nvObj_t *nv)
-{
-fprintf_P(stderr, PSTR("\n\n\n### TinyG SELF TEST Help ###\n"));
-fprintf_P(stderr, PSTR("\
-Invoke self test by entering $test=N where N is one of:\n\
- $test=1 smoke test\n\
- $test=2 homing test (you must trip homing switches)\n\
- $test=3 square test (a series of squares)\n\
- $test=4 arc test (some large circles)\n\
- $test=5 dwell test (moves spaced by 1 second dwells)\n\
- $test=6 feedhold test (enter ! and ~ to hold and restart, respectively)\n\
- $test=7 M codes test (M codes intermingled with moves)\n\
- $test=8 JSON test (motion test run using JSON commands)\n\
- $test=9 inverse time test\n\
- $test=10 rotary motion test\n\
- $test=11 small moves test\n\
- $test=12 slow moves test\n\
- $test=13 coordinate system offset test (G92, G54-G59)\n\
-\n\
-Tests assume a centered XY origin and at least 80mm clearance in all directions\n\
-Tests assume Z has at least 40mm posiitive clearance\n\
-Tests start with a G0 X0 Y0 Z0 move\n\
-Homing is the exception. No initial position or clearance is assumed\n\
-"));
-_postscript();
-return STAT_OK;
+
+/// Help invoked for tests
+stat_t help_test(nvObj_t *nv) {
+ fprintf_P(stderr, PSTR("\n\n\n### TinyG SELF TEST Help ###\n"));
+ fprintf_P(stderr, PSTR
+ ("Invoke self test by entering $test=N where N is one of:\n"
+ " $test=1 smoke test\n"
+ " $test=2 homing test (you must trip homing switches)\n"
+ " $test=3 square test (a series of squares)\n"
+ " $test=4 arc test (some large circles)\n"
+ " $test=5 dwell test (moves spaced by 1 second dwells)\n"
+ " $test=6 feedhold test (enter ! and ~ to hold and restart, respectively)\n"
+ " $test=7 M codes test (M codes intermingled with moves)\n"
+ " $test=8 JSON test (motion test run using JSON commands)\n"
+ " $test=9 inverse time test\n"
+ " $test=10 rotary motion test\n"
+ " $test=11 small moves test\n"
+ " $test=12 slow moves test\n"
+ " $test=13 coordinate system offset test (G92, G54-G59)\n"
+ "\n"
+ "Tests assume a centered XY origin and at least 80mm clearance in all directions\n"
+ "Tests assume Z has at least 40mm posiitive clearance\n"
+ "Tests start with a G0 X0 Y0 Z0 move\n"
+ "Homing is the exception. No initial position or clearance is assumed\n"));
+ _postscript();
+
+ return STAT_OK;
}
-/*
- * help_defa() - help invoked for defaults
- */
-stat_t help_defa(nvObj_t *nv)
-{
-fprintf_P(stderr, PSTR("\n\n\n### TinyG RESTORE DEFAULTS Help ###\n"));
-fprintf_P(stderr, PSTR("\
-Enter $defa=1 to reset the system to the factory default values.\n\
-This will overwrite any changes you have made.\n"));
-_postscript();
-return STAT_OK;
+
+/// Help invoked for defaults
+stat_t help_defa(nvObj_t *nv) {
+ fprintf_P(stderr, PSTR("\n\n\n### TinyG RESTORE DEFAULTS Help ###\n"));
+ fprintf_P(stderr, PSTR
+ ("Enter $defa=1 to reset the system to the factory default values.\n"
+ "This will overwrite any changes you have made.\n"));
+ _postscript();
+
+ return STAT_OK;
}
-/*
- * help_boot_loader()
- */
-stat_t help_boot_loader(nvObj_t *nv)
-{
-fprintf_P(stderr, PSTR("\n\n\n### TinyG BOOT LOADER Help ###\n"));
-fprintf_P(stderr, PSTR("\
-Enter $boot=1 to enter the boot loader.\n"));
-_postscript();
-return STAT_OK;
+
+stat_t help_boot_loader(nvObj_t *nv) {
+ fprintf_P(stderr, PSTR("\n\n\n### TinyG BOOT LOADER Help ###\n"));
+ fprintf_P(stderr, PSTR("Enter $boot=1 to enter the boot loader.\n"));
+ _postscript();
+
+ return STAT_OK;
}
#endif // __HELP_SCREENS
#define HELP_H_ONCE
#ifdef __HELP_SCREENS
-
- stat_t help_general(nvObj_t *nv);
- stat_t help_config(nvObj_t *nv);
- stat_t help_test(nvObj_t *nv);
- stat_t help_defa(nvObj_t *nv);
- stat_t help_boot_loader(nvObj_t *nv);
-
+stat_t help_general(nvObj_t *nv);
+stat_t help_config(nvObj_t *nv);
+stat_t help_test(nvObj_t *nv);
+stat_t help_defa(nvObj_t *nv);
+stat_t help_boot_loader(nvObj_t *nv);
#else
-
- stat_t help_stub(nvObj_t *nv);
- #define help_general help_stub
- #define help_config help_stub
- #define help_test help_stub
- #define help_defa help_stub
- #define help_boot_loader help_stub
-
+stat_t help_stub(nvObj_t *nv);
+#define help_general help_stub
+#define help_config help_stub
+#define help_test help_stub
+#define help_defa help_stub
+#define help_boot_loader help_stub
#endif // __HELP_SCREENS
-#endif // End of include guard: HELP_H_ONCE
+#endif // HELP_H_ONCE
#include <avr/interrupt.h>
-/***** PWM defines, structures and memory allocation *****/
pwmSingleton_t pwm;
+
// defines common to all PWM channels
-//#define PWM_TIMER_TYPE TC1_struct // PWM uses TC1's
-#define PWM_TIMER_t TC1_t // PWM uses TC1's
-#define PWM_TIMER_DISABLE 0 // turn timer off (clock = 0 Hz)
-#define PWM_MAX_FREQ (F_CPU/256) // max frequency with 8-bits duty cycle precision
-#define PWM_MIN_FREQ (F_CPU/64/65536) // min frequency with supported prescaling
+#define PWM_TIMER_t TC1_t // PWM uses TC1's
+#define PWM_TIMER_DISABLE 0 // turn timer off (clock = 0 Hz)
+#define PWM_MAX_FREQ (F_CPU / 256) // max frequency with 8-bits duty cycle precision
+#define PWM_MIN_FREQ (F_CPU / 64 / 65536) // min frequency with supported prescaling
+
-// channel specific defines
/* CLKSEL is used to configure default PWM clock operating ranges
* These can be changed by pwm_freq() depending on the PWM frequency selected
*
* The useful ranges (assuming a 32 Mhz system clock) are:
- * TC_CLKSEL_DIV1_gc - good for about 500 Hz to 125 Khz practical upper limit
+ * TC_CLKSEL_DIV1_gc - good for about 500 Hz to 125 Khz practical upper limit
* TC_CLKSEL_DIV2_gc - good for about 250 Hz to 62 KHz
- * TC_CLKSEL_DIV4_gc - good for about 125 Hz to 31 KHz
- * TC_CLKSEL_DIV8_gc - good for about 62 Hz to 16 KHz
- * TC_CLKSEL_DIV64_gc - good for about 8 Hz to 2 Khz
+ * TC_CLKSEL_DIV4_gc - good for about 125 Hz to 31 KHz
+ * TC_CLKSEL_DIV8_gc - good for about 62 Hz to 16 KHz
+ * TC_CLKSEL_DIV64_gc - good for about 8 Hz to 2 Khz
*/
#define PWM1_CTRLA_CLKSEL TC_CLKSEL_DIV1_gc // starting clock select value
-#define PWM1_CTRLB (3 | TC0_CCBEN_bm) // single slope PWM enabled on channel B
-#define PWM1_ISR_vect TCD1_CCB_vect // must match timer assignments in system.h
+#define PWM1_CTRLB (3 | TC0_CCBEN_bm) // single slope PWM enabled on channel B
+#define PWM1_ISR_vect TCD1_CCB_vect // must match timer assignments in system.h
#define PWM1_INTCTRLB 0 // timer interrupt level (0=off, 1=lo, 2=med, 3=hi)
-#define PWM2_CTRLA_CLKSEL TC_CLKSEL_DIV1_gc
-#define PWM2_CTRLB 3 // single slope PWM enabled, no output channel
-//#define PWM2_CTRLB (3 | TC0_CCBEN_bm) // single slope PWM enabled on channel B
+#define PWM2_CTRLA_CLKSEL TC_CLKSEL_DIV1_gc
+#define PWM2_CTRLB 3 // single slope PWM enabled, no output channel
#define PWM2_ISR_vect TCE1_CCB_vect // must match timer assignments in system.h
#define PWM2_INTCTRLB 0 // timer interrupt level (0=off, 1=lo, 2=med, 3=hi)
-/***** PWM code *****/
+
/*
- * pwm_init() - initialize pwm channels
+ * Initialize pwm channels
*
- * Notes:
- * - Whatever level interrupts you use must be enabled in main()
- * - init assumes PWM1 output bit (D5) has been set to output previously (stepper.c)
- * - 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
+ * Notes:
+ * - Whatever level interrupts you use must be enabled in main()
+ * - init assumes PWM1 output bit (D5) has been set to output previously (stepper.c)
+ * - See system.h for timer and port assignments
*/
-void pwm_init()
-{
- gpio_set_bit_off(SPINDLE_PWM);
-
- // setup PWM channel 1
- memset(&pwm.p[PWM_1], 0, sizeof(pwmChannel_t)); // clear parent structure
- pwm.p[PWM_1].timer = &TIMER_PWM1; // bind timer struct to PWM struct array
- pwm.p[PWM_1].ctrla = PWM1_CTRLA_CLKSEL; // initialize starting clock operating range
- pwm.p[PWM_1].timer->CTRLB = PWM1_CTRLB;
- pwm.p[PWM_1].timer->INTCTRLB = PWM1_INTCTRLB; // set interrupt level
-
- // setup PWM channel 2
- memset(&pwm.p[PWM_2], 0, sizeof(pwmChannel_t)); // clear all values, pointers and status
- pwm.p[PWM_2].timer = &TIMER_PWM2;
- pwm.p[PWM_2].ctrla = PWM2_CTRLA_CLKSEL;
- pwm.p[PWM_2].timer->CTRLB = PWM2_CTRLB;
- pwm.p[PWM_2].timer->INTCTRLB = PWM2_INTCTRLB;
+void pwm_init() {
+ gpio_set_bit_off(SPINDLE_PWM);
+
+ // setup PWM channel 1
+ memset(&pwm.p[PWM_1], 0, sizeof(pwmChannel_t)); // clear parent structure
+ pwm.p[PWM_1].timer = &TIMER_PWM1; // bind timer struct to PWM struct array
+ pwm.p[PWM_1].ctrla = PWM1_CTRLA_CLKSEL; // initialize starting clock operating range
+ pwm.p[PWM_1].timer->CTRLB = PWM1_CTRLB;
+ pwm.p[PWM_1].timer->INTCTRLB = PWM1_INTCTRLB; // set interrupt level
+
+ // setup PWM channel 2
+ memset(&pwm.p[PWM_2], 0, sizeof(pwmChannel_t)); // clear all values, pointers and status
+ pwm.p[PWM_2].timer = &TIMER_PWM2;
+ pwm.p[PWM_2].ctrla = PWM2_CTRLA_CLKSEL;
+ pwm.p[PWM_2].timer->CTRLB = PWM2_CTRLB;
+ pwm.p[PWM_2].timer->INTCTRLB = PWM2_INTCTRLB;
}
-/*
- * ISRs for PWM timers
- */
-ISR(PWM1_ISR_vect)
-{
- return;
-}
-ISR(PWM2_ISR_vect)
-{
- return;
-}
+ISR(PWM1_ISR_vect) {}
+
+
+ISR(PWM2_ISR_vect) {}
+
/*
- * pwm_set_freq() - set PWM channel frequency
+ * Set PWM channel frequency
*
- * channel - PWM channel
- * freq - PWM frequency in Khz as a float
+ * @param channel PWM channel
+ * @param freq PWM frequency in Khz as a float
*
* Assumes 32MHz clock.
* Doesn't turn time on until duty cycle is set
*/
-
-stat_t pwm_set_freq(uint8_t chan, float freq)
-{
- if (chan > PWMS) { return STAT_NO_SUCH_DEVICE;}
- if (freq > PWM_MAX_FREQ) { return STAT_INPUT_EXCEEDS_MAX_VALUE;}
- if (freq < PWM_MIN_FREQ) { return STAT_INPUT_LESS_THAN_MIN_VALUE;}
-
- // set the period and the prescaler
- float prescale = F_CPU/65536/freq; // optimal non-integer prescaler value
- if (prescale <= 1) {
- pwm.p[chan].timer->PER = F_CPU/freq;
- pwm.p[chan].timer->CTRLA = TC_CLKSEL_DIV1_gc;
- } else if (prescale <= 2) {
- pwm.p[chan].timer->PER = F_CPU/2/freq;
- pwm.p[chan].timer->CTRLA = TC_CLKSEL_DIV2_gc;
- } else if (prescale <= 4) {
- pwm.p[chan].timer->PER = F_CPU/4/freq;
- pwm.p[chan].timer->CTRLA = TC_CLKSEL_DIV4_gc;
- } else if (prescale <= 8) {
- pwm.p[chan].timer->PER = F_CPU/8/freq;
- pwm.p[chan].timer->CTRLA = TC_CLKSEL_DIV8_gc;
- } else {
- pwm.p[chan].timer->PER = F_CPU/64/freq;
- pwm.p[chan].timer->CTRLA = TC_CLKSEL_DIV64_gc;
- }
-
- return STAT_OK;
+stat_t pwm_set_freq(uint8_t chan, float freq) {
+ if (chan > PWMS) { return STAT_NO_SUCH_DEVICE;}
+ if (freq > PWM_MAX_FREQ) { return STAT_INPUT_EXCEEDS_MAX_VALUE;}
+ if (freq < PWM_MIN_FREQ) { return STAT_INPUT_LESS_THAN_MIN_VALUE;}
+
+ // Set the period and the prescaler
+ float prescale = F_CPU / 65536 / freq; // optimal non-integer prescaler value
+ if (prescale <= 1) {
+ pwm.p[chan].timer->PER = F_CPU / freq;
+ pwm.p[chan].timer->CTRLA = TC_CLKSEL_DIV1_gc;
+
+ } else if (prescale <= 2) {
+ pwm.p[chan].timer->PER = F_CPU / 2 / freq;
+ pwm.p[chan].timer->CTRLA = TC_CLKSEL_DIV2_gc;
+
+ } else if (prescale <= 4) {
+ pwm.p[chan].timer->PER = F_CPU / 4 / freq;
+ pwm.p[chan].timer->CTRLA = TC_CLKSEL_DIV4_gc;
+
+ } else if (prescale <= 8) {
+ pwm.p[chan].timer->PER = F_CPU / 8 / freq;
+ pwm.p[chan].timer->CTRLA = TC_CLKSEL_DIV8_gc;
+
+ } else {
+ pwm.p[chan].timer->PER = F_CPU / 64 / freq;
+ pwm.p[chan].timer->CTRLA = TC_CLKSEL_DIV64_gc;
+ }
+
+ return STAT_OK;
}
+
/*
- * pwm_set_duty() - set PWM channel duty cycle
+ * Set PWM channel duty cycle
*
- * channel - PWM channel
- * duty - PWM duty cycle from 0% to 100%
+ * @param channel PWM channel
+ * @param duty PWM duty cycle from 0% to 100%
*
* Setting duty cycle to 0 disables the PWM channel with output low
* Setting duty cycle to 100 disables the PWM channel with output high
*
* The frequency must have been set previously
*/
+stat_t pwm_set_duty(uint8_t chan, float duty) {
+ if (duty < 0.0) return STAT_INPUT_LESS_THAN_MIN_VALUE;
+ if (duty > 1.0) return STAT_INPUT_EXCEEDS_MAX_VALUE;
-stat_t pwm_set_duty(uint8_t chan, float duty)
-{
- if (duty < 0.0) { return STAT_INPUT_LESS_THAN_MIN_VALUE;}
- if (duty > 1.0) { return STAT_INPUT_EXCEEDS_MAX_VALUE;}
-
-// Ffrq = Fper/(2N(CCA+1))
-// Fpwm = Fper/((N(PER+1))
- float period_scalar = pwm.p[chan].timer->PER;
- pwm.p[chan].timer->CCB = (uint16_t)(period_scalar * duty) + 1;
+ // Ffrq = Fper / 2N(CCA + 1)
+ // Fpwm = Fper / N(PER + 1)
+ float period_scalar = pwm.p[chan].timer->PER;
+ pwm.p[chan].timer->CCB = (uint16_t)(period_scalar * duty) + 1;
- return STAT_OK;
+ return STAT_OK;
}
-/***********************************************************************************
- * CONFIGURATION AND INTERFACE FUNCTIONS
- * Functions to get and set variables from the cfgArray table
- ***********************************************************************************/
-
-// none
-
-
-/***********************************************************************************
- * TEXT MODE SUPPORT
- * Functions to print variables from the cfgArray table
- ***********************************************************************************/
-
#ifdef __TEXT_MODE
-
static const char fmt_p1frq[] PROGMEM = "[p1frq] pwm frequency %15.0f Hz\n";
static const char fmt_p1csl[] PROGMEM = "[p1csl] pwm cw speed lo %15.0f RPM\n";
static const char fmt_p1csh[] PROGMEM = "[p1csh] pwm cw speed hi %15.0f RPM\n";
static const char fmt_p1wph[] PROGMEM = "[p1wph] pwm ccw phase hi%15.3f [0..1]\n";
static const char fmt_p1pof[] PROGMEM = "[p1pof] pwm phase off %15.3f [0..1]\n";
-void pwm_print_p1frq(nvObj_t *nv) { text_print_flt(nv, fmt_p1frq);}
-void pwm_print_p1csl(nvObj_t *nv) { text_print_flt(nv, fmt_p1csl);}
-void pwm_print_p1csh(nvObj_t *nv) { text_print_flt(nv, fmt_p1csh);}
-void pwm_print_p1cpl(nvObj_t *nv) { text_print_flt(nv, fmt_p1cpl);}
-void pwm_print_p1cph(nvObj_t *nv) { text_print_flt(nv, fmt_p1cph);}
-void pwm_print_p1wsl(nvObj_t *nv) { text_print_flt(nv, fmt_p1wsl);}
-void pwm_print_p1wsh(nvObj_t *nv) { text_print_flt(nv, fmt_p1wsh);}
-void pwm_print_p1wpl(nvObj_t *nv) { text_print_flt(nv, fmt_p1wpl);}
-void pwm_print_p1wph(nvObj_t *nv) { text_print_flt(nv, fmt_p1wph);}
-void pwm_print_p1pof(nvObj_t *nv) { text_print_flt(nv, fmt_p1pof);}
-
+void pwm_print_p1frq(nvObj_t *nv) {text_print_flt(nv, fmt_p1frq);}
+void pwm_print_p1csl(nvObj_t *nv) {text_print_flt(nv, fmt_p1csl);}
+void pwm_print_p1csh(nvObj_t *nv) {text_print_flt(nv, fmt_p1csh);}
+void pwm_print_p1cpl(nvObj_t *nv) {text_print_flt(nv, fmt_p1cpl);}
+void pwm_print_p1cph(nvObj_t *nv) {text_print_flt(nv, fmt_p1cph);}
+void pwm_print_p1wsl(nvObj_t *nv) {text_print_flt(nv, fmt_p1wsl);}
+void pwm_print_p1wsh(nvObj_t *nv) {text_print_flt(nv, fmt_p1wsh);}
+void pwm_print_p1wpl(nvObj_t *nv) {text_print_flt(nv, fmt_p1wpl);}
+void pwm_print_p1wph(nvObj_t *nv) {text_print_flt(nv, fmt_p1wph);}
+void pwm_print_p1pof(nvObj_t *nv) {text_print_flt(nv, fmt_p1pof);}
#endif //__TEXT_MODE
#define PWM_H_ONCE
typedef struct pwmConfigChannel {
- float frequency; // base frequency for PWM driver, in Hz
- float cw_speed_lo; // minimum clockwise spindle speed [0..N]
- float cw_speed_hi; // maximum clockwise spindle speed
- float cw_phase_lo; // pwm phase at minimum CW spindle speed, clamped [0..1]
- float cw_phase_hi; // pwm phase at maximum CW spindle speed, clamped [0..1]
- float ccw_speed_lo; // minimum counter-clockwise spindle speed [0..N]
- float ccw_speed_hi; // maximum counter-clockwise spindle speed
- float ccw_phase_lo; // pwm phase at minimum CCW spindle speed, clamped [0..1]
- float ccw_phase_hi; // pwm phase at maximum CCW spindle speed, clamped
- float phase_off; // pwm phase when spindle is disabled
+ float frequency; // base frequency for PWM driver, in Hz
+ float cw_speed_lo; // minimum clockwise spindle speed [0..N]
+ float cw_speed_hi; // maximum clockwise spindle speed
+ float cw_phase_lo; // pwm phase at minimum CW spindle speed, clamped [0..1]
+ float cw_phase_hi; // pwm phase at maximum CW spindle speed, clamped [0..1]
+ float ccw_speed_lo; // minimum counter-clockwise spindle speed [0..N]
+ float ccw_speed_hi; // maximum counter-clockwise spindle speed
+ float ccw_phase_lo; // pwm phase at minimum CCW spindle speed, clamped [0..1]
+ float ccw_phase_hi; // pwm phase at maximum CCW spindle speed, clamped
+ float phase_off; // pwm phase when spindle is disabled
} pwmConfigChannel_t;
+
typedef struct pwmChannel {
- uint8_t ctrla; // byte needed to active CTRLA (it's dynamic - rest are static)
- TC1_t *timer; // assumes TC1 flavor timers used for PWM channels
+ uint8_t ctrla; // byte needed to active CTRLA (it's dynamic - rest are static)
+ TC1_t *timer; // assumes TC1 flavor timers used for PWM channels
} pwmChannel_t;
+
typedef struct pwmSingleton {
- pwmConfigChannel_t c[PWMS]; // array of channel configs
- pwmChannel_t p[PWMS]; // array of PWM channels
+ pwmConfigChannel_t c[PWMS]; // array of channel configs
+ pwmChannel_t p[PWMS]; // array of PWM channels
} pwmSingleton_t;
extern pwmSingleton_t pwm;
-/*** function prototypes ***/
void pwm_init();
stat_t pwm_set_freq(uint8_t channel, float freq);
stat_t pwm_set_duty(uint8_t channel, float duty);
+
#ifdef __TEXT_MODE
- void pwm_print_p1frq(nvObj_t *nv);
- void pwm_print_p1csl(nvObj_t *nv);
- void pwm_print_p1csh(nvObj_t *nv);
- void pwm_print_p1cpl(nvObj_t *nv);
- void pwm_print_p1cph(nvObj_t *nv);
- void pwm_print_p1wsl(nvObj_t *nv);
- void pwm_print_p1wsh(nvObj_t *nv);
- void pwm_print_p1wpl(nvObj_t *nv);
- void pwm_print_p1wph(nvObj_t *nv);
- void pwm_print_p1pof(nvObj_t *nv);
+void pwm_print_p1frq(nvObj_t *nv);
+void pwm_print_p1csl(nvObj_t *nv);
+void pwm_print_p1csh(nvObj_t *nv);
+void pwm_print_p1cpl(nvObj_t *nv);
+void pwm_print_p1cph(nvObj_t *nv);
+void pwm_print_p1wsl(nvObj_t *nv);
+void pwm_print_p1wsh(nvObj_t *nv);
+void pwm_print_p1wpl(nvObj_t *nv);
+void pwm_print_p1wph(nvObj_t *nv);
+void pwm_print_p1pof(nvObj_t *nv);
#else
- #define pwm_print_p1frq tx_print_stub
- #define pwm_print_p1csl tx_print_stub
- #define pwm_print_p1csh tx_print_stub
- #define pwm_print_p1cpl tx_print_stub
- #define pwm_print_p1cph tx_print_stub
- #define pwm_print_p1wsl tx_print_stub
- #define pwm_print_p1wsh tx_print_stub
- #define pwm_print_p1wpl tx_print_stub
- #define pwm_print_p1wph tx_print_stub
- #define pwm_print_p1pof tx_print_stub
+#define pwm_print_p1frq tx_print_stub
+#define pwm_print_p1csl tx_print_stub
+#define pwm_print_p1csh tx_print_stub
+#define pwm_print_p1cpl tx_print_stub
+#define pwm_print_p1cph tx_print_stub
+#define pwm_print_p1wsl tx_print_stub
+#define pwm_print_p1wsh tx_print_stub
+#define pwm_print_p1wpl tx_print_stub
+#define pwm_print_p1wph tx_print_stub
+#define pwm_print_p1pof tx_print_stub
#endif // __TEXT_MODE
-#endif // End of include guard: PWM_H_ONCE
+#endif // PWM_H_ONCE