Compare commits
4 commits
8d99d529f5
...
0579532711
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0579532711 | ||
|
|
d3a29cc6c9 | ||
|
|
e06a147c6e | ||
|
|
fc2affa04e |
2 changed files with 85 additions and 31 deletions
107
leia/leia.c
107
leia/leia.c
|
|
@ -137,7 +137,7 @@ const struct conf runcon = {
|
|||
.adc_incr = 16, // one conversions per channel
|
||||
.adc_period = TICK_NS(1000000),
|
||||
.dac_step = 0x20,
|
||||
.pad = "\xff\xff\xff\xff\xff\xff\xff"
|
||||
.pad = "\xff\xff\xff\xff\xff\xff\xff",
|
||||
};
|
||||
|
||||
void stepper_init()
|
||||
|
|
@ -158,14 +158,19 @@ void stepper_init()
|
|||
DDRC = DIR | MS1 | MS2 | MS3;
|
||||
}
|
||||
|
||||
static inline
|
||||
void stepper_run()
|
||||
{
|
||||
TCNT1H = 0;
|
||||
TCNT1L = 0;
|
||||
TIMSK1 = TIFR1 = (1<<OCIE1B);
|
||||
}
|
||||
|
||||
static inline
|
||||
void stepper_start(uint8_t reset)
|
||||
{
|
||||
RESET_PORT = v.conf.enable & ~reset;
|
||||
DIR_PORT = v.conf.dir;
|
||||
TCNT1H = 0;
|
||||
TCNT1L = 0;
|
||||
TIMSK1 = (1<<OCIE1B);
|
||||
}
|
||||
|
||||
static inline
|
||||
|
|
@ -175,12 +180,12 @@ void stepper_stop()
|
|||
}
|
||||
|
||||
static inline
|
||||
char stepper_status()
|
||||
uint8_t stepper_status()
|
||||
{
|
||||
return TIMSK1;
|
||||
}
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
ISR(TIMER1_COMPA_vect)
|
||||
{
|
||||
if (!v.conf.n_steps || (LIMIT_PORT & v.conf.lmask) != v.conf.lval) {
|
||||
|
|
@ -190,6 +195,7 @@ ISR(TIMER1_COMPA_vect)
|
|||
}
|
||||
v.conf.n_steps--;
|
||||
STEP_PORT = v.conf.step;
|
||||
TIMSK1 = TIFR1 = 1<<OCIE1B;
|
||||
}
|
||||
#else
|
||||
ISR(TIMER1_COMPA_vect, ISR_NAKED)
|
||||
|
|
@ -214,6 +220,9 @@ ISR(TIMER1_COMPA_vect, ISR_NAKED)
|
|||
"sts %[N]+1, r25" "\n\t"
|
||||
"lds r24, %[S]" "\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 r24" "\n\t"
|
||||
"out __SREG__, r24" "\n\t"
|
||||
|
|
@ -234,18 +243,20 @@ ISR(TIMER1_COMPA_vect, ISR_NAKED)
|
|||
[V] "m" (v.conf.lval),
|
||||
[S] "m" (v.conf.step),
|
||||
[MSK] "n" (_SFR_MEM_ADDR(TIMSK1)),
|
||||
[IFR] "n" (_SFR_IO_ADDR(TIFR1)),
|
||||
[IE] "n" (1<<OCIE1B),
|
||||
[P] "n" (_SFR_IO_ADDR(STEP_PORT)),
|
||||
[L] "n" (_SFR_IO_ADDR(LIMIT_PORT))
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
ISR(TIMER1_COMPB_vect)
|
||||
{
|
||||
STEP_PORT = 0;
|
||||
RESET_PORT = v.conf.enable;
|
||||
TIMSK1 = TIFR1 = 1<<OCIE1B | 1<<OCIE1A;
|
||||
TIMSK1 = TIFR1 = 1<<OCIE1A;
|
||||
}
|
||||
#else
|
||||
ISR(TIMER1_COMPB_vect, ISR_NAKED)
|
||||
|
|
@ -267,12 +278,12 @@ ISR(TIMER1_COMPB_vect, ISR_NAKED)
|
|||
[RES] "n" (_SFR_IO_ADDR(RESET_PORT)),
|
||||
[STP] "n" (_SFR_IO_ADDR(STEP_PORT)),
|
||||
[ENA] "m" (v.conf.enable),
|
||||
[IE] "n" (1<<OCIE1B | 1<<OCIE1A)
|
||||
[IE] "n" (1<<OCIE1A)
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
ISR(TIMER0_COMPA_vect)
|
||||
{
|
||||
uint16_t d = v.stat.dac;
|
||||
|
|
@ -376,6 +387,7 @@ void dac_ramp(uint16_t d)
|
|||
d &= s;
|
||||
TIMSK0 = 0;
|
||||
DACON = 1<<DALA | 1<<DAEN | 1<<DAOE;
|
||||
OCR0A = OCR0B = v.conf.adc_period;
|
||||
v.stat.dac = DAC & s;
|
||||
v.conf.dac_ramp = d;
|
||||
if (d != v.stat.dac)
|
||||
|
|
@ -715,7 +727,7 @@ static inline
|
|||
void reg8f(uint8_t *v, unsigned char *r, const unsigned char *c)
|
||||
{
|
||||
r[1] = *v;
|
||||
*v = r[1] & ~c[2] | c[1];
|
||||
*v = r[1] & ~c[2] | c[1] & ~(r[1] & c[2]);
|
||||
}
|
||||
|
||||
static inline
|
||||
|
|
@ -850,16 +862,13 @@ int main()
|
|||
while (1) {
|
||||
unsigned char cmd[3];
|
||||
unsigned char resp[3];
|
||||
if (!stepper_status() && v.conf.step && v.conf.n_steps)
|
||||
stepper_start(0);
|
||||
stepper_run();
|
||||
if (spi_slave_Rx(cmd, 3)) {
|
||||
spi_slave_Tx((const unsigned char*)"\xff\xff\xff" "EEY", 6);
|
||||
continue;
|
||||
}
|
||||
stepper_stop();
|
||||
char up = upcase(cmd[0]);
|
||||
if (up)
|
||||
v.conf.step = 0;
|
||||
resp[0] = cmd[0];
|
||||
uint8_t i;
|
||||
switch (cmd[0] | 0x20) {
|
||||
|
|
@ -878,32 +887,74 @@ int main()
|
|||
if (up)
|
||||
RESET_PORT = v.conf.enable;
|
||||
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;
|
||||
if (0) case '1': v.conf.step = STEP1;
|
||||
if (0) case '2': v.conf.step = STEP2;
|
||||
v.conf.dir = cmd[1] & 0xf;
|
||||
if (cmd[1] & 0x0e)
|
||||
v.conf.dir = cmd[1] & 0x0f;
|
||||
else {
|
||||
v.conf.dir &= 0x0e;
|
||||
v.conf.dir |= cmd[1] & 1;
|
||||
}
|
||||
if (cmd[2])
|
||||
v.conf.n_steps = cmd[2] << ((cmd[1]>>4) & 7);
|
||||
v.conf.n_steps = cmd[2] << (cmd[1]>>4);
|
||||
stepper_start(0);
|
||||
// fall through, return n_steps
|
||||
case 's': reg16(&v.conf.n_steps, resp, cmd); break;
|
||||
case 'r': resp[2] = cmd[2];
|
||||
switch (cmd[2] & 0x3) {
|
||||
case 0: reg8(&v.conf.reset, resp, cmd);
|
||||
case 1: reg8(&v.conf.disable, resp, cmd);
|
||||
case 2: reg8(&v.conf.awake, resp, cmd);
|
||||
case 3: reg8(&v.conf.ledoff, resp, cmd);
|
||||
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;
|
||||
}
|
||||
if (up && cmd[2] & 0x3)
|
||||
v.conf.enable = v.conf.awake | v.conf.ledoff | v.conf.disable;
|
||||
if (cmd[2] & 0x40)
|
||||
switch (cmd[2] & 0x0c) {
|
||||
case 0x04: // set RESET_PORT bits
|
||||
switch (cmd[2] & 0x3) {
|
||||
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 0x08: // clear RESET_PORT bits
|
||||
switch (cmd[2] & 0x3) {
|
||||
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;
|
||||
if (cmd[2] & 0x80)
|
||||
if (cmd[2] & 0x20) // assert RESET
|
||||
RESET_PORT &=~ v.conf.reset;
|
||||
if (cmd[2] & 0x40) // reinitialize
|
||||
stepper_init();
|
||||
if (cmd[2] & 0x10)
|
||||
if (cmd[2] & 0x80) // pulse the reset pin(s)
|
||||
stepper_start(v.conf.reset);
|
||||
break;
|
||||
case 'd': reg16(&v.stat.dac, resp, cmd);
|
||||
dac_ramp(v.stat.dac);
|
||||
if (up)
|
||||
dac_ramp(v.stat.dac);
|
||||
break;
|
||||
case 'p': reg16(&v.conf.dac_step, resp, cmd); break;
|
||||
case 'a':
|
||||
|
|
|
|||
|
|
@ -186,9 +186,12 @@ static inline
|
|||
unsigned char spi_slave_Tx_sei(const unsigned char d[], unsigned char n)
|
||||
{
|
||||
n = spi_slave_Tx_n(d, n);
|
||||
while (!PIN_SSEL);
|
||||
while (!PIN_SSEL)
|
||||
if (SPSR & SPSR_IF) {
|
||||
SPSR;
|
||||
SPDR = 0;
|
||||
}
|
||||
PCIFR |= PCIF_SSEL;
|
||||
sei();
|
||||
return n;
|
||||
}
|
||||
|
||||
|
|
@ -216,7 +219,7 @@ unsigned char spi_slave_Rx_sleep(unsigned char d[], unsigned char n)
|
|||
while (!PIN_SSEL) {
|
||||
if (SPSR & SPSR_IF) {
|
||||
SPSR;
|
||||
SPDR;
|
||||
SPDR = 0;
|
||||
}
|
||||
sei();
|
||||
sleep_cpu();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue