Bug fixes for timers, added some wdt support for limit debounce.

- Typo in timer def,
- Handle 8 bit timers correctly,
- Don't skip TOP count in CTC mode
- added SREG for atomic bit operations
This commit is contained in:
ashelly 2014-07-10 13:01:03 -04:00
parent 23ed7b6d4b
commit 9b37637ae6
7 changed files with 198 additions and 138 deletions

View File

@ -179,7 +179,7 @@
// NOTE: Uncomment to enable. The recommended delay must be > 3us, and, when added with the // NOTE: Uncomment to enable. The recommended delay must be > 3us, and, when added with the
// user-supplied step pulse time, the total time must not exceed 127us. Reported successful // user-supplied step pulse time, the total time must not exceed 127us. Reported successful
// values for certain setups have ranged from 5 to 20us. // values for certain setups have ranged from 5 to 20us.
// #define STEP_PULSE_DELAY 10 // Step pulse delay in microseconds. Default disabled. #define STEP_PULSE_DELAY 10 // Step pulse delay in microseconds. Default disabled.
// The number of linear motions in the planner buffer to be planned at any give time. The vast // The number of linear motions in the planner buffer to be planned at any give time. The vast
// majority of RAM that Grbl uses is based on this buffer size. Only increase if there is extra // majority of RAM that Grbl uses is based on this buffer size. Only increase if there is extra
@ -232,7 +232,7 @@
// electrical interference on the signal cables from external sources. It's recommended to first // electrical interference on the signal cables from external sources. It's recommended to first
// use shielded signal cables with their shielding connected to ground (old USB/computer cables // use shielded signal cables with their shielding connected to ground (old USB/computer cables
// work well and are cheap to find) and wire in a low-pass circuit into each limit pin. // work well and are cheap to find) and wire in a low-pass circuit into each limit pin.
// #define ENABLE_SOFTWARE_DEBOUNCE // Default disabled. Uncomment to enable. #define ENABLE_SOFTWARE_DEBOUNCE // Default disabled. Uncomment to enable.
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------

View File

@ -15,7 +15,8 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with Grbl. If not, see <http://www.gnu.org/licenses/>. # along with Grbl. If not, see <http://www.gnu.org/licenses/>.
PLATFORM = WINDOWS # PLATFORM = WINDOWS
PLATFORM = LINUX
OBJECTS = main.o simulator.o serial.o ../main.o ../protocol.o ../planner.o ../settings.o ../print.o ../nuts_bolts.o eeprom.o ../serial.o avr/pgmspace.o avr/interrupt.o avr/io.o util/delay.o util/floatunsisf.o ../stepper.o ../gcode.o ../spindle_control.o ../motion_control.o ../limits.o ../report.o ../coolant_control.o ../probe.o ../system.o platform_$(PLATFORM).o OBJECTS = main.o simulator.o serial.o ../main.o ../protocol.o ../planner.o ../settings.o ../print.o ../nuts_bolts.o eeprom.o ../serial.o avr/pgmspace.o avr/interrupt.o avr/io.o util/delay.o util/floatunsisf.o ../stepper.o ../gcode.o ../spindle_control.o ../motion_control.o ../limits.o ../report.o ../coolant_control.o ../probe.o ../system.o platform_$(PLATFORM).o
CLOCK = 16000000 CLOCK = 16000000

View File

