Added site favicon, Fixed problems with offsets and imperial units, Added step-test
authorJoseph Coffland <joseph@cauldrondevelopment.com>
Mon, 12 Mar 2018 05:05:21 +0000 (22:05 -0700)
committerJoseph Coffland <joseph@cauldrondevelopment.com>
Mon, 12 Mar 2018 05:05:21 +0000 (22:05 -0700)
17 files changed:
.gitignore
CHANGELOG.md
src/avr/Makefile
src/avr/Makefile.common [new file with mode: 0644]
src/avr/src/config.h
src/avr/src/drv8711.c
src/avr/src/hardware.c
src/avr/src/hardware.h
src/avr/src/line.c
src/avr/src/main.c
src/avr/src/motor.c
src/avr/src/pins.h
src/avr/step-test/Makefile [new file with mode: 0644]
src/avr/step-test/step-test.c [new file with mode: 0644]
src/avr/test/firmware-test.c
src/py/bbctrl/Mach.py
src/resources/favicon.ico [new file with mode: 0644]

index 36cd8779c0a4e18468f081f463d82963faac4288..9e00f1b2551eb5830aa96aa3dc449da47cfe8ed0 100644 (file)
@@ -16,3 +16,6 @@ __pycache__
 *.deb
 *.zip
 /rpi-share
+
+*.elf
+*.hex
index f5518f277abb97b1a5a61eb008291fa859e5fdf0..8314278b9a2678383310134317005d20371c20e5 100644 (file)
@@ -5,6 +5,9 @@ Buildbotics CNC Controller Firmware Change Log
  - Fixed stopping problems. #127
  - Fixed ``Negative s-curve time`` error.
  - Improved jogging with soft limits.
+ - Added site favicon.
+ - Fixed problems with offsets and imperial units.
+ - Fixed ``All zero s-curve times`` caused by extreemly short, non-zero moves.
 
 ## v0.3.18
  - Don't enable any tool by default.
index d1489dac43f1240ca22ef3a5165b7bbea5514b5f..2c00a07d4abe67a8165b51d530dedb6dac8373ae 100644 (file)
@@ -3,96 +3,26 @@ PROJECT  = bbctrl-avr-firmware
 MCU      = atxmega192a3u
 CLOCK    = 32000000
 
