Compare commits

..

No commits in common. "05795327117d4f0123e5b537556f01f173145068" and "8d99d529f5eeba36e87e7b1725878bdc77bb916a" have entirely different histories.

2 changed files with 31 additions and 85 deletions

View file

@ -137,7 +137,7 @@ const struct conf runcon = {
.adc_incr = 16, // one conversions per channel .adc_incr = 16, // one conversions per channel
.adc_period = TICK_NS(1000000), .adc_period = TICK_NS(1000000),
.dac_step = 0x20, .dac_step = 0x20,
.pad = "\xff\xff\xff\xff\xff\xff\xff", .pad = "\xff\xff\xff\xff\xff\xff\xff"
}; };
void stepper_init() void stepper_init()
@ -158,19 +158,14 @@ void stepper_init()
DDRC = DIR | MS1 | MS2 | MS3; DDRC = DIR | MS1 | MS2 | MS3;
} }
static inline
void stepper_run()
{
TCNT1H = 0;
TCNT1L = 0;
TIMSK1 = TIFR1 = (1<<OCIE1B);
}
static inline static inline
void stepper_start(uint8_t reset) void stepper_start(uint8_t reset)
{ {
RESET_PORT = v.conf.enable & ~reset; RESET_PORT = v.conf.enable & ~reset;
DIR_PORT = v.conf.dir; DIR_PORT = v.conf.dir;
TCNT1H = 0;
TCNT1L = 0;
TIMSK1 = (1<<OCIE1B);
} }
static inline static inline
@ -180,12 +175,12 @@ void stepper_stop()
} }
static inline static inline
uint8_t stepper_status() char stepper_status()
{ {
return TIMSK1; return TIMSK1;
} }
#if 0 #if 1
ISR(TIMER1_COMPA_vect) ISR(TIMER1_COMPA_vect)
{ {
if (!v.conf.n_steps || (LIMIT_PORT & v.conf.lmask) != v.conf.lval) { if (!v.conf.n_steps || (LIMIT_PORT & v.conf.lmask) != v.conf.lval) {
@ -195,7 +190,6 @@ ISR(TIMER1_COMPA_vect)
} }
v.conf.n_steps--; v.conf.n_steps--;
STEP_PORT = v.conf.step; STEP_PORT = v.conf.step;
TIMSK1 = TIFR1 = 1<<OCIE1B;
} }
#else #else
ISR(TIMER1_COMPA_vect, ISR_NAKED) ISR(TIMER1_COMPA_vect, ISR_NAKED)
@ -220,9 +214,6 @@ ISR(TIMER1_COMPA_vect, ISR_NAKED)
"sts %[N]+1, r25" "\n\t" "sts %[N]+1, r25" "\n\t"
"lds r24, %[S]" "\n\t" "lds r24, %[S]" "\n\t"
"out %[P], r24" "\n\t" "out %[P], r24" "\n\t"
"ldi r24, %[IE]" "\n\t"
"out %[IFR], r24" "\n\t"
"sts %[MSK], r24" "\n\t"
"pop r25" "\n\t" "pop r25" "\n\t"
"pop r24" "\n\t" "pop r24" "\n\t"
"out __SREG__, r24" "\n\t" "out __SREG__, r24" "\n\t"
@ -243,20 +234,18 @@ ISR(TIMER1_COMPA_vect, ISR_NAKED)
[V] "m" (v.conf.lval), [V] "m" (v.conf.lval),
[S] "m" (v.conf.step), [S] "m" (v.conf.step),
[MSK] "n" (_SFR_MEM_ADDR(TIMSK1)), [MSK] "n" (_SFR_MEM_ADDR(TIMSK1)),
[IFR] "n" (_SFR_IO_ADDR(TIFR1)),
[IE] "n" (1<<OCIE1B),
[P] "n" (_SFR_IO_ADDR(STEP_PORT)), [P] "n" (_SFR_IO_ADDR(STEP_PORT)),
[L] "n" (_SFR_IO_ADDR(LIMIT_PORT)) [L] "n" (_SFR_IO_ADDR(LIMIT_PORT))
); );
} }
#endif #endif
#if 0 #if 1
ISR(TIMER1_COMPB_vect) ISR(TIMER1_COMPB_vect)
{ {
STEP_PORT = 0; STEP_PORT = 0;
RESET_PORT = v.conf.enable; RESET_PORT = v.conf.enable;
TIMSK1 = TIFR1 = 1<<OCIE1A; TIMSK1 = TIFR1 = 1<<OCIE1B | 1<<OCIE1A;
} }
#else #else
ISR(TIMER1_COMPB_vect, ISR_NAKED) ISR(TIMER1_COMPB_vect, ISR_NAKED)
@ -278,12 +267,12 @@ ISR(TIMER1_COMPB_vect, ISR_NAKED)
[RES] "n" (_SFR_IO_ADDR(RESET_PORT)), [RES] "n" (_SFR_IO_ADDR(RESET_PORT)),
[STP] "n" (_SFR_IO_ADDR(STEP_PORT)), [STP] "n" (_SFR_IO_ADDR(STEP_PORT)),
[ENA] "m" (v.conf.enable), [ENA] "m" (v.conf.enable),
[IE] "n" (1<<OCIE1A) [IE] "n" (1<<OCIE1B | 1<<OCIE1A)
); );
} }
#endif #endif
#if 0 #if 1
ISR(TIMER0_COMPA_vect) ISR(TIMER0_COMPA_vect)
{ {
uint16_t d = v.stat.dac; uint16_t d = v.stat.dac;
@ -387,7 +376,6 @@ void dac_ramp(uint16_t d)
d &= s; d &= s;
TIMSK0 = 0; TIMSK0 = 0;
DACON = 1<<DALA | 1<<DAEN | 1<<DAOE; DACON = 1<<DALA | 1<<DAEN | 1<<DAOE;
OCR0A = OCR0B = v.conf.adc_period;
v.stat.dac = DAC & s; v.stat.dac = DAC & s;
v.conf.dac_ramp = d; v.conf.dac_ramp = d;
if (d != v.stat.dac) if (d != v.stat.dac)
@ -727,7 +715,7 @@ static inline
void reg8f(uint8_t *v, unsigned char *r, const unsigned char *c) void reg8f(uint8_t *v, unsigned char *r, const unsigned char *c)
{ {
r[1] = *v; r[1] = *v;
*v = r[1] & ~c[2] | c[1] & ~(r[1] & c[2]); *v = r[1] & ~c[2] | c[1];
} }
static inline static inline
@ -862,13 +850,16 @@ int main()
while (1) { while (1) {
unsigned char cmd[3]; unsigned char cmd[3];
unsigned char resp[3]; unsigned char resp[3];
stepper_run(); if (!stepper_status() && v.conf.step && v.conf.n_steps)
stepper_start(0);
if (spi_slave_Rx(cmd, 3)) { if (spi_slave_Rx(cmd, 3)) {
spi_slave_Tx((const unsigned char*)"\xff\xff\xff" "EEY", 6); spi_slave_Tx((const unsigned char*)"\xff\xff\xff" "EEY", 6);
continue; continue;
} }
stepper_stop(); stepper_stop();
char up = upcase(cmd[0]); char up = upcase(cmd[0]);
if (up)
v.conf.step = 0;
resp[0] = cmd[0]; resp[0] = cmd[0];
uint8_t i; uint8_t i;
switch (cmd[0] | 0x20) { switch (cmd[0] | 0x20) {
@ -887,73 +878,31 @@ int main()
if (up) if (up)
RESET_PORT = v.conf.enable; RESET_PORT = v.conf.enable;
break; break;
case 'i': reg8f(&v.conf.dir, resp, cmd);
if (up) {
DIR_PORT = v.conf.dir;
uint8_t s = 0;
if (v.conf.dir & 0x10) s |= STEP1;
if (v.conf.dir & 0x20) s |= STEP2;
STEP_PORT = s;
}
break;
case '0': v.conf.step = 0; case '0': v.conf.step = 0;
if (0) case '1': v.conf.step = STEP1; if (0) case '1': v.conf.step = STEP1;
if (0) case '2': v.conf.step = STEP2; if (0) case '2': v.conf.step = STEP2;
if (cmd[1] & 0x0e) v.conf.dir = cmd[1] & 0xf;
v.conf.dir = cmd[1] & 0x0f;
else {
v.conf.dir &= 0x0e;
v.conf.dir |= cmd[1] & 1;
}
if (cmd[2]) if (cmd[2])
v.conf.n_steps = cmd[2] << (cmd[1]>>4); v.conf.n_steps = cmd[2] << ((cmd[1]>>4) & 7);
stepper_start(0);
// fall through, return n_steps // fall through, return n_steps
case 's': reg16(&v.conf.n_steps, resp, cmd); break; case 's': reg16(&v.conf.n_steps, resp, cmd); break;
case 'r': resp[2] = cmd[2]; case 'r': resp[2] = cmd[2];
switch (cmd[2] & 0x3) { // define RESET_PORT bits
case 0: reg8(&v.conf.reset, resp, cmd); break;
case 1: reg8(&v.conf.disable, resp, cmd); break;
case 2: reg8(&v.conf.ledoff, resp, cmd); break;
case 3: reg8(&v.conf.awake, resp, cmd); break;
}
switch (cmd[2] & 0x0c) {
case 0x04: // set RESET_PORT bits
switch (cmd[2] & 0x3) { switch (cmd[2] & 0x3) {
case 0: v.conf.enable |= v.conf.reset; break; case 0: reg8(&v.conf.reset, resp, cmd);
case 1: v.conf.enable |= v.conf.disable; break; case 1: reg8(&v.conf.disable, resp, cmd);
case 2: v.conf.enable |= v.conf.ledoff; break; case 2: reg8(&v.conf.awake, resp, cmd);
case 3: v.conf.enable |= v.conf.awake; break; case 3: reg8(&v.conf.ledoff, resp, cmd);
} }
break; if (up && cmd[2] & 0x3)
case 0x08: // clear RESET_PORT bits v.conf.enable = v.conf.awake | v.conf.ledoff | v.conf.disable;
switch (cmd[2] & 0x3) { if (cmd[2] & 0x40)
case 0: v.conf.enable &=~ v.conf.reset; break;
case 1: v.conf.enable &=~ v.conf.disable; break;
case 2: v.conf.enable &=~ v.conf.ledoff; break;
case 3: v.conf.enable &=~ v.conf.awake; break;
}
break;
case 0x0c: // assign enable/disable/ledoff/sleep
v.conf.enable = v.conf.awake | v.conf.reset;
switch (cmd[2] & 0x3) { // no breaks
case 3: v.conf.enable &=~ v.conf.awake;
case 2: v.conf.enable |= v.conf.ledoff;
case 1: v.conf.enable |= v.conf.disable;
}
break;
}
if (cmd[2] & 0x10) // drive PORT
RESET_PORT = v.conf.enable; RESET_PORT = v.conf.enable;
if (cmd[2] & 0x20) // assert RESET if (cmd[2] & 0x80)
RESET_PORT &=~ v.conf.reset;
if (cmd[2] & 0x40) // reinitialize
stepper_init(); stepper_init();
if (cmd[2] & 0x80) // pulse the reset pin(s) if (cmd[2] & 0x10)
stepper_start(v.conf.reset); stepper_start(v.conf.reset);
break; break;
case 'd': reg16(&v.stat.dac, resp, cmd); case 'd': reg16(&v.stat.dac, resp, cmd);
if (up)
dac_ramp(v.stat.dac); dac_ramp(v.stat.dac);
break; break;
case 'p': reg16(&v.conf.dac_step, resp, cmd); break; case 'p': reg16(&v.conf.dac_step, resp, cmd); break;

View file

@ -186,12 +186,9 @@ static inline
unsigned char spi_slave_Tx_sei(const unsigned char d[], unsigned char n) unsigned char spi_slave_Tx_sei(const unsigned char d[], unsigned char n)
{ {
n = spi_slave_Tx_n(d, n); n = spi_slave_Tx_n(d, n);
while (!PIN_SSEL) while (!PIN_SSEL);
if (SPSR & SPSR_IF) {
SPSR;
SPDR = 0;
}
PCIFR |= PCIF_SSEL; PCIFR |= PCIF_SSEL;
sei();
return n; return n;
} }
@ -219,7 +216,7 @@ unsigned char spi_slave_Rx_sleep(unsigned char d[], unsigned char n)
while (!PIN_SSEL) { while (!PIN_SSEL) {
if (SPSR & SPSR_IF) { if (SPSR & SPSR_IF) {
SPSR; SPSR;
SPDR = 0; SPDR;
} }
sei(); sei();
sleep_cpu(); sleep_cpu();