*.deb
*.zip
/rpi-share
+
+*.elf
+*.hex
- 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.
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:
$(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
--- /dev/null
+# 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/*)
// 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,
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,
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,
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,
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,
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,
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();
#include "hardware.h"
#include "rtc.h"
#include "usart.h"
-#include "huanyang.h"
#include "config.h"
#include "pgmspace.h"
/// Lowest level hardware init
-void hardware_init() {
+void hw_init() {
_init_clock(); // set system clock
rtc_init(); // real time counter
_read_hw_id();
#include <stdint.h>
-void hardware_init();
+void hw_init();
void hw_request_hard_reset();
void hw_reset_handler();
// 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;
// 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
// 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;
// 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;
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__
--- /dev/null
+# 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
--- /dev/null
+/******************************************************************************\
+
+ 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;
+}
#include <stdlib.h>
-int main(int argc, char *argv[]) {
+int main() {
axis_map_motors();
exec_init(); // motion exec
vars_init(); // configuration variables
# 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':