@ -22,12 +22,14 @@
#include "interrupt.h" #include "interrupt.h"
#include "io.h" #include "io.h"
#include "wdt.h"
//pseudo-Interrupt vector table //pseudo-Interrupt vector table
isr_fp compa_vect[6]={0}; isr_fp compa_vect[6]={0};
isr_fp compb_vect[6]={0}; isr_fp compb_vect[6]={0};
isr_fp ovf_vect[6]={0}; isr_fp ovf_vect[6]={0};
isr_fp wdt_vect = 0;
isr_fp pc_vect = 0;
void sei() {io.sreg|=SEI;} void sei() {io.sreg|=SEI;}
void cli() {io.sreg&=~SEI;} void cli() {io.sreg&=~SEI;}
@ -45,9 +47,20 @@ enum sim_wgm_mode {
wgm_RESERVED wgm_RESERVED
}; };
enum sim_wgm_mode sim_wgm0[4] = {wgm_NORMAL,wgm_PHASE_PWM,wgm_CTC,wgm_FAST_PWM}; //3-bit wgm table for 8-bit timers
enum sim_wgm_mode sim_wgmN[8] = {wgm_NORMAL,wgm_PHASE_PWM,wgm_PHASE_PWM,wgm_PH_F_PWM, enum sim_wgm_mode sim_wgm_3[] = {wgm_NORMAL,wgm_PHASE_PWM,wgm_CTC,wgm_FAST_PWM,
wgm_CTC, wgm_FAST_PWM, wgm_FAST_PWM, wgm_FAST_PWM}; wgm_RESERVED,wgm_PHASE_PWM, wgm_RESERVED, wgm_FAST_PWM};
//4-bit wgm modes for 16-bit timers
enum sim_wgm_mode sim_wgm_4[16] = {wgm_NORMAL,wgm_PHASE_PWM,wgm_PHASE_PWM,wgm_PHASE_PWM,
wgm_CTC, wgm_FAST_PWM, wgm_FAST_PWM, wgm_FAST_PWM,
wgm_PH_F_PWM, wgm_PH_F_PWM, wgm_PHASE_PWM, wgm_PHASE_PWM,
wgm_CTC, wgm_RESERVED, wgm_FAST_PWM, wgm_FAST_PWM};
static const uint16_t timer_bitdepth[SIM_N_TIMERS] = {
0xFF,0xFFFF,0xFF,
//0xFFFF,0xFFFF,0xFFFF 3 more for mega
};
void timer_interrupts() { void timer_interrupts() {
int i; int i;
@ -55,45 +68,54 @@ void timer_interrupts() {
io.prescaler++; io.prescaler++;
//all clocks //all clocks
for (i=0;i<2;i++){ for (i=0;i<SIM_N_TIMERS;i++){
uint8_t cs = io.tccrb[i]&7; //clock select bits uint8_t cs = io.tccrb[i]&7; //clock select bits
int16_t increment = sim_scaling[cs]; int16_t increment = sim_scaling[cs];
uint16_t bitmask = timer_bitdepth[i];
//check scaling to see if timer fires //check scaling to see if timer fires
if (increment && (io.prescaler&(increment-1))==0) { if (increment && (io.prescaler&(increment-1))==0) {
//select waveform generation mode //select waveform generation mode
enum sim_wgm_mode mode; enum sim_wgm_mode mode;
if (i==0 || i==2) { //(T0 and T2 are different from rest) if (i==0 || i==2) { //(T0 and T2 use only 3 wgm bits)
uint8_t wgm = io.tccra[i]&3; //look at low 2 bits uint8_t wgm = ((io.tccrb[i]&0x08)>>1) | (io.tccra[i]&3);
mode = sim_wgm0[wgm]; mode = sim_wgm_3[wgm];
} }
else { else {
uint8_t wgm = ((io.tccrb[i]&8)>>1) | (io.tccra[i]&3); //only using 3 bits for now uint8_t wgm = ((io.tccrb[i]&0x18)>>1) | (io.tccra[i]&3); //4 wgm bits
mode = sim_wgmN[wgm]; mode = sim_wgm_4[wgm];
} }
//tick //tick
if (io.tifr[i]&(1<<SIM_ROLL)) { //handle CTC mode rollover
io.tcnt[i]=0;
io.tifr[i]&=~(1<<SIM_ROLL);
}
else {
io.tcnt[i]++; io.tcnt[i]++;
//comparators }
if ((io.timsk[i]&(1<<SIM_OCA)) && io.tcnt[i]==io.ocra[i]) io.tifr[i]|=(1<<SIM_OCA); io.tcnt[i]&=bitmask; //limit the 8 bit timers
if ((io.timsk[i]&(1<<SIM_OCB)) && io.tcnt[i]==io.ocrb[i]) io.tifr[i]|=(1<<SIM_OCB);
if ((io.timsk[i]&(1<<SIM_OCC)) && io.tcnt[i]==io.ocrc[i]) io.tifr[i]|=(1<<SIM_OCC);
switch (mode) { switch (mode) {
case wgm_NORMAL: //Normal mode case wgm_NORMAL: //Normal mode, ovf on rollover
if (i==0) io.tcnt[i]&=0xFF; //timer0 is 8 bit; if (io.tcnt[i]==0) io.tifr[i]|=(1<<SIM_TOV); //overflow
if (i==2) io.tcnt[i]&=0xFF; //timer2 is 8 bit;
if (io.tcnt[i]==0) io.tifr[i]|=(1<<SIM_TOV);
break; break;
case wgm_CTC: //CTC mode case wgm_CTC: //CTC mode, ovf at TOP, 0 next tick
if (io.tcnt[i]==io.ocra[i]) io.tcnt[i]=0; if (io.tcnt[i]==(io.ocra[i]&bitmask)) {
io.tifr[i]|=(1<<SIM_TOV)|(1<<SIM_ROLL); //overflow
}
break; break;
default: //unsupported default: //unsupported
break; break;
} }
//comparators
if ((io.timsk[i]&(1<<SIM_OCA)) && io.tcnt[i]==(io.ocra[i]&bitmask)) io.tifr[i]|=(1<<SIM_OCA);
if ((io.timsk[i]&(1<<SIM_OCB)) && io.tcnt[i]==(io.ocrb[i]&bitmask)) io.tifr[i]|=(1<<SIM_OCB);
if ((io.timsk[i]&(1<<SIM_OCC)) && io.tcnt[i]==(io.ocrc[i]&bitmask)) io.tifr[i]|=(1<<SIM_OCC);
//call any triggered interupts //call any triggered interupts
if (ien && io.tifr[i]) { if (ien && io.tifr[i]) {
if (compa_vect[i] && (io.tifr[i]&(1<<SIM_OCA))) { if (compa_vect[i] && (io.tifr[i]&(1<<SIM_OCA))) {
@ -130,6 +152,3 @@ void timer_interrupts() {
} }

View File

@ -28,12 +28,14 @@
//#define TIMER1_COMPA_vect //#define TIMER1_COMPA_vect
#define ISR(a) void interrupt_ ## a () #define ISR(a) void interrupt_ ## a ()
// Stub of the timer interrupt functions we need // Stubs of the hardware interrupt functions we are using
void interrupt_TIMER0_COMPA_vect(); void interrupt_TIMER0_COMPA_vect();
void interrupt_TIMER1_COMPA_vect(); void interrupt_TIMER1_COMPA_vect();
void interrupt_TIMER0_OVF_vect(); void interrupt_TIMER0_OVF_vect();
void interrupt_SERIAL_UDRE(); void interrupt_SERIAL_UDRE();
void interrupt_SERIAL_RX(); void interrupt_SERIAL_RX();
void interrupt_LIMIT_INT_vect();
void interrupt_WDT_vect();
//pseudo-Interrupt vector table //pseudo-Interrupt vector table
@ -41,7 +43,8 @@ typedef void(*isr_fp)(void);
extern isr_fp compa_vect[6]; extern isr_fp compa_vect[6];
extern isr_fp compb_vect[6]; extern isr_fp compb_vect[6];
extern isr_fp ovf_vect[6]; extern isr_fp ovf_vect[6];
extern isr_fp wdt_vect;
extern isr_fp pc_vect; //pin change
// enable interrupts now does something in the simulation environment // enable interrupts now does something in the simulation environment
#define SEI 0x80 #define SEI 0x80
@ -52,5 +55,4 @@ void cli();
void timer_interrupts(); void timer_interrupts();
#endif #endif

View File

@ -4,7 +4,7 @@
Part of Grbl Simulator Part of Grbl Simulator
Copyright (c) 2012 Jens Geisler Copyright (c) 2012-2104 Jens Geisler, Adam Shelly
Grbl is free software: you can redistribute it and/or modify Grbl is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -40,7 +40,7 @@ enum {
SIM_PORT_COUNT SIM_PORT_COUNT
}; };
#define SIM_N_TIMERS 6 #define SIM_N_TIMERS 3 //328p has 3, Mega has 6
// dummy register variables // dummy register variables
@ -60,12 +60,14 @@ typedef struct io_sim {
uint8_t pcmsk[3]; uint8_t pcmsk[3];
uint8_t ucsr0[3]; uint8_t ucsr0[3];
uint8_t udr[3]; uint8_t udr[3];
uint8_t gpior[3];
uint8_t mcusr;
uint8_t wdtcsr;
union hilo16 ubrr0; union hilo16 ubrr0;
uint16_t prescaler; //continuously running uint16_t prescaler; //continuously running
uint8_t sreg; uint8_t sreg;
} io_sim_t; } io_sim_t;
volatile extern io_sim_t io; volatile extern io_sim_t io;
@ -94,6 +96,8 @@ volatile extern io_sim_t io;
#define DDRG io.ddr[SIM_G] #define DDRG io.ddr[SIM_G]
#define DDRH io.ddr[SIM_H] #define DDRH io.ddr[SIM_H]
#define DDRJ io.ddr[SIM_J] #define DDRJ io.ddr[SIM_J]
#define DDRK io.ddr[SIM_K]
#define DDRL io.ddr[SIM_L]
#define PINA io.pin[SIM_A] #define PINA io.pin[SIM_A]
#define PINB io.pin[SIM_B] #define PINB io.pin[SIM_B]
@ -121,6 +125,7 @@ volatile extern io_sim_t io;
#define SIM_OCB 2 #define SIM_OCB 2
#define SIM_OCC 3 #define SIM_OCC 3
#define SIM_ICI 5 #define SIM_ICI 5
#define SIM_ROLL 7 //stealing reserved TIFR bit
#define OCIE0A SIM_OCA #define OCIE0A SIM_OCA
#define OCIE0B SIM_OCB #define OCIE0B SIM_OCB
@ -148,8 +153,8 @@ volatile extern io_sim_t io;
#define TCNT1 io.tcnt[1] #define TCNT1 io.tcnt[1]
#define TCNT2 io.tcnt[2] #define TCNT2 io.tcnt[2]
#define TCCR0B io.tccra[0] #define TCCR0A io.tccra[0]
#define TCCR0A io.tccrb[0] #define TCCR0B io.tccrb[0]
#define TCCR1A io.tccra[1] #define TCCR1A io.tccra[1]
#define TCCR1B io.tccrb[1] #define TCCR1B io.tccrb[1]
#define TCCR2A io.tccra[2] #define TCCR2A io.tccra[2]
@ -179,6 +184,7 @@ volatile extern io_sim_t io;
#define PCICR io.pcicr #define PCICR io.pcicr
#define PCIE0 0 #define PCIE0 0
#define PCIE1 1 #define PCIE1 1
#define PCIE2 2
//serial channel //serial channel
#define UCSR0A io.ucsr0[SIM_A] #define UCSR0A io.ucsr0[SIM_A]
@ -196,6 +202,23 @@ volatile extern io_sim_t io;
#define PCMSK1 io.pcmsk[1] #define PCMSK1 io.pcmsk[1]
#define PCMSK2 io.pcmsk[2] #define PCMSK2 io.pcmsk[2]
//GPIO
#define GPIOR0 io.gpior[0]
#define GPIOR1 io.gpior[1]
#define GPIOR2 io.gpior[2]
//MCU Status
#define MCUSR io.mcusr
#define PORF 0
#define EXTRF 1
#define BORF 2
#define WDRF 3
#define JTRF 4
//Interrupt Status
#define SREG io.sreg
#endif #endif

View File

@ -1 +1,11 @@
#define WDTCSR wdt
#define WDP0 0
#define WDP1 1
#define WDP2 2
#define WDE 3
#define WDCE 4
#define WDP3 5
#define WDIE 6
#define WDIF 7
uint16_t wdt; uint16_t wdt;

View File

@ -4,7 +4,7 @@
Part of Grbl Simulator Part of Grbl Simulator
Copyright (c) 2012 Jens Geisler Copyright (c) 2012-2014 Jens Geisler, Adam Shelly
Grbl is free software: you can redistribute it and/or modify Grbl is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -32,7 +32,7 @@
#include "eeprom.h" #include "eeprom.h"
int block_position[]= {0,0,0}; //step count after most recently planned block int block_position[N_AXIS]= {0}; //step count after most recently planned block
uint32_t block_number= 0; uint32_t block_number= 0;
sim_vars_t sim={0}; sim_vars_t sim={0};
@ -50,6 +50,11 @@ void init_simulator(float time_multiplier) {
#ifdef STEP_PULSE_DELAY #ifdef STEP_PULSE_DELAY
compa_vect[0] = interrupt_TIMER0_COMPA_vect; compa_vect[0] = interrupt_TIMER0_COMPA_vect;
#endif #endif
#ifdef ENABLE_SOFTWARE_DEBOUNCE
wdt_vect = interrupt_WDT_vect;
#endif
pc_vect = interrupt_LIMIT_INT_vect;
sim.next_print_time = args.step_time; sim.next_print_time = args.step_time;
sim.speedup = time_multiplier; sim.speedup = time_multiplier;