-TARGET  = $(PROJECT).elf
-
-# Compile flags
-CC = avr-g++
-
-COMMON = -mmcu=$(MCU) -flto -fwhole-program
-
-CFLAGS += $(COMMON)
-CFLAGS += -Wall -Werror
-CFLAGS += -Wno-error=strict-aliasing # for _invsqrt
-CFLAGS += -std=gnu++98 -DF_CPU=$(CLOCK)UL -O3
-CFLAGS += -funsigned-bitfields -fpack-struct -fshort-enums -funsigned-char
-CFLAGS += -MD -MP -MT $@ -MF build/dep/$(@F).d
-CFLAGS += -D__STDC_LIMIT_MACROS
-CFLAGS += -Isrc
-
-# Linker flags
-LDFLAGS += $(COMMON) -Wl,-u,vfprintf -lprintf_flt -lm
-LIBS += -lm
-
-# EEPROM flags
-EEFLAGS += -j .eeprom
-EEFLAGS += --set-section-flags=.eeprom="alloc,load"
-EEFLAGS += --change-section-lma .eeprom=0 --no-change-warnings
-
-# Programming flags
-ifndef (PROGRAMMER)
-PROGRAMMER = avrispmkII
-#PROGRAMMER = jtag3pdi
-endif
-PDEV = usb
-AVRDUDE_OPTS = -c $(PROGRAMMER) -p $(MCU) -P $(PDEV)
-
-FUSE0=0xff
-FUSE1=0x00
-FUSE2=0xbe
-FUSE4=0xff
-FUSE5=0xeb
-
 # SRC
 SRC = $(wildcard src/*.c) $(wildcard src/*.cpp)
 OBJ = $(patsubst src/%.cpp,build/%.o,$(patsubst src/%.c,build/%.o,$(SRC)))
 JSON = vars command messages
 JSON := $(patsubst %,build/%.json,$(JSON))
 
-# Build
-all: $(PROJECT).hex $(JSON) size
-
-# JSON
-build/%.json: src/%.json.in src/%.def
-       cpp -Isrc $< | sed "/^#.*$$/d;s/'\(.\)'/\"\1\"/g" > $@
-
-# Compile
-build/%.o: src/%.c
-       @mkdir -p $(shell dirname $@)
-       $(CC) $(INCLUDES) $(CFLAGS) -c -o $@ $<
+include Makefile.common
 
-build/%.o: src/%.cpp
-       @mkdir -p $(shell dirname $@)
-       $(CC) $(INCLUDES) $(CFLAGS) -c -o $@ $<
+CFLAGS += -Isrc
 
-build/%.o: src/%.S
-       @mkdir -p $(shell dirname $@)
-       $(CC) $(INCLUDES) $(CFLAGS) -c -o $@ $<
+# Build
+all: $(PROJECT).hex $(JSON) size
 
-# Link
-$(TARGET): $(OBJ)
+$(PROJECT).elf: $(OBJ)
        $(CC) $(LDFLAGS) $(OBJ) $(LIBS) -o $@
 
-%.hex: %.elf
-       avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature $< $@
-
-%.eep: %.elf
-       avr-objcopy $(EEFLAGS) -O ihex $< $@
 
-%.lss: %.elf
-       avr-objdump -h -S $< > $@
-
-size: $(TARGET)
-       @for X in A B C; do\
-         echo '****************************************************************' ;\
-         avr-size -$$X --mcu=$(MCU) $(TARGET) ;\
-       done
-
-data-usage: $(TARGET)
-       avr-nm -S --size-sort -t decimal $(TARGET) | grep ' [BbDd] '
-
-
-prog-usage: $(TARGET)
-       avr-nm -S --size-sort -t decimal $(TARGET) | grep -v ' [BbDd] '
+# JSON
+build/%.json: src/%.json.in src/%.def
+       cpp -Isrc $< | sed "/^#.*$$/d;s/'\(.\)'/\"\1\"/g" > $@
 
 # Program
 init:
@@ -102,48 +32,7 @@ init:
        $(MAKE) program-boot
        $(MAKE) program
 
-reset:
-       avrdude $(AVRDUDE_OPTS)
-
-erase:
-       avrdude $(AVRDUDE_OPTS) -e
-
-program: $(PROJECT).hex
-       avrdude $(AVRDUDE_OPTS) -U flash:w:$(PROJECT).hex:i
-
-verify: $(PROJECT).hex
-       avrdude $(AVRDUDE_OPTS) -U flash:v:$(PROJECT).hex:i
-
 program-boot:
        $(MAKE) -C ../boot program
 
-fuses:
-       avrdude $(AVRDUDE_OPTS) -U fuse0:w:$(FUSE0):m -U fuse1:w:$(FUSE1):m \
-         -U fuse2:w:$(FUSE2):m -U fuse4:w:$(FUSE4):m -U fuse5:w:$(FUSE5):m
-
-read_fuses:
-       avrdude $(AVRDUDE_OPTS) -q -q -U fuse0:r:-:h -U fuse1:r:-:h -U fuse2:r:-:h \
-         -U fuse4:r:-:h -U fuse5:r:-:h
-
-signature:
-       avrdude $(AVRDUDE_OPTS) -q -q -U signature:r:-:h
-
-prodsig:
-       avrdude $(AVRDUDE_OPTS) -q -q -U prodsig:r:-:h
-
-usersig:
-       avrdude $(AVRDUDE_OPTS) -q -q -U usersig:r:-:h
-
-# Clean
-tidy:
-       rm -f $(shell find -name \*~ -o -name \#\*)
-
-clean: tidy
-       rm -rf $(PROJECT).elf $(PROJECT).hex $(PROJECT).eep $(PROJECT).lss \
-         $(PROJECT).map build
-
-.PHONY: tidy clean size all reset erase program fuses read_fuses prodsig
-.PHONY: signature usersig data-usage prog-usage
-
-# Dependencies
--include $(shell mkdir -p build/dep) $(wildcard build/dep/*)
+.PHONY: all init program-boot
diff --git a/src/avr/Makefile.common b/src/avr/Makefile.common
new file mode 100644 (file)
index 0000000..5810090
--- /dev/null
@@ -0,0 +1,115 @@
+# Compile flags
+CC = avr-g++
+
+COMMON = -mmcu=$(MCU) -flto -fwhole-program
+
+CFLAGS += $(COMMON)
+CFLAGS += -Wall -Werror
+CFLAGS += -Wno-error=strict-aliasing # for _invsqrt
+CFLAGS += -std=gnu++98 -DF_CPU=$(CLOCK)UL -O3
+CFLAGS += -funsigned-bitfields -fpack-struct -fshort-enums -funsigned-char
+CFLAGS += -MD -MP -MT $@ -MF build/dep/$(@F).d
+CFLAGS += -D__STDC_LIMIT_MACROS
+
+# Linker flags
+LDFLAGS += $(COMMON) -Wl,-u,vfprintf -lprintf_flt -lm
+LIBS += -lm
+
+# EEPROM flags
+EEFLAGS += -j .eeprom
+EEFLAGS += --set-section-flags=.eeprom="alloc,load"
+EEFLAGS += --change-section-lma .eeprom=0 --no-change-warnings
+
+# Programming flags
+ifndef (PROGRAMMER)
+PROGRAMMER = avrispmkII
+#PROGRAMMER = jtag3pdi
+endif
+PDEV = usb
+AVRDUDE_OPTS = -c $(PROGRAMMER) -p $(MCU) -P $(PDEV)
+
+FUSE0=0xff
+FUSE1=0x00
+FUSE2=0xbe
+FUSE4=0xff
+FUSE5=0xeb
+
+# Compile
+build/%.o: src/%.c
+       @mkdir -p $(shell dirname $@)
+       $(CC) $(CFLAGS) -c -o $@ $<
+
+build/%.o: src/%.cpp
+       @mkdir -p $(shell dirname $@)
+       $(CC) $(CFLAGS) -c -o $@ $<
+
+build/%.o: src/%.S
+       @mkdir -p $(shell dirname $@)
+       $(CC) $(CFLAGS) -c -o $@ $<
+
+# Link
+%.hex: %.elf
+       avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature $< $@
+
+%.eep: %.elf
+       avr-objcopy $(EEFLAGS) -O ihex $< $@
+
+%.lss: %.elf
+       avr-objdump -h -S $< > $@
+
+size: $(PROJECT).elf
+       @for X in A B C; do\
+         echo '****************************************************************' ;\
+         avr-size -$$X --mcu=$(MCU) $(PROJECT).elf ;\
+       done
+
+data-usage: $(PROJECT).elf
+       avr-nm -S --size-sort -t decimal $(PROJECT).elf | grep ' [BbDd] '
+
+
+prog-usage: $(PROJECT).elf
+       avr-nm -S --size-sort -t decimal $(PROJECT).elf | grep -v ' [BbDd] '
+
+# Program
+reset:
+       avrdude $(AVRDUDE_OPTS)
+
+erase:
+       avrdude $(AVRDUDE_OPTS) -e
+
+program: $(PROJECT).hex
+       avrdude $(AVRDUDE_OPTS) -U flash:w:$(PROJECT).hex:i
+
+verify: $(PROJECT).hex
+       avrdude $(AVRDUDE_OPTS) -U flash:v:$(PROJECT).hex:i
+
+fuses:
+       avrdude $(AVRDUDE_OPTS) -U fuse0:w:$(FUSE0):m -U fuse1:w:$(FUSE1):m \
+         -U fuse2:w:$(FUSE2):m -U fuse4:w:$(FUSE4):m -U fuse5:w:$(FUSE5):m
+
+read_fuses:
+       avrdude $(AVRDUDE_OPTS) -q -q -U fuse0:r:-:h -U fuse1:r:-:h -U fuse2:r:-:h \
+         -U fuse4:r:-:h -U fuse5:r:-:h
+
+signature:
+       avrdude $(AVRDUDE_OPTS) -q -q -U signature:r:-:h
+
+prodsig:
+       avrdude $(AVRDUDE_OPTS) -q -q -U prodsig:r:-:h
+
+usersig:
+       avrdude $(AVRDUDE_OPTS) -q -q -U usersig:r:-:h
+
+# Clean
+tidy:
+       rm -f $(shell find -name \*~ -o -name \#\*)
+
+clean: tidy
+       rm -rf $(PROJECT).elf $(PROJECT).hex $(PROJECT).eep $(PROJECT).lss \
+         $(PROJECT).map build
+
+.PHONY: tidy clean size reset erase program fuses read_fuses prodsig
+.PHONY: signature usersig data-usage prog-usage
+
+# Dependencies
+-include $(shell mkdir -p build/dep) $(wildcard build/dep/*)
index fbee04d35711b6810ace0efe8adfd71cec6e814e..c1c0eba9f13568112061964eefd2c32209aeb4b5 100644 (file)
@@ -36,7 +36,7 @@
 
 // Pins
 enum {
-  STALL_X_PIN = PORT_A << 3,
+  STALL_X_PIN = PIN_ID(PORT_A, 0),
   STALL_Y_PIN,
   STALL_Z_PIN,
   STALL_A_PIN,
@@ -45,7 +45,7 @@ enum {
   ANALOG_1_PIN,
   ANALOG_2_PIN,
 
-  MIN_X_PIN = PORT_B << 3,
+  MIN_X_PIN = PIN_ID(PORT_B, 0),
   MAX_X_PIN,
   MIN_A_PIN,
   MAX_A_PIN,
@@ -54,7 +54,7 @@ enum {
   MIN_Z_PIN,
   MAX_Z_PIN,
 
-  SDA_PIN = PORT_C << 3,
+  SDA_PIN = PIN_ID(PORT_C, 0),
   SCL_PIN,
   SERIAL_RX_PIN,
   SERIAL_TX_PIN,
@@ -63,7 +63,7 @@ enum {
   SPI_MISO_PIN,
   SPI_MOSI_PIN,
 
-  STEP_X_PIN = PORT_D << 3,
+  STEP_X_PIN = PIN_ID(PORT_D, 0),
   SPI_CS_X_PIN,
   SPI_CS_A_PIN,
   SPI_CS_Z_PIN,
@@ -72,7 +72,7 @@ enum {
   RS485_RO_PIN,
   RS485_DI_PIN,
 
-  STEP_Y_PIN = PORT_E << 3,
+  STEP_Y_PIN = PIN_ID(PORT_E, 0),
   SPI_CS_Y_PIN,
   DIR_X_PIN,
   DIR_Y_PIN,
@@ -81,7 +81,7 @@ enum {
   DIR_Z_PIN,
   DIR_A_PIN,
 
-  STEP_Z_PIN = PORT_F << 3,
+  STEP_Z_PIN = PIN_ID(PORT_F, 0),
   RS485_RW_PIN,
   FAULT_PIN,
   ESTOP_PIN,
index 37583d733fff9d910c3af3f47b102e87f5a5c3ff..e05ac519645ae2f22343d678979addfec3f74182 100644 (file)
@@ -359,7 +359,7 @@ void drv8711_init() {
   PR.PRPC &= ~PR_SPI_bm; // Disable power reduction
   SPIC.CTRL = SPI_ENABLE_bm | SPI_MASTER_bm | SPI_MODE_0_gc |
     SPI_PRESCALER_DIV16_gc; // enable, big endian, master, mode, clock div
-  PORT(SPI_CLK_PIN)->REMAP = PORT_SPI_bm; // Swap SCK and MOSI
+  PIN_PORT(SPI_CLK_PIN)->REMAP = PORT_SPI_bm; // Swap SCK and MOSI
   SPIC.INTCTRL = SPI_INTLVL_LO_gc; // interupt level
 
   _init_spi_commands();
index ee81ff7a45d76de74dd2758e3bb463467f132b3a..5528d9bdec919722b57883e03e86aecc862cf49d 100644 (file)
@@ -28,7 +28,6 @@
 #include "hardware.h"
 #include "rtc.h"
 #include "usart.h"
-#include "huanyang.h"
 #include "config.h"
 #include "pgmspace.h"
 
@@ -112,7 +111,7 @@ static void _read_hw_id() {
 
 
 /// Lowest level hardware init
-void hardware_init() {
+void hw_init() {
   _init_clock();                           // set system clock
   rtc_init();                              // real time counter
   _read_hw_id();
index fdda57ef52a38eb7d8cd4a517080f55dd768f92c..e2be012a4f4aaf827d52866aaaa8ee5baef4eb70 100644 (file)
@@ -32,7 +32,7 @@
 #include <stdint.h>
 
 
-void hardware_init();
+void hw_init();
 void hw_request_hard_reset();
 void hw_reset_handler();
 
index 5516e1690c899f9808196dec1eec090223852521..2260f1dad1020336a3f937fc657c66314b84043f 100644 (file)
@@ -215,6 +215,9 @@ static stat_t _line_exec() {
   // Adjust segment time if near a stopping point
   float seg_time = SEGMENT_TIME;
   if (l.stop_section && section_time - l.current_time < SEGMENT_TIME) {
+    // TODO Instead of adjusting seg_time either absorb the next partial segment
+    // or expand it to a full segment so that we only have SEGMENT_TIME length
+    // segments.
     seg_time += section_time - l.current_time;
     l.offset_time += section_time - l.current_time;
     l.current_time = section_time;
index 377952c23aa08d5efd1fc2609e6099cce0531872..5877224ee952d312c21c4eeff1f258271f87d215 100644 (file)
@@ -56,7 +56,7 @@ int main() {
   // Init
   cli();                          // disable interrupts
 
-  hardware_init();                // hardware setup - must be first
+  hw_init();                      // hardware setup - must be first
   outputs_init();                 // output pins
   analog_init();                  // analog input pins
   usart_init();                   // serial port
index 8841d9f80eb185a57f60382a56f93a0c05a62919..b82a583fe9195deea538e0428cb69f5bd4e2e1e1 100644 (file)
@@ -242,6 +242,9 @@ void motor_end_move(int motor) {
   // Stop clock
   m->timer->CTRLA = 0;
 
+  // TODO Wait for pending DMA transfers
+  //while (m->dma->CTRLB & (DMA_CH_CHBUSY_bm | DMA_CH_CHPEND_bm)) continue;
+
   // Get actual step count from DMA channel
   const int24_t half_steps = 0xffff - m->dma->TRFCNT;
 
@@ -327,6 +330,7 @@ void motor_prep_move(int motor, float time, float target) {
 
   // Find the fastest clock rate that will fit the required number of steps.
   // Note, clock toggles step line so we need two clocks per step.
+  // TODO Always use DIV2 clock
   uint24_t seg_clocks = time * F_CPU * 60;
   uint24_t ticks_per_step = seg_clocks / half_steps + 1; // Round up
   if (ticks_per_step < 0xffff) m->timer_clock = TC_CLKSEL_DIV1_gc;
index 49ae19e5929c36683b8fb4e226a70731faafef57..56fc78d100e2f9a2c02c16fb879377a1984dd35b 100644 (file)
 
 enum {PORT_A = 1, PORT_B, PORT_C, PORT_D, PORT_E, PORT_F};
 
-#define PORT(PIN) pin_ports[(PIN >> 3) - 1]
-#define BM(PIN) (1 << (PIN & 7))
+#define PIN_INDEX(PIN) (PIN & 7)
+#define PORT_INDEX(PIN) ((PIN >> 3) - 1)
+
+#define PIN_PORT(PIN) pin_ports[PORT_INDEX(PIN)]
+#define PIN_BM(PIN) (1 << PIN_INDEX(PIN))
+
+#define PIN_ID(PORT, PIN) (PORT << 3 | (PIN & 7))
 
 #ifdef __AVR__
 #include <avr/io.h>
 
 extern PORT_t *pin_ports[];
 
-#define DIRSET_PIN(PIN) PORT(PIN)->DIRSET = BM(PIN)
-#define DIRCLR_PIN(PIN) PORT(PIN)->DIRCLR = BM(PIN)
-#define OUTCLR_PIN(PIN) PORT(PIN)->OUTCLR = BM(PIN)
-#define OUTSET_PIN(PIN) PORT(PIN)->OUTSET = BM(PIN)
-#define OUTTGL_PIN(PIN) PORT(PIN)->OUTTGL = BM(PIN)
-#define OUT_PIN(PIN) (!!(PORT(PIN)->OUT & BM(PIN)))
-#define IN_PIN(PIN) (!!(PORT(PIN)->IN & BM(PIN)))
-#define PINCTRL_PIN(PIN) ((&PORT(PIN)->PIN0CTRL)[PIN & 7])
+#define DIRSET_PIN(PIN) PIN_PORT(PIN)->DIRSET = PIN_BM(PIN)
+#define DIRCLR_PIN(PIN) PIN_PORT(PIN)->DIRCLR = PIN_BM(PIN)
+#define OUTCLR_PIN(PIN) PIN_PORT(PIN)->OUTCLR = PIN_BM(PIN)
+#define OUTSET_PIN(PIN) PIN_PORT(PIN)->OUTSET = PIN_BM(PIN)
+#define OUTTGL_PIN(PIN) PIN_PORT(PIN)->OUTTGL = PIN_BM(PIN)
+#define OUT_PIN(PIN) (!!(PIN_PORT(PIN)->OUT & PIN_BM(PIN)))
+#define IN_PIN(PIN) (!!(PIN_PORT(PIN)->IN & PIN_BM(PIN)))
+#define PINCTRL_PIN(PIN) ((&PIN_PORT(PIN)->PIN0CTRL)[PIN_INDEX(PIN)])
 
 #define SET_PIN(PIN, X) \
   do {if (X) OUTSET_PIN(PIN); else OUTCLR_PIN(PIN);} while (0);
 
+#define PIN_EVSYS_CHMUX(PIN) \
+  (EVSYS_CHMUX_PORTA_PIN0_gc + (8 * PORT_INDEX(PIN)) + PIN_INDEX(PIN))
+
 #endif // __AVR__
diff --git a/src/avr/step-test/Makefile b/src/avr/step-test/Makefile
new file mode 100644 (file)
index 0000000..52f894a
--- /dev/null
@@ -0,0 +1,20 @@
+# Makefile for Bulidbotics step-test
+PROJECT  = step-test
+MCU      = atxmega192a3u
+CLOCK    = 32000000
+
+# SRC
+SRC = usart.c lcd.c pins.c hardware.c
+SRC := $(wildcard *.c) $(patsubst %,../src/%,$(SRC))
+
+include ../Makefile.common
+
+CFLAGS += -I../src -I.
+
+# Build
+all: $(PROJECT).hex size
+
+$(PROJECT).elf: $(SRC)
+       $(CC) $(SRC) $(CFLAGS) $(LDFLAGS) $(LIBS) -o $@
+
+.PHONY: all
diff --git a/src/avr/step-test/step-test.c b/src/avr/step-test/step-test.c
new file mode 100644 (file)
index 0000000..c16dfe1
--- /dev/null
@@ -0,0 +1,157 @@
+/******************************************************************************\
+
+                 This file is part of the Buildbotics firmware.
+
+                   Copyright (c) 2015 - 2018, Buildbotics LLC
+                              All rights reserved.
+
+      This file ("the software") is free software: you can redistribute it
+      and/or modify it under the terms of the GNU General Public License,
+       version 2 as published by the Free Software Foundation. You should
+       have received a copy of the GNU General Public License, version 2
+      along with the software. If not, see <http://www.gnu.org/licenses/>.
+
+      The software 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 software.  If not, see
+                        <http://www.gnu.org/licenses/>.
+
+                 For information regarding this software email:
+                   "Joseph Coffland" <joseph@buildbotics.com>
+
+\******************************************************************************/
+
+#include "config.h"
+#include "hardware.h"
+#include "usart.h"
+#include "lcd.h"
+
+#include <avr/interrupt.h>
+
+#include <stdint.h>
+#include <stdio.h>
+
+
+void rtc_init() {}
+
+
+static struct {
+  uint8_t step_pin;
+  uint8_t dir_pin;
+  TC0_t *timer;
+  volatile int16_t high;
+
+} channel[4] = {
+  {STEP_X_PIN, DIR_X_PIN, &TCC0, 0},
+  {STEP_Y_PIN, DIR_Y_PIN, &TCD0, 0},
+  {STEP_Z_PIN, DIR_Z_PIN, &TCE0, 0},
+  {STEP_A_PIN, DIR_A_PIN, &TCF0, 0},
+};
+
+
+#define EVSYS_CHMUX(CH) (&EVSYS_CH0MUX)[CH]
+#define EVSYS_CHCTRL(CH) (&EVSYS_CH0CTRL)[CH]
+
+
+void channel_overflow(int i) {
+  if (IN_PIN(channel[i].dir_pin)) channel[i].high--;
+  else channel[i].high++;
+}
+
+
+ISR(TCC0_OVF_vect) {channel_overflow(0);}
+ISR(TCD0_OVF_vect) {channel_overflow(1);}
+ISR(TCE0_OVF_vect) {channel_overflow(2);}
+ISR(TCF0_OVF_vect) {channel_overflow(3);}
+
+
+void channel_update_dir(int i) {
+  if (IN_PIN(channel[i].dir_pin)) channel[i].timer->CTRLFSET = TC0_DIR_bm;
+  else channel[i].timer->CTRLFCLR = TC0_DIR_bm;
+}
+
+
+ISR(PORTE_INT0_vect) {
+  for (int i = 0; i < 4; i++) channel_update_dir(i);
+}
+
+
+int32_t channel_read(int i) {
+  while (true) {
+    int32_t x = (int32_t)channel[i].high << 16 | channel[i].timer->CNT;
+    int32_t y = (int32_t)channel[i].high << 16 | channel[i].timer->CNT;
+    if (x == y) return x;
+  }
+}
+
+
+void channel_init(int i) {
+  uint8_t step_pin = channel[i].step_pin;
+  uint8_t dir_pin = channel[i].dir_pin;
+
+  // Configure I/O
+  DIRCLR_PIN(step_pin);
+  DIRCLR_PIN(dir_pin);
+  PINCTRL_PIN(step_pin) = PORT_SRLEN_bm | PORT_ISC_RISING_gc;
+  PINCTRL_PIN(dir_pin)  = PORT_SRLEN_bm | PORT_ISC_BOTHEDGES_gc;
+
+  // Dir change interrupt
+  PIN_PORT(dir_pin)->INTCTRL  |= PORT_INT0LVL_MED_gc;
+  PIN_PORT(dir_pin)->INT0MASK |= PIN_BM(dir_pin);
+
+  // Events
+  EVSYS_CHMUX(i) = PIN_EVSYS_CHMUX(step_pin);
+  EVSYS_CHCTRL(i) = EVSYS_DIGFILT_8SAMPLES_gc;
+
+  // Clock
+  channel[i].timer->CTRLA = TC_CLKSEL_EVCH0_gc + i;
+  channel[i].timer->INTCTRLA = TC_OVFINTLVL_HI_gc;
+
+  // Set initial clock direction
+  channel_update_dir(i);
+}
+
+
+ISR(TCC1_OVF_vect) {
+  printf("%ld,%ld,%ld,%ld\n",
+         channel_read(0), channel_read(1), channel_read(2), channel_read(3));
+}
+
+
+static void _splash(uint8_t addr) {
+  lcd_init(addr);
+  lcd_goto(addr, 5, 1);
+  lcd_pgmstr(addr, PSTR("Step Test"));
+}
+
+
+static void init() {
+  cli();
+
+  hw_init();
+  usart_init();
+  for (int i = 0; i < 4; i++) channel_init(i);
+
+  // Configure clock
+  TCC1.INTCTRLA = TC_OVFINTLVL_LO_gc;
+  TCC1.PER = F_CPU / 256 * 0.01; // 10ms
+  TCC1.CTRLA = TC_CLKSEL_DIV256_gc;
+
+  sei();
+}
+
+
+int main() {
+  init();
+
+  _splash(0x27);
+  _splash(0x3f);
+
+  while (true) continue;
+
+  return 0;
+}
index ae51a31cd1d568a61ab553b32edbe52b0d6d731d..5e5b3a0859e2a39320f440811637596955835cca 100644 (file)
@@ -36,7 +36,7 @@
 #include <stdlib.h>
 
 
-int main(int argc, char *argv[]) {
+int main() {
   axis_map_motors();
   exec_init();                    // motion exec
   vars_init();                    // configuration variables
index 443ad74026328ad211e5edac9f1c2b0fa9dacea9..b162dba57295dab94ae62642c209a7000a75406e 100644 (file)
@@ -115,7 +115,7 @@ class Mach(Comm):
             # Continue after seek hold
             if (self.ctrl.state.get('pr', '') == 'Switch found' and
                 self.planner.is_synchronizing()):
-                self.unpause()
+                self._unpause()
 
             # Continue after stop hold
             if self.ctrl.state.get('pr', '') == 'User stop':
diff --git a/src/resources/favicon.ico b/src/resources/favicon.ico
new file mode 100644 (file)
index 0000000..f71dc1e
Binary files /dev/null and b/src/resources/favicon.ico differ