# Makefile for the project TinyG firmware
PROJECT = tinyg
-MCU = atxmega192a3
+MCU = atxmega192a3u
CLOCK = 32000000
TARGET = $(PROJECT).elf
COMMON = -mmcu=$(MCU)
CFLAGS += $(COMMON)
-CFLAGS += -gdwarf-2 -std=gnu99 -Wall -Werror -DF_CPU=$(CLOCK)UL -Os -funsigned-char
-CFLAGS += -funsigned-bitfields -fpack-struct -fshort-enums
+CFLAGS += -gdwarf-2 -std=gnu99 -Wall -Werror -DF_CPU=$(CLOCK)UL -Os
+CFLAGS += -funsigned-bitfields -fpack-struct -fshort-enums -funsigned-char
CFLAGS += -MD -MP -MT $@ -MF build/dep/$(@F).d
# Linker flags
* largest possible operation - usually the status report.
*/
-/***********************************************************************************
- **** DEFINITIONS AND SETTINGS *****************************************************
- ***********************************************************************************/
+#include <stdint.h>
// Sizing and footprints // chose one based on # of elements in cfgArray
-//typedef uint8_t index_t; // use this if there are < 256 indexed objects
-typedef uint16_t index_t; // use this if there are > 255 indexed objects
+//typedef uint8_t index_t; // use this if there are < 256 indexed objects
+typedef uint16_t index_t; // use this if there are > 255 indexed objects
// defines allocated from stack (not-pre-allocated)
-#define NV_FORMAT_LEN 128 // print formatting string max length
-#define NV_MESSAGE_LEN 128 // sufficient space to contain end-user messages
+#define NV_FORMAT_LEN 128 // print formatting string max length
+#define NV_MESSAGE_LEN 128 // sufficient space to contain end-user messages
// pre-allocated defines (take RAM permanently)
#define NV_SHARED_STRING_LEN 512 // shared string for string values
-#define NV_BODY_LEN 30 // body elements - allow for 1 parent + N children
+#define NV_BODY_LEN 30 // body elements - allow for 1 parent + N children
// (each body element takes about 30 bytes of RAM)
// Stuff you probably don't want to change
-#define GROUP_LEN 3 // max length of group prefix
-#define TOKEN_LEN 5 // 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_MAX_OBJECTS (NV_BODY_LEN-1) // maximum number of objects in a body string
+#define GROUP_LEN 3 // max length of group prefix
+#define TOKEN_LEN 5 // 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_MAX_OBJECTS (NV_BODY_LEN-1) // maximum number of objects in a body string
#define NO_MATCH (index_t)0xFFFF
#define NV_STATUS_REPORT_LEN NV_MAX_OBJECTS // max number of status report elements - see cfgArray
// **** must also line up in cfgArray, se00 - seXX ****
enum tgCommunicationsMode {
- TEXT_MODE = 0, // text command line mode
- JSON_MODE, // strict JSON construction
+ TEXT_MODE = 0, // text command line mode
+ JSON_MODE, // strict JSON construction
JSON_MODE_RELAXED // relaxed JSON construction (future)
};
enum flowControl {
- FLOW_CONTROL_OFF = 0, // flow control disabled
- FLOW_CONTROL_XON, // flow control uses XON/XOFF
+ FLOW_CONTROL_OFF = 0, // flow control disabled
+ FLOW_CONTROL_XON, // flow control uses XON/XOFF
FLOW_CONTROL_RTS // flow control uses RTS/CTS
};
-/*
-enum lineTermination { // REMOVED. Too easy to make the board non-responsive (not a total brick, but close)
- IGNORE_OFF = 0, // accept either CR or LF as termination on RX text line
- IGNORE_CR, // ignore CR on RX
- IGNORE_LF // ignore LF on RX
-};
-*/
-/*
-enum tgCommunicationsSticky {
- NOT_STICKY = 0, // communications mode changes automatically
- STICKY // communications mode does not change
-};
-*/
-
enum valueType { // value typing for config and JSON
TYPE_EMPTY = -1, // value struct is empty (which is not the same as "0")
- TYPE_0 = 0, // value is 'null' (meaning the JSON null value)
- TYPE_BOOL, // value is "true" (1) or "false"(0)
- TYPE_INTEGER, // value is a uint32_t
- TYPE_DATA, // value is blind cast to uint32_t
- TYPE_FLOAT, // value is a floating point number
+ TYPE_0 = 0, // value is 'null' (meaning the JSON null value)
+ TYPE_BOOL, // value is "true" (1) or "false"(0)
+ TYPE_INTEGER, // value is a uint32_t
+ TYPE_DATA, // value is blind cast to uint32_t
+ TYPE_FLOAT, // value is a floating point number
TYPE_STRING, // value is in string field
- TYPE_ARRAY, // value is array element count, values are CSV ASCII in string field
- TYPE_PARENT // object is a parent to a sub-object
+ TYPE_ARRAY, // value is array element count, values are CSV ASCII in string field
+ TYPE_PARENT // object is a parent to a sub-object
};
/**** operations flags and shorthand ****/
#define F_INITIALIZE 0x01 // initialize this item (run set during initialization)
-#define F_PERSIST 0x02 // persist this item when set is run
-#define F_NOSTRIP 0x04 // do not strip the group prefix from the token
-#define F_CONVERT 0x08 // set if unit conversion is required
-
-#define _f0 0x00
-#define _fi (F_INITIALIZE)
-#define _fp (F_PERSIST)
-#define _fn (F_NOSTRIP)
-#define _fc (F_CONVERT)
+#define F_PERSIST 0x02 // persist this item when set is run
+#define F_NOSTRIP 0x04 // do not strip the group prefix from the token
+#define F_CONVERT 0x08 // set if unit conversion is required
+
+#define _f0 0x00
+#define _fi (F_INITIALIZE)
+#define _fp (F_PERSIST)
+#define _fn (F_NOSTRIP)
+#define _fc (F_CONVERT)
#define _fip (F_INITIALIZE | F_PERSIST)
-#define _fipc (F_INITIALIZE | F_PERSIST | F_CONVERT)
-#define _fipn (F_INITIALIZE | F_PERSIST | F_NOSTRIP)
-#define _fipnc (F_INITIALIZE | F_PERSIST | F_NOSTRIP | F_CONVERT)
+#define _fipc (F_INITIALIZE | F_PERSIST | F_CONVERT)
+#define _fipn (F_INITIALIZE | F_PERSIST | F_NOSTRIP)
+#define _fipnc (F_INITIALIZE | F_PERSIST | F_NOSTRIP | F_CONVERT)
/**** Structures ****/
enum cmControllerState { // manages startup lines
CONTROLLER_INITIALIZING = 0, // controller is initializing - not ready for use
- CONTROLLER_NOT_CONNECTED, // controller has not yet detected connection to USB (or other comm channel)
- CONTROLLER_CONNECTED, // controller has connected to USB (or other comm channel)
- CONTROLLER_STARTUP, // controller is running startup messages and lines
+ CONTROLLER_NOT_CONNECTED, // controller has not yet detected connection to comm channel
+ CONTROLLER_CONNECTED, // controller has connected to comm channel
+ CONTROLLER_STARTUP, // controller is running startup messages and lines
CONTROLLER_READY // controller is active and ready for use
};
* HI Dwell timer counter (set in stepper.h)
* LO Segment execution SW interrupt (set in stepper.h)
* MED GPIO1 switch port (set in gpio.h)
- * MED Serial RX for USB & RS-485 (set in usart.c)
- * MED Serial TX for USB & RS-485 (set in usart.c) (* see note)
+ * MED Serial RX (set in usart.c)
+ * MED Serial TX (set in usart.c) (* see note)
* LO Real time clock interrupt (set in xmega_rtc.h)
*
* (*) The TX cannot run at LO level or exception reports and other prints
#ifndef HARDWARE_H_ONCE
#define HARDWARE_H_ONCE
-/*--- Hardware platform enumerations ---*/
-
enum hwPlatform {
HM_PLATFORM_NONE = 0,
-
HW_PLATFORM_TINYG_XMEGA, // TinyG code base on Xmega boards.
- // hwVersion 7 = TinyG v7 and earlier
- // hwVersion 8 = TinyG v8
-
- HW_PLATFORM_G2_DUE, // G2 code base on native Arduino Due
-
- HW_PLATFORM_TINYG_V9 // G2 code base on v9 boards
- // hwVersion 0 = v9c
- // hwVersion 1 = v9d
- // hwVersion 2 = v9f
- // hwVersion 3 = v9h
- // hwVersion 4 = v9i
};
-#define HW_VERSION_TINYGV6 6
-#define HW_VERSION_TINYGV7 7
-#define HW_VERSION_TINYGV8 8
-
-#define HW_VERSION_TINYGV9C 0
-#define HW_VERSION_TINYGV9D 1
-#define HW_VERSION_TINYGV9F 2
-#define HW_VERSION_TINYGV9H 3
-#define HW_VERSION_TINYGV9I 4
+#define HW_VERSION_TINYGV6 6
+#define HW_VERSION_TINYGV7 7
+#define HW_VERSION_TINYGV8 8
#include "config.h" // needed for the stat_t typedef
#include <avr/interrupt.h>
*** These are not all the same, and must line up in multiple places in gpio.h ***
* Sorry if this is confusing - it's a board routing issue
*/
-#define PORT_MOTOR_1 PORTA // motors mapped to ports
+#define PORT_MOTOR_1 PORTA // motors mapped to ports
#define PORT_MOTOR_2 PORTF
-#define PORT_MOTOR_3 PORTE
-#define PORT_MOTOR_4 PORTD
+#define PORT_MOTOR_3 PORTE
+#define PORT_MOTOR_4 PORTD
-#define PORT_SWITCH_X PORTA // Switch axes mapped to ports
-#define PORT_SWITCH_Y PORTD
-#define PORT_SWITCH_Z PORTE
-#define PORT_SWITCH_A PORTF
+#define PORT_SWITCH_X PORTA // Switch axes mapped to ports
+#define PORT_SWITCH_Y PORTD
+#define PORT_SWITCH_Z PORTE
+#define PORT_SWITCH_A PORTF
#define PORT_OUT_V7_X PORTA // v7 mapping - Output bits mapped to ports
-#define PORT_OUT_V7_Y PORTF
+#define PORT_OUT_V7_Y PORTF
#define PORT_OUT_V7_Z PORTD
#define PORT_OUT_V7_A PORTE
#define PORT_OUT_V6_X PORTA // v6 and earlier mapping - Output bits mapped to ports
-#define PORT_OUT_V6_Y PORTF
+#define PORT_OUT_V6_Y PORTF
#define PORT_OUT_V6_Z PORTE
#define PORT_OUT_V6_A PORTD
// These next four must be changed when the PORT_MOTOR_* definitions change!
-#define PORTCFG_VP0MAP_PORT_MOTOR_1_gc PORTCFG_VP0MAP_PORTA_gc
-#define PORTCFG_VP1MAP_PORT_MOTOR_2_gc PORTCFG_VP1MAP_PORTF_gc
-#define PORTCFG_VP2MAP_PORT_MOTOR_3_gc PORTCFG_VP2MAP_PORTE_gc
-#define PORTCFG_VP3MAP_PORT_MOTOR_4_gc PORTCFG_VP3MAP_PORTD_gc
+#define PORTCFG_VP0MAP_PORT_MOTOR_1_gc PORTCFG_VP02MAP_PORTA_gc
+#define PORTCFG_VP1MAP_PORT_MOTOR_2_gc PORTCFG_VP13MAP_PORTF_gc
+#define PORTCFG_VP2MAP_PORT_MOTOR_3_gc PORTCFG_VP02MAP_PORTE_gc
+#define PORTCFG_VP3MAP_PORT_MOTOR_4_gc PORTCFG_VP13MAP_PORTD_gc
-#define PORT_MOTOR_1_VPORT VPORT0
-#define PORT_MOTOR_2_VPORT VPORT1
-#define PORT_MOTOR_3_VPORT VPORT2
-#define PORT_MOTOR_4_VPORT VPORT3
+#define PORT_MOTOR_1_VPORT VPORT0
+#define PORT_MOTOR_2_VPORT VPORT1
+#define PORT_MOTOR_3_VPORT VPORT2
+#define PORT_MOTOR_4_VPORT VPORT3
/*
* Port setup - Stepper / Switch Ports:
- * b0 (out) step (SET is step, CLR is rest)
+ * b0 (out) step (SET is step, CLR is rest)
* b1 (out) direction (CLR = Clockwise)
* b2 (out) motor enable (CLR = Enabled)
* b3 (out) microstep 0
*/
#define MOTOR_PORT_DIR_gm 0x3F // dir settings: lower 6 out, upper 2 in
-enum cfgPortBits { // motor control port bit positions
+enum cfgPortBits { // motor control port bit positions
STEP_BIT_bp = 0, // bit 0
- DIRECTION_BIT_bp, // bit 1
+ DIRECTION_BIT_bp, // bit 1
MOTOR_ENABLE_BIT_bp, // bit 2
- MICROSTEP_BIT_0_bp, // bit 3
- MICROSTEP_BIT_1_bp, // bit 4
- GPIO1_OUT_BIT_bp, // bit 5 (4 gpio1 output bits; 1 from each axis)
- SW_MIN_BIT_bp, // bit 6 (4 input bits for homing/limit switches)
- SW_MAX_BIT_bp // bit 7 (4 input bits for homing/limit switches)
+ MICROSTEP_BIT_0_bp, // bit 3
+ MICROSTEP_BIT_1_bp, // bit 4
+ GPIO1_OUT_BIT_bp, // bit 5 (4 gpio1 output bits; 1 from each axis)
+ SW_MIN_BIT_bp, // bit 6 (4 input bits for homing/limit switches)
+ SW_MAX_BIT_bp // bit 7 (4 input bits for homing/limit switches)
};
-#define STEP_BIT_bm (1<<STEP_BIT_bp)
-#define DIRECTION_BIT_bm (1<<DIRECTION_BIT_bp)
-#define MOTOR_ENABLE_BIT_bm (1<<MOTOR_ENABLE_BIT_bp)
-#define MICROSTEP_BIT_0_bm (1<<MICROSTEP_BIT_0_bp)
-#define MICROSTEP_BIT_1_bm (1<<MICROSTEP_BIT_1_bp)
-#define GPIO1_OUT_BIT_bm (1<<GPIO1_OUT_BIT_bp) // spindle and coolant output bits
-#define SW_MIN_BIT_bm (1<<SW_MIN_BIT_bp) // minimum switch inputs
-#define SW_MAX_BIT_bm (1<<SW_MAX_BIT_bp) // maximum switch inputs
+#define STEP_BIT_bm (1 << STEP_BIT_bp)
+#define DIRECTION_BIT_bm (1 << DIRECTION_BIT_bp)
+#define MOTOR_ENABLE_BIT_bm (1 << MOTOR_ENABLE_BIT_bp)
+#define MICROSTEP_BIT_0_bm (1 << MICROSTEP_BIT_0_bp)
+#define MICROSTEP_BIT_1_bm (1 << MICROSTEP_BIT_1_bp)
+#define GPIO1_OUT_BIT_bm (1 << GPIO1_OUT_BIT_bp) // spindle and coolant output bits
+#define SW_MIN_BIT_bm (1 << SW_MIN_BIT_bp) // minimum switch inputs
+#define SW_MAX_BIT_bm (1 << SW_MAX_BIT_bp) // maximum switch inputs
/* Bit assignments for GPIO1_OUTs for spindle, PWM and coolant */
#define SPINDLE_BIT 0x08 // spindle on/off
#define SPINDLE_DIR 0x04 // spindle direction, 1=CW, 0=CCW
#define SPINDLE_PWM 0x02 // spindle PWMs output bit
-#define MIST_COOLANT_BIT 0x01 // coolant on/off - these are the same due to limited ports
-#define FLOOD_COOLANT_BIT 0x01 // coolant on/off
+#define MIST_COOLANT_BIT 0x01 // coolant on/off - these are the same due to limited ports
+#define FLOOD_COOLANT_BIT 0x01 // coolant on/off
#define SPINDLE_LED 0
#define SPINDLE_DIR_LED 1
/* Timer assignments - see specific modules for details) */
#define TIMER_DDA TCC0 // DDA timer (see stepper.h)
-#define TIMER_DWELL TCD0 // Dwell timer (see stepper.h)
-#define TIMER_LOAD TCE0 // Loader timer (see stepper.h)
-#define TIMER_EXEC TCF0 // Exec timer (see stepper.h)
-#define TIMER_5 TCC1 // unallocated timer
-#define TIMER_PWM1 TCD1 // PWM timer #1 (see pwm.c)
-#define TIMER_PWM2 TCE1 // PWM timer #2 (see pwm.c)
+#define TIMER_DWELL TCD0 // Dwell timer (see stepper.h)
+#define TIMER_LOAD TCE0 // Loader time (see stepper.h)
+#define TIMER_EXEC TCF0 // Exec timer (see stepper.h)
+#define TIMER_TMC2660 TCC1 // TMC2660 timer (see tmc2660.h)
+#define TIMER_PWM1 TCD1 // PWM timer #1 (see pwm.c)
+#define TIMER_PWM2 TCE1 // PWM timer #2 (see pwm.c)
/* Timer setup for stepper and dwells */
-#define FREQUENCY_DDA (float)50000 // DDA frequency in hz.
+#define FREQUENCY_DDA (float)50000 // DDA frequency in hz.
#define FREQUENCY_DWELL (float)10000 // Dwell count frequency in hz.
-#define LOAD_TIMER_PERIOD 100 // cycles you have to shut off SW interrupt
-#define EXEC_TIMER_PERIOD 100 // cycles you have to shut off SW interrupt
-#define EXEC_TIMER_PERIOD_LONG 100 // cycles you have to shut off SW interrupt
+#define LOAD_TIMER_PERIOD 100 // cycles you have to shut off SW interrupt
+#define EXEC_TIMER_PERIOD 100 // cycles you have to shut off SW interrupt
+#define EXEC_TIMER_PERIOD_LONG 100 // cycles you have to shut off SW interrupt
-#define STEP_TIMER_TYPE TC0_struct // stepper subsybstem uses all the TC0's
+#define STEP_TIMER_TYPE TC0_struct // stepper subsybstem uses all the TC0's
#define STEP_TIMER_DISABLE 0 // turn timer off (clock = 0 Hz)
-#define STEP_TIMER_ENABLE 1 // turn timer clock on (F_CPU = 32 Mhz)
-#define STEP_TIMER_WGMODE 0 // normal mode (count to TOP and rollover)
+#define STEP_TIMER_ENABLE 1 // turn timer clock on (F_CPU = 32 Mhz)
+#define STEP_TIMER_WGMODE 0 // normal mode (count to TOP and rollover)
#define LOAD_TIMER_DISABLE 0 // turn load timer off (clock = 0 Hz)
-#define LOAD_TIMER_ENABLE 1 // turn load timer clock on (F_CPU = 32 Mhz)
-#define LOAD_TIMER_WGMODE 0 // normal mode (count to TOP and rollover)
+#define LOAD_TIMER_ENABLE 1 // turn load timer clock on (F_CPU = 32 Mhz)
+#define LOAD_TIMER_WGMODE 0 // normal mode (count to TOP and rollover)
#define EXEC_TIMER_DISABLE 0 // turn exec timer off (clock = 0 Hz)
-#define EXEC_TIMER_ENABLE 1 // turn exec timer clock on (F_CPU = 32 Mhz)
-#define EXEC_TIMER_WGMODE 0 // normal mode (count to TOP and rollover)
+#define EXEC_TIMER_ENABLE 1 // turn exec timer clock on (F_CPU = 32 Mhz)
+#define EXEC_TIMER_WGMODE 0 // normal mode (count to TOP and rollover)
-#define TIMER_DDA_ISR_vect TCC0_OVF_vect // must agree with assignment in system.h
-#define TIMER_DWELL_ISR_vect TCD0_OVF_vect // must agree with assignment in system.h
+#define TIMER_DDA_ISR_vect TCC0_OVF_vect // must agree with assignment in system.h
+#define TIMER_DWELL_ISR_vect TCD0_OVF_vect // must agree with assignment in system.h
#define TIMER_LOAD_ISR_vect TCE0_OVF_vect // must agree with assignment in system.h
#define TIMER_EXEC_ISR_vect TCF0_OVF_vect // must agree with assignment in system.h
-#define TIMER_OVFINTLVL_HI 3 // timer interrupt level (3=hi)
-#define TIMER_OVFINTLVL_MED 2; // timer interrupt level (2=med)
-#define TIMER_OVFINTLVL_LO 1; // timer interrupt level (1=lo)
+#define TIMER_OVFINTLVL_HI 3 // timer interrupt level (3=hi)
+#define TIMER_OVFINTLVL_MED 2 // timer interrupt level (2=med)
+#define TIMER_OVFINTLVL_LO 1 // timer interrupt level (1=lo)
-#define TIMER_DDA_INTLVL TIMER_OVFINTLVL_HI
-#define TIMER_DWELL_INTLVL TIMER_OVFINTLVL_HI
-#define TIMER_LOAD_INTLVL TIMER_OVFINTLVL_HI
-#define TIMER_EXEC_INTLVL TIMER_OVFINTLVL_LO
+#define TIMER_DDA_INTLVL TIMER_OVFINTLVL_HI
+#define TIMER_DWELL_INTLVL TIMER_OVFINTLVL_HI
+#define TIMER_LOAD_INTLVL TIMER_OVFINTLVL_HI
+#define TIMER_EXEC_INTLVL TIMER_OVFINTLVL_LO
/**** Device singleton - global structure to allow iteration through similar devices ****/
typedef struct hmSingleton {
PORT_t *st_port[MOTORS]; // bindings for stepper motor ports (stepper.c)
PORT_t *sw_port[MOTORS]; // bindings for switch ports (GPIO2)
- PORT_t *out_port[MOTORS]; // bindings for output ports (GPIO1)
+ PORT_t *out_port[MOTORS]; // bindings for output ports (GPIO1)
} hwSingleton_t;
hwSingleton_t hw;
-void hardware_init(); // master hardware init
+void hardware_init(); // master hardware init
void hw_request_hard_reset();
void hw_hard_reset();
stat_t hw_hard_reset_handler();
#include "test.h"
#include "pwm.h"
#include "usart.h"
+#include "tmc2660.h"
#include <avr/interrupt.h>
#include "xmega/xmega_interrupts.h"
usart_init(); // serial port
// do these next
+ tmc2660_init(); // motor drivers
stepper_init(); // stepper subsystem
encoder_init(); // virtual encoders
switch_init(); // switches
*/
stat_t rpt_exception(uint8_t status)
{
- if (status != STAT_OK) { // makes it possible to call exception reports w/o checking status value
- if (js.json_syntax == JSON_SYNTAX_RELAXED) {
- printf_P(PSTR("{er:{fb:%0.2f,st:%d,msg:\"%s\"}}\n"),
- TINYG_FIRMWARE_BUILD, status, get_status_message(status));
- } else {
- printf_P(PSTR("{\"er\":{\"fb\":%0.2f,\"st\":%d,\"msg\":\"%s\"}}\n"),
- TINYG_FIRMWARE_BUILD, status, get_status_message(status));
- }
+ if (status != STAT_OK) { // makes it possible to call exception reports w/o checking status value
+ if (js.json_syntax == JSON_SYNTAX_RELAXED) {
+ printf_P(PSTR("{er:{fb:%0.2f,st:%d,msg:\"%s\"}}\n"),
+ TINYG_FIRMWARE_BUILD, status, get_status_message(status));
+ } else {
+ printf_P(PSTR("{\"er\":{\"fb\":%0.2f,\"st\":%d,\"msg\":\"%s\"}}\n"),
+ TINYG_FIRMWARE_BUILD, status, get_status_message(status));
}
- return status; // makes it possible to inline, e.g: return(rpt_exception(status));
+ }
+ return status; // makes it possible to inline, e.g: return(rpt_exception(status));
}
/*
*/
stat_t rpt_er(nvObj_t *nv)
{
- return(rpt_exception(STAT_GENERIC_EXCEPTION_REPORT)); // bogus exception report for testing
+ return(rpt_exception(STAT_GENERIC_EXCEPTION_REPORT)); // bogus exception report for testing
}
/**** Application Messages *********************************************************
void _startup_helper(stat_t status, const char *msg)
{
#ifndef __SUPPRESS_STARTUP_MESSAGES
- js.json_footer_depth = JSON_FOOTER_DEPTH; //++++ temporary until changeover is complete
- nv_reset_nv_list();
- nv_add_object((const char_t *)"fv"); // firmware version
- nv_add_object((const char_t *)"fb"); // firmware build
- nv_add_object((const char_t *)"hp"); // hardware platform
- nv_add_object((const char_t *)"hv"); // hardware version
- nv_add_object((const char_t *)"id"); // hardware ID
- nv_add_string((const char_t *)"msg", pstr2str(msg)); // startup message
- json_print_response(status);
+ js.json_footer_depth = JSON_FOOTER_DEPTH; //++++ temporary until changeover is complete
+ nv_reset_nv_list();
+ nv_add_object((const char_t *)"fv"); // firmware version
+ nv_add_object((const char_t *)"fb"); // firmware build
+ nv_add_object((const char_t *)"hp"); // hardware platform
+ nv_add_object((const char_t *)"hv"); // hardware version
+ nv_add_object((const char_t *)"id"); // hardware ID
+ nv_add_string((const char_t *)"msg", pstr2str(msg)); // startup message
+ json_print_response(status);
#endif
}
void rpt_print_initializing_message()
{
- _startup_helper(STAT_INITIALIZING, PSTR(INIT_MESSAGE));
+ _startup_helper(STAT_INITIALIZING, PSTR(INIT_MESSAGE));
}
void rpt_print_loading_configs_message()
{
- _startup_helper(STAT_INITIALIZING, PSTR("Loading configs from EEPROM"));
+ _startup_helper(STAT_INITIALIZING, PSTR("Loading configs from EEPROM"));
}
void rpt_print_system_ready_message()
{
- _startup_helper(STAT_OK, PSTR("SYSTEM READY"));
- if (cfg.comm_mode == TEXT_MODE)
- text_response(STAT_OK, (char_t *)""); // prompt
+ _startup_helper(STAT_OK, PSTR("SYSTEM READY"));
+ if (cfg.comm_mode == TEXT_MODE)
+ text_response(STAT_OK, (char_t *)""); // prompt
}
/*****************************************************************************
uint8_t _is_stat(nvObj_t *nv)
{
- char_t tok[TOKEN_LEN+1];
+ char_t tok[TOKEN_LEN+1];
- GET_TOKEN_STRING(nv->value, tok);
- if (strcmp(tok, "stat") == 0) { return true;}
- return false;
+ GET_TOKEN_STRING(nv->value, tok);
+ if (strcmp(tok, "stat") == 0) { return true;}
+ return false;
}
/*
*/
void sr_init_status_report()
{
- nvObj_t *nv = nv_reset_nv_list(); // used for status report persistence locations
- sr.status_report_requested = false;
- char_t sr_defaults[NV_STATUS_REPORT_LEN][TOKEN_LEN+1] = { STATUS_REPORT_DEFAULTS }; // see settings.h
- nv->index = nv_get_index((const char_t *)"", (const char_t *)"se00"); // set first SR persistence index
- sr.stat_index = 0;
-
- for (uint8_t i=0; i < NV_STATUS_REPORT_LEN ; i++) {
- if (sr_defaults[i][0] == 0) break; // quit on first blank array entry
- sr.status_report_value[i] = -1234567; // pre-load values with an unlikely number
- nv->value = nv_get_index((const char_t *)"", sr_defaults[i]);// load the index for the SR element
- if (nv->value == NO_MATCH) {
- rpt_exception(STAT_BAD_STATUS_REPORT_SETTING); // trap mis-configured profile settings
- return;
- }
- if (_is_stat(nv) == true)
- sr.stat_index = nv->value; // identify index for 'stat' if status is in the report
- nv_set(nv);
- nv_persist(nv); // conditionally persist - automatic by nv_persist()
- nv->index++; // increment SR NVM index
+ nvObj_t *nv = nv_reset_nv_list(); // used for status report persistence locations
+ sr.status_report_requested = false;
+ char_t sr_defaults[NV_STATUS_REPORT_LEN][TOKEN_LEN+1] = { STATUS_REPORT_DEFAULTS }; // see settings.h
+ nv->index = nv_get_index((const char_t *)"", (const char_t *)"se00"); // set first SR persistence index
+ sr.stat_index = 0;
+
+ for (uint8_t i=0; i < NV_STATUS_REPORT_LEN ; i++) {
+ if (sr_defaults[i][0] == 0) break; // quit on first blank array entry
+ sr.status_report_value[i] = -1234567; // pre-load values with an unlikely number
+ nv->value = nv_get_index((const char_t *)"", sr_defaults[i]);// load the index for the SR element
+ if (nv->value == NO_MATCH) {
+ rpt_exception(STAT_BAD_STATUS_REPORT_SETTING); // trap mis-configured profile settings
+ return;
}
+ if (_is_stat(nv) == true)
+ sr.stat_index = nv->value; // identify index for 'stat' if status is in the report
+ nv_set(nv);
+ nv_persist(nv); // conditionally persist - automatic by nv_persist()
+ nv->index++; // increment SR NVM index
+ }
}
/*
*/
stat_t sr_set_status_report(nvObj_t *nv)
{
- uint8_t elements = 0;
- index_t status_report_list[NV_STATUS_REPORT_LEN];
- memset(status_report_list, 0, sizeof(status_report_list));
- index_t sr_start = nv_get_index((const char_t *)"",(const char_t *)"se00");// set first SR persistence index
-
- for (uint8_t i=0; i<NV_STATUS_REPORT_LEN; i++) {
- if (((nv = nv->nx) == 0) || (nv->valuetype == TYPE_EMPTY)) break;
- if ((nv->valuetype == TYPE_BOOL) && (fp_TRUE(nv->value))) {
- status_report_list[i] = nv->index;
- nv->value = nv->index; // persist the index as the value
- nv->index = sr_start + i; // index of the SR persistence location
- nv_persist(nv);
- elements++;
- } else {
- return STAT_UNRECOGNIZED_NAME;
- }
+ uint8_t elements = 0;
+ index_t status_report_list[NV_STATUS_REPORT_LEN];
+ memset(status_report_list, 0, sizeof(status_report_list));
+ index_t sr_start = nv_get_index((const char_t *)"",(const char_t *)"se00");// set first SR persistence index
+
+ for (uint8_t i=0; i<NV_STATUS_REPORT_LEN; i++) {
+ if (((nv = nv->nx) == 0) || (nv->valuetype == TYPE_EMPTY)) break;
+ if ((nv->valuetype == TYPE_BOOL) && (fp_TRUE(nv->value))) {
+ status_report_list[i] = nv->index;
+ nv->value = nv->index; // persist the index as the value
+ nv->index = sr_start + i; // index of the SR persistence location
+ nv_persist(nv);
+ elements++;
+ } else {
+ return STAT_UNRECOGNIZED_NAME;
}
- if (elements == 0)
- return STAT_INVALID_OR_MALFORMED_COMMAND;
- memcpy(sr.status_report_list, status_report_list, sizeof(status_report_list));
- return(_populate_unfiltered_status_report()); // return current values
+ }
+ if (elements == 0)
+ return STAT_INVALID_OR_MALFORMED_COMMAND;
+ memcpy(sr.status_report_list, status_report_list, sizeof(status_report_list));
+ return(_populate_unfiltered_status_report()); // return current values
}
/*
*/
stat_t sr_request_status_report(uint8_t request_type)
{
- if (request_type == SR_IMMEDIATE_REQUEST) {
- sr.status_report_systick = SysTickTimer_getValue();
- }
- if ((request_type == SR_TIMED_REQUEST) && (sr.status_report_requested == false)) {
- sr.status_report_systick = SysTickTimer_getValue() + sr.status_report_interval;
- }
- sr.status_report_requested = true;
- return STAT_OK;
+ if (request_type == SR_IMMEDIATE_REQUEST) {
+ sr.status_report_systick = SysTickTimer_getValue();
+ }
+ if ((request_type == SR_TIMED_REQUEST) && (sr.status_report_requested == false)) {
+ sr.status_report_systick = SysTickTimer_getValue() + sr.status_report_interval;
+ }
+ sr.status_report_requested = true;
+ return STAT_OK;
}
stat_t sr_status_report_callback() // called by controller dispatcher
{
#ifdef __SUPPRESS_STATUS_REPORTS
- return STAT_NOOP;
+ return STAT_NOOP;
#endif
- if (sr.status_report_verbosity == SR_OFF)
- return STAT_NOOP;
+ if (sr.status_report_verbosity == SR_OFF)
+ return STAT_NOOP;
- if (sr.status_report_requested == false)
- return STAT_NOOP;
+ if (sr.status_report_requested == false)
+ return STAT_NOOP;
- if (SysTickTimer_getValue() < sr.status_report_systick)
- return STAT_NOOP;
+ if (SysTickTimer_getValue() < sr.status_report_systick)
+ return STAT_NOOP;
- sr.status_report_requested = false; // disable reports until requested again
+ sr.status_report_requested = false; // disable reports until requested again
- if (sr.status_report_verbosity == SR_VERBOSE) {
- _populate_unfiltered_status_report();
- } else {
- if (_populate_filtered_status_report() == false) { // no new data
- return STAT_OK;
- }
+ if (sr.status_report_verbosity == SR_VERBOSE) {
+ _populate_unfiltered_status_report();
+ } else {
+ if (_populate_filtered_status_report() == false) { // no new data
+ return STAT_OK;
}
- nv_print_list(STAT_OK, TEXT_INLINE_PAIRS, JSON_OBJECT_FORMAT);
- return STAT_OK;
+ }
+ nv_print_list(STAT_OK, TEXT_INLINE_PAIRS, JSON_OBJECT_FORMAT);
+ return STAT_OK;
}
/*
*/
stat_t sr_run_text_status_report()
{
- _populate_unfiltered_status_report();
- nv_print_list(STAT_OK, TEXT_MULTILINE_FORMATTED, JSON_RESPONSE_FORMAT);
- return STAT_OK;
+ _populate_unfiltered_status_report();
+ nv_print_list(STAT_OK, TEXT_MULTILINE_FORMATTED, JSON_RESPONSE_FORMAT);
+ return STAT_OK;
}
/*
*/
static stat_t _populate_unfiltered_status_report()
{
- const char_t sr_str[] = "sr";
- char_t tmp[TOKEN_LEN+1];
- nvObj_t *nv = nv_reset_nv_list(); // sets *nv to the start of the body
-
- nv->valuetype = TYPE_PARENT; // setup the parent object (no length checking required)
- strcpy(nv->token, sr_str);
- nv->index = nv_get_index((const char_t *)"", sr_str);// set the index - may be needed by calling function
- nv = nv->nx; // no need to check for 0 as list has just been reset
-
- for (uint8_t i=0; i<NV_STATUS_REPORT_LEN; i++) {
- if ((nv->index = sr.status_report_list[i]) == 0) { break;}
- nv_get_nvObj(nv);
-
- strcpy(tmp, nv->group); // flatten out groups - WARNING - you cannot use strncpy here...
- strcat(tmp, nv->token);
- strcpy(nv->token, tmp); //...or here.
-
- if ((nv = nv->nx) == 0)
- return cm_hard_alarm(STAT_BUFFER_FULL_FATAL); // should never be 0 unless SR length exceeds available buffer array
- }
- return STAT_OK;
+ const char_t sr_str[] = "sr";
+ char_t tmp[TOKEN_LEN+1];
+ nvObj_t *nv = nv_reset_nv_list(); // sets *nv to the start of the body
+
+ nv->valuetype = TYPE_PARENT; // setup the parent object (no length checking required)
+ strcpy(nv->token, sr_str);
+ nv->index = nv_get_index((const char_t *)"", sr_str);// set the index - may be needed by calling function
+ nv = nv->nx; // no need to check for 0 as list has just been reset
+
+ for (uint8_t i=0; i<NV_STATUS_REPORT_LEN; i++) {
+ if ((nv->index = sr.status_report_list[i]) == 0) { break;}
+ nv_get_nvObj(nv);
+
+ strcpy(tmp, nv->group); // flatten out groups - WARNING - you cannot use strncpy here...
+ strcat(tmp, nv->token);
+ strcpy(nv->token, tmp); //...or here.
+
+ if ((nv = nv->nx) == 0)
+ return cm_hard_alarm(STAT_BUFFER_FULL_FATAL); // should never be 0 unless SR length exceeds available buffer array
+ }
+ return STAT_OK;
}
/*
*/
static uint8_t _populate_filtered_status_report()
{
- const char_t sr_str[] = "sr";
- uint8_t has_data = false;
- char_t tmp[TOKEN_LEN+1];
- nvObj_t *nv = nv_reset_nv_list(); // sets nv to the start of the body
-
- nv->valuetype = TYPE_PARENT; // setup the parent object (no need to length check the copy)
- strcpy(nv->token, sr_str);
-// nv->index = nv_get_index((const char_t *)"", sr_str);// OMITTED - set the index - may be needed by calling function
- nv = nv->nx; // no need to check for 0 as list has just been reset
-
- for (uint8_t i=0; i<NV_STATUS_REPORT_LEN; i++) {
- if ((nv->index = sr.status_report_list[i]) == 0) { break;}
-
- nv_get_nvObj(nv);
- // do not report values that have not changed...
- // ...except for stat=3 (STOP), which is an exception
- if (fp_EQ(nv->value, sr.status_report_value[i])) {
-// if (nv->index != sr.stat_index) {
-// if (fp_EQ(nv->value, COMBINED_PROGRAM_STOP)) {
- nv->valuetype = TYPE_EMPTY;
- continue;
-// }
-// }
- // report anything that has changed
- } else {
- strcpy(tmp, nv->group); // flatten out groups - WARNING - you cannot use strncpy here...
- strcat(tmp, nv->token);
- strcpy(nv->token, tmp); //...or here.
- sr.status_report_value[i] = nv->value;
- if ((nv = nv->nx) == 0) return false; // should never be 0 unless SR length exceeds available buffer array
- has_data = true;
- }
+ const char_t sr_str[] = "sr";
+ uint8_t has_data = false;
+ char_t tmp[TOKEN_LEN+1];
+ nvObj_t *nv = nv_reset_nv_list(); // sets nv to the start of the body
+
+ nv->valuetype = TYPE_PARENT; // setup the parent object (no need to length check the copy)
+ strcpy(nv->token, sr_str);
+ // nv->index = nv_get_index((const char_t *)"", sr_str);// OMITTED - set the index - may be needed by calling function
+ nv = nv->nx; // no need to check for 0 as list has just been reset
+
+ for (uint8_t i=0; i<NV_STATUS_REPORT_LEN; i++) {
+ if ((nv->index = sr.status_report_list[i]) == 0) { break;}
+
+ nv_get_nvObj(nv);
+ // do not report values that have not changed...
+ // ...except for stat=3 (STOP), which is an exception
+ if (fp_EQ(nv->value, sr.status_report_value[i])) {
+ // if (nv->index != sr.stat_index) {
+ // if (fp_EQ(nv->value, COMBINED_PROGRAM_STOP)) {
+ nv->valuetype = TYPE_EMPTY;
+ continue;
+ // }
+ // }
+ // report anything that has changed
+ } else {
+ strcpy(tmp, nv->group); // flatten out groups - WARNING - you cannot use strncpy here...
+ strcat(tmp, nv->token);
+ strcpy(nv->token, tmp); //...or here.
+ sr.status_report_value[i] = nv->value;
+ if ((nv = nv->nx) == 0) return false; // should never be 0 unless SR length exceeds available buffer array
+ has_data = true;
}
- return has_data;
+ }
+ return has_data;
}
/*
stat_t sr_set_si(nvObj_t *nv)
{
- if (nv->value < STATUS_REPORT_MIN_MS) { nv->value = STATUS_REPORT_MIN_MS;}
- sr.status_report_interval = (uint32_t)nv->value;
- return(STAT_OK);
+ if (nv->value < STATUS_REPORT_MIN_MS) { nv->value = STATUS_REPORT_MIN_MS;}
+ sr.status_report_interval = (uint32_t)nv->value;
+ return(STAT_OK);
}
/*********************
*/
void qr_init_queue_report()
{
- qr.queue_report_requested = false;
- qr.buffers_added = 0;
- qr.buffers_removed = 0;
- qr.init_tick = SysTickTimer_getValue();
+ qr.queue_report_requested = false;
+ qr.buffers_added = 0;
+ qr.buffers_removed = 0;
+ qr.init_tick = SysTickTimer_getValue();
}
/*
*/
void qr_request_queue_report(int8_t buffers)
{
- // get buffer depth and added/removed count
- qr.buffers_available = mp_get_planner_buffers_available();
- if (buffers > 0) {
- qr.buffers_added += buffers;
- } else {
- qr.buffers_removed -= buffers;
- }
-
- // time-throttle requests while generating arcs
- qr.motion_mode = cm_get_motion_mode(ACTIVE_MODEL);
- if ((qr.motion_mode == MOTION_MODE_CW_ARC) || (qr.motion_mode == MOTION_MODE_CCW_ARC)) {
- uint32_t tick = SysTickTimer_getValue();
- if (tick - qr.init_tick < MIN_ARC_QR_INTERVAL) {
- qr.queue_report_requested = false;
- return;
- }
+ // get buffer depth and added/removed count
+ qr.buffers_available = mp_get_planner_buffers_available();
+ if (buffers > 0) {
+ qr.buffers_added += buffers;
+ } else {
+ qr.buffers_removed -= buffers;
+ }
+
+ // time-throttle requests while generating arcs
+ qr.motion_mode = cm_get_motion_mode(ACTIVE_MODEL);
+ if ((qr.motion_mode == MOTION_MODE_CW_ARC) || (qr.motion_mode == MOTION_MODE_CCW_ARC)) {
+ uint32_t tick = SysTickTimer_getValue();
+ if (tick - qr.init_tick < MIN_ARC_QR_INTERVAL) {
+ qr.queue_report_requested = false;
+ return;
}
+ }
- // either return or request a report
- if (qr.queue_report_verbosity != QR_OFF) {
- qr.queue_report_requested = true;
- }
+ // either return or request a report
+ if (qr.queue_report_verbosity != QR_OFF) {
+ qr.queue_report_requested = true;
+ }
}
/*
stat_t qr_queue_report_callback() // called by controller dispatcher
{
#ifdef __SUPPRESS_QUEUE_REPORTS
- return STAT_NOOP;
+ return STAT_NOOP;
#endif
- if (qr.queue_report_verbosity == QR_OFF)
- return STAT_NOOP;
+ if (qr.queue_report_verbosity == QR_OFF)
+ return STAT_NOOP;
- if (qr.queue_report_requested == false)
- return STAT_NOOP;
+ if (qr.queue_report_requested == false)
+ return STAT_NOOP;
- qr.queue_report_requested = false;
+ qr.queue_report_requested = false;
- if (cfg.comm_mode == TEXT_MODE) {
- if (qr.queue_report_verbosity == QR_SINGLE) {
- fprintf(stderr, "qr:%d\n", qr.buffers_available);
- } else {
- fprintf(stderr, "qr:%d, qi:%d, qo:%d\n", qr.buffers_available,qr.buffers_added,qr.buffers_removed);
- }
+ if (cfg.comm_mode == TEXT_MODE) {
+ if (qr.queue_report_verbosity == QR_SINGLE) {
+ fprintf(stderr, "qr:%d\n", qr.buffers_available);
+ } else {
+ fprintf(stderr, "qr:%d, qi:%d, qo:%d\n", qr.buffers_available,qr.buffers_added,qr.buffers_removed);
+ }
- } else if (js.json_syntax == JSON_SYNTAX_RELAXED) {
- if (qr.queue_report_verbosity == QR_SINGLE) {
- fprintf(stderr, "{qr:%d}\n", qr.buffers_available);
- } else {
- fprintf(stderr, "{qr:%d,qi:%d,qo:%d}\n", qr.buffers_available, qr.buffers_added,qr.buffers_removed);
- }
+ } else if (js.json_syntax == JSON_SYNTAX_RELAXED) {
+ if (qr.queue_report_verbosity == QR_SINGLE) {
+ fprintf(stderr, "{qr:%d}\n", qr.buffers_available);
+ } else {
+ fprintf(stderr, "{qr:%d,qi:%d,qo:%d}\n", qr.buffers_available, qr.buffers_added,qr.buffers_removed);
+ }
+ } else {
+ if (qr.queue_report_verbosity == QR_SINGLE) {
+ fprintf(stderr, "{\"qr\":%d}\n", qr.buffers_available);
} else {
- if (qr.queue_report_verbosity == QR_SINGLE) {
- fprintf(stderr, "{\"qr\":%d}\n", qr.buffers_available);
- } else {
- fprintf(stderr, "{\"qr\":%d,\"qi\":%d,\"qo\":%d}\n", qr.buffers_available, qr.buffers_added,qr.buffers_removed);
- }
+ fprintf(stderr, "{\"qr\":%d,\"qi\":%d,\"qo\":%d}\n", qr.buffers_available, qr.buffers_added,qr.buffers_removed);
}
- qr_init_queue_report();
+ }
+ qr_init_queue_report();
- return STAT_OK;
+ return STAT_OK;
}
/*
- * rx_request_rx_report() - request an update on usb serial buffer space available
+ * rx_request_rx_report() - request an update on serial buffer space available
*/
void rx_request_rx_report() {
- rx.rx_report_requested = true;
- rx.space_available = usart_rx_space();
+ rx.rx_report_requested = true;
+ rx.space_available = usart_rx_space();
}
* rx_report_callback() - send rx report if one has been requested
*/
stat_t rx_report_callback() {
- if (!rx.rx_report_requested)
- return STAT_NOOP;
+ if (!rx.rx_report_requested)
+ return STAT_NOOP;
- rx.rx_report_requested = false;
+ rx.rx_report_requested = false;
- fprintf(stderr, "{\"rx\":%d}\n", rx.space_available);
- return STAT_OK;
+ fprintf(stderr, "{\"rx\":%d}\n", rx.space_available);
+ return STAT_OK;
}
* qo_get() - run a queue report - buffers out
*/
stat_t qr_get(nvObj_t *nv) {
- nv->value = (float)mp_get_planner_buffers_available(); // ensure that manually requested QR count is always up to date
- nv->valuetype = TYPE_INTEGER;
- return STAT_OK;
+ nv->value = (float)mp_get_planner_buffers_available(); // ensure that manually requested QR count is always up to date
+ nv->valuetype = TYPE_INTEGER;
+ return STAT_OK;
}
stat_t qi_get(nvObj_t *nv) {
- nv->value = (float)qr.buffers_added;
- nv->valuetype = TYPE_INTEGER;
- qr.buffers_added = 0; // reset it
- return STAT_OK;
+ nv->value = (float)qr.buffers_added;
+ nv->valuetype = TYPE_INTEGER;
+ qr.buffers_added = 0; // reset it
+ return STAT_OK;
}
stat_t qo_get(nvObj_t *nv) {
- nv->value = (float)qr.buffers_removed;
- nv->valuetype = TYPE_INTEGER;
- qr.buffers_removed = 0; // reset it
- return STAT_OK;
+ nv->value = (float)qr.buffers_removed;
+ nv->valuetype = TYPE_INTEGER;
+ qr.buffers_removed = 0; // reset it
+ return STAT_OK;
}
* job_print_job()
*/
stat_t job_populate_job_report() {
- const char_t job_str[] = "job";
- char_t tmp[TOKEN_LEN+1];
- nvObj_t *nv = nv_reset_nv_list(); // sets *nv to the start of the body
+ const char_t job_str[] = "job";
+ char_t tmp[TOKEN_LEN+1];
+ nvObj_t *nv = nv_reset_nv_list(); // sets *nv to the start of the body
- nv->valuetype = TYPE_PARENT; // setup the parent object
- strcpy(nv->token, job_str);
+ nv->valuetype = TYPE_PARENT; // setup the parent object
+ strcpy(nv->token, job_str);
- //nv->index = nv_get_index((const char_t *)"", job_str);// set the index - may be needed by calling function
- nv = nv->nx; // no need to check for 0 as list has just been reset
+ //nv->index = nv_get_index((const char_t *)"", job_str);// set the index - may be needed by calling function
+ nv = nv->nx; // no need to check for 0 as list has just been reset
- index_t job_start = nv_get_index((const char_t *)"",(const char_t *)"job1");// set first job persistence index
- for (uint8_t i=0; i<4; i++) {
+ index_t job_start = nv_get_index((const char_t *)"",(const char_t *)"job1");// set first job persistence index
+ for (uint8_t i=0; i<4; i++) {
- nv->index = job_start + i;
- nv_get_nvObj(nv);
+ nv->index = job_start + i;
+ nv_get_nvObj(nv);
- strcpy(tmp, nv->group); // concatenate groups and tokens - do NOT use strncpy()
- strcat(tmp, nv->token);
- strcpy(nv->token, tmp);
+ strcpy(tmp, nv->group); // concatenate groups and tokens - do NOT use strncpy()
+ strcat(tmp, nv->token);
+ strcpy(nv->token, tmp);
- if ((nv = nv->nx) == 0)
- return STAT_OK; // should never be 0 unless SR length exceeds available buffer array
- }
- return STAT_OK;
+ if ((nv = nv->nx) == 0)
+ return STAT_OK; // should never be 0 unless SR length exceeds available buffer array
+ }
+ return STAT_OK;
}
stat_t job_set_job_report(nvObj_t *nv)
{
- index_t job_start = nv_get_index((const char_t *)"",(const char_t *)"job1");// set first job persistence index
-
- for (uint8_t i=0; i<4; i++) {
- if (((nv = nv->nx) == 0) || (nv->valuetype == TYPE_EMPTY)) { break;}
- if (nv->valuetype == TYPE_INTEGER) {
- cs.job_id[i] = nv->value;
- nv->index = job_start + i; // index of the SR persistence location
- nv_persist(nv);
- } else {
- return STAT_UNSUPPORTED_TYPE;
- }
+ index_t job_start = nv_get_index((const char_t *)"",(const char_t *)"job1");// set first job persistence index
+
+ for (uint8_t i=0; i<4; i++) {
+ if (((nv = nv->nx) == 0) || (nv->valuetype == TYPE_EMPTY)) { break;}
+ if (nv->valuetype == TYPE_INTEGER) {
+ cs.job_id[i] = nv->value;
+ nv->index = job_start + i; // index of the SR persistence location
+ nv_persist(nv);
+ } else {
+ return STAT_UNSUPPORTED_TYPE;
}
- job_populate_job_report(); // return current values
- return STAT_OK;
+ }
+ job_populate_job_report(); // return current values
+ return STAT_OK;
}
uint8_t job_report_callback()
{
- if (cfg.comm_mode == TEXT_MODE) {
- // no-op, job_ids are client app state
- } else if (js.json_syntax == JSON_SYNTAX_RELAXED) {
- fprintf(stderr, "{job:[%lu,%lu,%lu,%lu]}\n", cs.job_id[0], cs.job_id[1], cs.job_id[2], cs.job_id[3] );
- } else {
- fprintf(stderr, "{\"job\":[%lu,%lu,%lu,%lu]}\n", cs.job_id[0], cs.job_id[1], cs.job_id[2], cs.job_id[3] );
- //job_clear_report();
- }
- return STAT_OK;
+ if (cfg.comm_mode == TEXT_MODE) {
+ // no-op, job_ids are client app state
+ } else if (js.json_syntax == JSON_SYNTAX_RELAXED) {
+ fprintf(stderr, "{job:[%lu,%lu,%lu,%lu]}\n", cs.job_id[0], cs.job_id[1], cs.job_id[2], cs.job_id[3] );
+ } else {
+ fprintf(stderr, "{\"job\":[%lu,%lu,%lu,%lu]}\n", cs.job_id[0], cs.job_id[1], cs.job_id[2], cs.job_id[3] );
+ //job_clear_report();
+ }
+ return STAT_OK;
}
stat_t job_get(nvObj_t *nv) { return job_populate_job_report();}
#define MIN_ARC_QR_INTERVAL 200 // minimum interval between QRs during arc generation (in system ticks)
enum srVerbosity { // status report enable and verbosity
- SR_OFF = 0, // no reports
- SR_FILTERED, // reports only values that have changed from the last report
- SR_VERBOSE // reports all values specified
+ SR_OFF = 0, // no reports
+ SR_FILTERED, // reports only values that have changed from the last report
+ SR_VERBOSE // reports all values specified
};
enum cmStatusReportRequest {
- SR_TIMED_REQUEST = 0, // request a status report at next timer interval
- SR_IMMEDIATE_REQUEST // request a status report ASAP
+ SR_TIMED_REQUEST = 0, // request a status report at next timer interval
+ SR_IMMEDIATE_REQUEST // request a status report ASAP
};
enum qrVerbosity { // planner queue enable and verbosity
- QR_OFF = 0, // no response is provided
- QR_SINGLE, // queue depth reported
- QR_TRIPLE // queue depth reported for buffers, buffers added, buffered removed
+ QR_OFF = 0, // no response is provided
+ QR_SINGLE, // queue depth reported
+ QR_TRIPLE // queue depth reported for buffers, buffers added, buffered removed
};
typedef struct srSingleton {
- /*** config values (PUBLIC) ***/
- uint8_t status_report_verbosity;
- uint32_t status_report_interval; // in milliseconds
+ /*** config values (PUBLIC) ***/
+ uint8_t status_report_verbosity;
+ uint32_t status_report_interval; // in milliseconds
- /*** runtime values (PRIVATE) ***/
- uint8_t status_report_requested; // flag that SR has been requested
- uint32_t status_report_systick; // SysTick value for next status report
- index_t stat_index; // table index value for stat - determined during initialization
- index_t status_report_list[NV_STATUS_REPORT_LEN]; // status report elements to report
- float status_report_value[NV_STATUS_REPORT_LEN]; // previous values for filtered reporting
+ /*** runtime values (PRIVATE) ***/
+ uint8_t status_report_requested; // flag that SR has been requested
+ uint32_t status_report_systick; // SysTick value for next status report
+ index_t stat_index; // table index value for stat - determined during initialization
+ index_t status_report_list[NV_STATUS_REPORT_LEN]; // status report elements to report
+ float status_report_value[NV_STATUS_REPORT_LEN]; // previous values for filtered reporting
} srSingleton_t;
typedef struct qrSingleton { // data for queue reports
- /*** config values (PUBLIC) ***/
- uint8_t queue_report_verbosity; // queue reports enabled and verbosity level
+ /*** config values (PUBLIC) ***/
+ uint8_t queue_report_verbosity; // queue reports enabled and verbosity level
- /*** runtime values (PRIVATE) ***/
- uint8_t queue_report_requested; // set to true to request a report
- uint8_t buffers_available; // stored buffer depth passed to by callback
- uint8_t prev_available; // buffers available at last count
- uint16_t buffers_added; // buffers added since last count
- uint16_t buffers_removed; // buffers removed since last report
- uint8_t motion_mode; // used to detect arc movement
- uint32_t init_tick; // time when values were last initialized or cleared
+ /*** runtime values (PRIVATE) ***/
+ uint8_t queue_report_requested; // set to true to request a report
+ uint8_t buffers_available; // stored buffer depth passed to by callback
+ uint8_t prev_available; // buffers available at last count
+ uint16_t buffers_added; // buffers added since last count
+ uint16_t buffers_removed; // buffers removed since last report
+ uint8_t motion_mode; // used to detect arc movement
+ uint32_t init_tick; // time when values were last initialized or cleared
} qrSingleton_t;
typedef struct rxSingleton {
- uint8_t rx_report_requested;
- uint16_t space_available; // space available in usb rx buffer at time of request
+ uint8_t rx_report_requested;
+ uint16_t space_available; // space available in rx buffer at time of request
} rxSingleton_t;
/**** Externs - See report.c for allocation ****/
#ifdef __TEXT_MODE
- void sr_print_sr(nvObj_t *nv);
- void sr_print_si(nvObj_t *nv);
- void sr_print_sv(nvObj_t *nv);
- void qr_print_qv(nvObj_t *nv);
- void qr_print_qr(nvObj_t *nv);
- void qr_print_qi(nvObj_t *nv);
- void qr_print_qo(nvObj_t *nv);
+void sr_print_sr(nvObj_t *nv);
+void sr_print_si(nvObj_t *nv);
+void sr_print_sv(nvObj_t *nv);
+void qr_print_qv(nvObj_t *nv);
+void qr_print_qr(nvObj_t *nv);
+void qr_print_qi(nvObj_t *nv);
+void qr_print_qo(nvObj_t *nv);
#else
- #define sr_print_sr tx_print_stub
- #define sr_print_si tx_print_stub
- #define sr_print_sv tx_print_stub
- #define qr_print_qv tx_print_stub
- #define qr_print_qr tx_print_stub
- #define qr_print_qi tx_print_stub
- #define qr_print_qo tx_print_stub
+#define sr_print_sr tx_print_stub
+#define sr_print_si tx_print_stub
+#define sr_print_sv tx_print_stub
+#define qr_print_qv tx_print_stub
+#define qr_print_qr tx_print_stub
+#define qr_print_qi tx_print_stub
+#define qr_print_qo tx_print_stub
#endif // __TEXT_MODE
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-/* This module provides the low-level stepper drivers and some related functions.
- * See stepper.h for a detailed explanation of this module.
+
+/* This module provides the low-level stepper drivers and some related functions.
+ * See stepper.h for a detailed explanation of this module.
*/
#include "tinyg.h"
* - motor polarity is setup during config_init()
* - high level interrupts must be enabled in main() once all inits are complete
*/
+
/* NOTE: This is the bare code that the Motate timer calls replace.
* NB: requires: #include <component_tc.h>
*
static void _set_motor_steps_per_unit(nvObj_t *nv)
{
uint8_t m = _get_motor(nv);
-// st_cfg.mot[m].units_per_step = (st_cfg.mot[m].travel_rev * st_cfg.mot[m].step_angle) / (360 * st_cfg.mot[m].microsteps); // unused
st_cfg.mot[m].steps_per_unit = (360 * st_cfg.mot[m].microsteps) / (st_cfg.mot[m].travel_rev * st_cfg.mot[m].step_angle);
st_reset();
}
--- /dev/null
+/******************************************************************************\
+
+ This file is part of the TinyG firmware.
+
+ Copyright (c) 2016, Buildbotics LLC
+ All rights reserved.
+
+ The C! library is free software: you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License
+ as published by the Free Software Foundation, either version 2.1 of
+ the License, or (at your option) any later version.
+
+ The C! library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the C! library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+ In addition, BSD licensing may be granted on a case by case basis
+ by written permission from at least one of the copyright holders.
+ You may request written permission by emailing the authors.
+
+ For information regarding this software email:
+ Joseph Coffland
+ joseph@buildbotics.com
+
+\******************************************************************************/
+
+#include "tmc2660.h"
+
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <string.h>
+
+
+typedef enum {
+ TMC2660_STATE_CONFIG,
+ TMC2660_STATE_MONITOR,
+ TMC2660_STATE_RESET,
+} tmc2660_state_t;
+
+typedef enum {
+ SPI_STATE_SELECT,
+ SPI_STATE_WRITE,
+ SPI_STATE_READ,
+} spi_state_t;
+
+typedef struct {
+ uint16_t mstep;
+ uint8_t status;
+ uint32_t regs[5];
+} tmc2660_driver_t;
+
+
+static const uint32_t reg_addrs[] = {
+ TMC2660_DRVCTRL_ADDR,
+ TMC2660_CHOPCONF_ADDR,
+ TMC2660_SMARTEN_ADDR,
+ TMC2660_SGCSCONF_ADDR,
+ TMC2660_DRVCONF_ADDR
+};
+
+
+static volatile tmc2660_state_t state;
+static volatile uint8_t driver;
+static volatile uint8_t reg;
+static tmc2660_driver_t drivers[TMC2660_NUM_DRIVERS];
+
+static volatile spi_state_t spi_state;
+static volatile uint8_t spi_byte;
+static volatile uint32_t spi_out;
+static volatile uint32_t spi_in;
+
+
+static void spi_cs(int driver, int enable) {
+ if (enable)
+ switch (driver) {
+ case 0: TMC2660_SPI_SSX_PORT.OUTCLR = 1 << TMC2660_SPI_SSX_PIN; break;
+ case 1: TMC2660_SPI_SSY_PORT.OUTCLR = 1 << TMC2660_SPI_SSY_PIN; break;
+ case 2: TMC2660_SPI_SSZ_PORT.OUTCLR = 1 << TMC2660_SPI_SSZ_PIN; break;
+ case 3: TMC2660_SPI_SSA_PORT.OUTCLR = 1 << TMC2660_SPI_SSA_PIN; break;
+ case 4: TMC2660_SPI_SSB_PORT.OUTCLR = 1 << TMC2660_SPI_SSB_PIN; break;
+ }
+ else
+ switch (driver) {
+ case 0: TMC2660_SPI_SSX_PORT.OUTSET = 1 << TMC2660_SPI_SSX_PIN; break;
+ case 1: TMC2660_SPI_SSY_PORT.OUTSET = 1 << TMC2660_SPI_SSY_PIN; break;
+ case 2: TMC2660_SPI_SSZ_PORT.OUTSET = 1 << TMC2660_SPI_SSZ_PIN; break;
+ case 3: TMC2660_SPI_SSA_PORT.OUTSET = 1 << TMC2660_SPI_SSA_PIN; break;
+ case 4: TMC2660_SPI_SSB_PORT.OUTSET = 1 << TMC2660_SPI_SSB_PIN; break;
+ }
+}
+
+
+
+static void spi_send() {
+ // Flush any status errors
+ // TODO check errors
+ uint8_t x = SPIC.STATUS;
+ x = x;
+
+ // Read
+ if (!spi_byte) spi_in = 0;
+ else spi_in = spi_in << 8 | SPIC.DATA;
+
+ // Write
+ if (spi_byte < 3)
+ SPIC.DATA = 0xff & (spi_out >> ((2 - spi_byte++) * 8));
+ else spi_byte = 0;
+}
+
+
+void spi_next() {
+ switch (spi_state) {
+ case SPI_STATE_SELECT:
+ // Select driver
+ spi_cs(driver, 1);
+
+ // Next state
+ TMC2660_TIMER.PER = 4;
+ spi_state = SPI_STATE_WRITE;
+ break;
+
+ case SPI_STATE_WRITE:
+ spi_out = reg_addrs[reg] | drivers[driver].regs[reg];
+ spi_send();
+
+ // Next state
+ TMC2660_TIMER.PER = 16;
+ spi_state = SPI_STATE_READ;
+ break;
+
+ case SPI_STATE_READ:
+ // Deselect driver
+ spi_cs(driver, 0);
+
+ // Read response
+ drivers[driver].mstep = (spi_in >> 14) & 0x3ff;
+ drivers[driver].status = spi_in >> 4;
+
+ // Next state
+ spi_state = SPI_STATE_SELECT;
+
+ if (++reg == 5) {
+ reg = 0;
+ if (++driver == TMC2660_NUM_DRIVERS) driver = 0;
+
+ TMC2660_TIMER.PER = 10;
+
+ } else TMC2660_TIMER.PER = 2;
+ break;
+ }
+}
+
+
+ISR(SPIC_INT_vect) {
+ spi_send();
+}
+
+
+ISR(TCC1_OVF_vect) {
+ spi_next();
+}
+
+
+void tmc2660_init() {
+ // Reset state
+ state = TMC2660_STATE_CONFIG;
+ spi_state = SPI_STATE_SELECT;
+ driver = reg = spi_byte = 0;
+ memset(drivers, 0, sizeof(drivers));
+
+ // Configure motors
+ for (int i = 0; i < TMC2660_NUM_DRIVERS; i++) {
+ drivers[i].regs[TMC2660_DRVCTRL] = 0;
+ drivers[i].regs[TMC2660_CHOPCONF] = 0x14557;
+ drivers[i].regs[TMC2660_SMARTEN] = 0x8202;
+ drivers[i].regs[TMC2660_SGCSCONF] = 0x1001f;
+ drivers[i].regs[TMC2660_DRVCONF] = 0x10;
+ }
+
+ // Setup pins
+ TMC2660_SPI_PORT.OUTSET = 1 << 4; // High
+ TMC2660_SPI_PORT.DIRSET = 1 << 4; // Output
+ TMC2660_SPI_PORT.OUTSET = 1 << TMC2660_SPI_SCK_PIN; // High
+ TMC2660_SPI_PORT.DIRSET = 1 << TMC2660_SPI_SCK_PIN; // Output
+ TMC2660_SPI_PORT.DIRCLR = 1 << TMC2660_SPI_MISO_PIN; // Input
+ TMC2660_SPI_PORT.OUTSET = 1 << TMC2660_SPI_MOSI_PIN; // High
+ TMC2660_SPI_PORT.DIRSET = 1 << TMC2660_SPI_MOSI_PIN; // Output
+
+#if TMC2660_NUM_DRIVERS > 0
+ TMC2660_SPI_SSX_PORT.OUTSET = 1 << TMC2660_SPI_SSX_PIN; // High
+ TMC2660_SPI_SSX_PORT.DIRSET = 1 << TMC2660_SPI_SSX_PIN; // Output
+#endif
+#if TMC2660_NUM_DRIVERS > 1
+ TMC2660_SPI_SSY_PORT.OUTSET = 1 << TMC2660_SPI_SSY_PIN; // High
+ TMC2660_SPI_SSY_PORT.DIRSET = 1 << TMC2660_SPI_SSY_PIN; // Output
+#endif
+#if TMC2660_NUM_DRIVERS > 2
+ TMC2660_SPI_SSZ_PORT.OUTSET = 1 << TMC2660_SPI_SSZ_PIN; // High
+ TMC2660_SPI_SSZ_PORT.DIRSET = 1 << TMC2660_SPI_SSZ_PIN; // Output
+#endif
+#if TMC2660_NUM_DRIVERS > 3
+ TMC2660_SPI_SSA_PORT.OUTSET = 1 << TMC2660_SPI_SSA_PIN; // High
+ TMC2660_SPI_SSA_PORT.DIRSET = 1 << TMC2660_SPI_SSA_PIN; // Output
+#endif
+#if TMC2660_NUM_DRIVERS > 4
+ TMC2660_SPI_SSB_PORT.OUTSET = 1 << TMC2660_SPI_SSB_PIN; // High
+ TMC2660_SPI_SSB_PORT.DIRSET = 1 << TMC2660_SPI_SSB_PIN; // Output
+#endif
+
+ // Configure SPI
+ PR.PRPC &= ~PR_SPI_bm; // Disable power reduction
+ SPIC.CTRL = SPI_ENABLE_bm | SPI_DORD_bm | SPI_MASTER_bm | SPI_MODE_3_gc |
+ SPI_PRESCALER_DIV128_gc; // enable, big endian, master, mode 3, clock/128
+ PORTC.REMAP = PORT_SPI_bm; // Swap SCK and MOSI
+ SPIC.INTCTRL = SPI_INTLVL_MED_gc; // interupt level
+
+ // Configure timer
+ PR.PRPC &= ~PR_TC1_bm; // Disable power reduction
+ TMC2660_TIMER.PER = F_CPU / 1024 / 10; // Set timer period
+ TMC2660_TIMER.INTCTRLA = TC_OVFINTLVL_LO_gc; // Low priority overflow int
+ TMC2660_TIMER.CTRLA = TC_CLKSEL_DIV1024_gc; // enable, clock/1024
+}
+
+
+uint8_t tmc2660_status(int driver) {
+ return drivers[driver].status;
+}
+
+
+uint16_t tmc2660_step(int driver) {
+ return drivers[driver].mstep;
+}
--- /dev/null
+/******************************************************************************\
+
+ This file is part of the TinyG firmware.
+
+ Copyright (c) 2016, Buildbotics LLC
+ All rights reserved.
+
+ The C! library is free software: you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License
+ as published by the Free Software Foundation, either version 2.1 of
+ the License, or (at your option) any later version.
+
+ The C! library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the C! library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+ In addition, BSD licensing may be granted on a case by case basis
+ by written permission from at least one of the copyright holders.
+ You may request written permission by emailing the authors.
+
+ For information regarding this software email:
+ Joseph Coffland
+ joseph@buildbotics.com
+
+\******************************************************************************/
+
+#ifndef TMC2660_H
+#define TMC2660_H
+
+#include <stdint.h>
+
+#define TMC2660_SPI_PORT PORTC
+#define TMC2660_SPI_SCK_PIN 5
+#define TMC2660_SPI_MISO_PIN 6
+#define TMC2660_SPI_MOSI_PIN 7
+
+#define TMC2660_SPI_SSX_PORT PORTA
+#define TMC2660_SPI_SSX_PIN 3
+#define TMC2660_SPI_SSY_PORT PORTF
+#define TMC2660_SPI_SSY_PIN 3
+#define TMC2660_SPI_SSZ_PORT PORTE
+#define TMC2660_SPI_SSZ_PIN 3
+#define TMC2660_SPI_SSA_PORT PORTD
+#define TMC2660_SPI_SSA_PIN 3
+#define TMC2660_SPI_SSB_PORT PORTB
+#define TMC2660_SPI_SSB_PIN 3
+
+#define TMC2660_NUM_DRIVERS 4
+
+#define TMC2660_TIMER TCC1
+
+void tmc2660_init();
+uint8_t tmc2660_status(int driver);
+uint16_t tmc2660_step(int driver);
+
+#define TMC2660_DRVCTRL 0
+#define TMC2660_DRVCTRL_ADDR (0UL << 18)
+#define TMC2660_DRVCTRL_PHA (1UL << 17)
+#define TMC2660_DRVCTRL_CA(x) (((int32_t)x & 0xff) << 9)
+#define TMC2660_DRVCTRL_PHB (1UL << 8)
+#define TMC2660_DRVCTRL_CB(x) (((int32_t)x & 0xff) << 0)
+#define TMC2660_DRVCTRL_INTPOL (1UL << 9)
+#define TMC2660_DRVCTRL_DEDGE (1UL << 8)
+#define TMC2660_DRVCTRL_MRES_256 (0UL << 0)
+#define TMC2660_DRVCTRL_MRES_128 (1UL << 0)
+#define TMC2660_DRVCTRL_MRES_64 (2UL << 0)
+#define TMC2660_DRVCTRL_MRES_32 (3UL << 0)
+#define TMC2660_DRVCTRL_MRES_16 (4UL << 0)
+#define TMC2660_DRVCTRL_MRES_8 (5UL << 0)
+#define TMC2660_DRVCTRL_MRES_4 (6UL << 0)
+#define TMC2660_DRVCTRL_MRES_2 (7UL << 0)
+#define TMC2660_DRVCTRL_MRES_1 (8UL << 0)
+
+#define TMC2660_CHOPCONF 1
+#define TMC2660_CHOPCONF_ADDR (4UL << 17)
+#define TMC2660_CHOPCONF_TBL_16 (0UL << 15)
+#define TMC2660_CHOPCONF_TBL_24 (1UL << 15)
+#define TMC2660_CHOPCONF_TBL_36 (2UL << 15)
+#define TMC2660_CHOPCONF_TBL_54 (3UL << 15)
+#define TMC2660_CHOPCONF_CHM (1UL << 14)
+#define TMC2660_CHOPCONF_RNDTF (1UL << 13)
+#define TMC2660_CHOPCONF_FDM_COMP (0UL << 12)
+#define TMC2660_CHOPCONF_FDM_TIMER (1UL << 12)
+#define TMC2660_CHOPCONF_HDEC_16 (0UL << 11)
+#define TMC2660_CHOPCONF_HDEC_32 (1UL << 11)
+#define TMC2660_CHOPCONF_HDEC_48 (2UL << 11)
+#define TMC2660_CHOPCONF_HDEC_64 (3UL << 11)
+#define TMC2660_CHOPCONF_HEND(x) ((((int32_t)x + 3) & 0xf) << 7)
+#define TMC2660_CHOPCONF_SWO(x) ((((int32_t)x + 3) & 0xf) << 7)
+#define TMC2660_CHOPCONF_HSTART(x) ((((int32_t)x - 1) & 7) << 4)
+#define TMC2660_CHOPCONF_FASTD(x) ((((int32_t)x & 8) << 11) | (x & 7) << 4))
+#define TMC2660_CHOPCONF_TOFF_TBL (1 << 0)
+#define TMC2660_CHOPCONF_TOFF(x) (((int32_t)x & 0xf) << 0)
+
+#define TMC2660_SMARTEN 2
+#define TMC2660_SMARTEN_ADDR (5UL << 17)
+#define TMC2660_SMARTEN_SEIMIN (1UL << 15)
+#define TMC2660_SMARTEN_SEDN_32 (0UL << 13)
+#define TMC2660_SMARTEN_SEDN_8 (1UL << 13)
+#define TMC2660_SMARTEN_SEDN_2 (2UL << 13)
+#define TMC2660_SMARTEN_SEDN_1 (3UL << 13)
+#define TMC2660_SMARTEN_MAX(x) ((x & 0xf) << 8)
+#define TMC2660_SMARTEN_SEUP_1 (0UL << 5)
+#define TMC2660_SMARTEN_SEUP_2 (1UL << 5)
+#define TMC2660_SMARTEN_SEUP_4 (2UL << 5)
+#define TMC2660_SMARTEN_SEUP_8 (3UL << 5)
+#define TMC2660_SMARTEN_MIN(x) (((int32_t)x & 0xf) << 0)
+
+#define TMC2660_SGCSCONF 3
+#define TMC2660_SGCSCONF_ADDR (6UL << 17)
+#define TMC2660_SGCSCONF_SFILT (1UL << 17)
+#define TMC2660_SGCSCONF_THRESH(x) (((int32_t)x & 0x7f) << 8)
+#define TMC2660_SGCSCONF_CS(x) (((int32_t)x & 0x1f) << 0)
+#define TMC2660_SGCSCONF_CS_NONE (31UL << 0)
+
+#define TMC2660_DRVCONF 4
+#define TMC2660_DRVCONF_ADDR (7UL << 17)
+#define TMC2660_DRVCONF_TST (1UL << 16)
+#define TMC2660_DRVCONF_SLPH_MIN (0UL << 14)
+#define TMC2660_DRVCONF_SLPH_MIN_TC (1UL << 14)
+#define TMC2660_DRVCONF_SLPH_MED_TC (2UL << 14)
+#define TMC2660_DRVCONF_SLPH_MAX (3UL << 14)
+#define TMC2660_DRVCONF_SLPL_MIN (0UL << 12)
+#define TMC2660_DRVCONF_SLPL_MED (2UL << 12)
+#define TMC2660_DRVCONF_SLPL_MAX (3UL << 12)
+#define TMC2660_DRVCONF_DISS2G (1UL << 10)
+#define TMC2660_DRVCONF_TS2G_3_2 (0UL << 8)
+#define TMC2660_DRVCONF_TS2G_1_6 (1UL << 8)
+#define TMC2660_DRVCONF_TS2G_1_2 (2UL << 8)
+#define TMC2660_DRVCONF_TS2G_0_8 (3UL << 8)
+#define TMC2660_DRVCONF_SDOFF (1UL << 7)
+#define TMC2660_DRVCONF_VSENSE (1UL << 6)
+#define TMC2660_DRVCONF_RDSEL_MSTEP (0UL << 4)
+#define TMC2660_DRVCONF_RDSEL_SG (1UL << 4)
+#define TMC2660_DRVCONF_RDSEL_SGCS (2UL << 4)
+
+#define TMC2660_DRVSTATUS_STST (1UL << 7)
+#define TMC2660_DRVSTATUS_OLB (1UL << 6)
+#define TMC2660_DRVSTATUS_OLA (1UL << 5)
+#define TMC2660_DRVSTATUS_S2GB (1UL << 4)
+#define TMC2660_DRVSTATUS_S2GA (1UL << 3)
+#define TMC2660_DRVSTATUS_OTPW (1UL << 2)
+#define TMC2660_DRVSTATUS_OT (1UL << 1)
+#define TMC2660_DRVSTATUS_SG (1UL << 0)
+
+#endif // TMC2660_H
This file is part of the TinyG firmware.
- Copyright (c) 2015, Buildbotics LLC
+ Copyright (c) 2015-2016, Buildbotics LLC
All rights reserved.
The C! library is free software: you can redistribute it and/or
USARTC0.CTRLA = USART_RXCINTLVL_HI_gc;
USARTC0.CTRLB = USART_RXEN_bm | USART_TXEN_bm | USART_CLK2X_bm;
- PMIC.CTRL |= PMIC_HILVLEN_bm; // Lowlevel interrupt on
+ PMIC.CTRL |= PMIC_HILVLEN_bm; // Interrupt level on
// Connect IO
stdout = &_stdout;
This file is part of the TinyG firmware.
- Copyright (c) 2015, Buildbotics LLC
+ Copyright (c) 2015-2016, Buildbotics LLC
All rights reserved.
The C! library is free software: you can redistribute it and/or