Compare commits

...

3 commits

Author SHA1 Message Date
Stephan I. Böttcher
e979101398 spi_slave: fixes 2025-10-22 11:45:38 +02:00
Stephan I. Böttcher
58b56f20bf leia: c isrs, for initial tests 2025-10-22 11:45:16 +02:00
Stephan I. Böttcher
e890a58340 .gitignore docs 2025-10-22 11:44:23 +02:00
3 changed files with 48 additions and 61 deletions

1
.gitignore vendored
View file

@ -6,3 +6,4 @@
*.o *.o
revision.h* revision.h*
*~ *~
docs

View file

@ -6,7 +6,7 @@
// PCINT2: disable interrupts when SSEL toggles. Allows the SPI to work undisturbed. // PCINT2: disable interrupts when SSEL toggles. Allows the SPI to work undisturbed.
// TIMER1: Motor step period, 23µs resolution, 1.5s range // TIMER1: Motor step period, 23µs resolution, 1.5s range
// OCR1A: interrupt: assert STEP // OCR1A: interrupt: assert STEP
// OCR2B: interrupt: deassert STEP, RESET // OCR1B: interrupt: deassert STEP, RESET
// ADC: Three NTCs ADC8,9,10, Iprim ADC3, internals. // ADC: Three NTCs ADC8,9,10, Iprim ADC3, internals.
// Interrupt stores conversionresults and advances channels. // Interrupt stores conversionresults and advances channels.
// DAC: Motor current reference. // DAC: Motor current reference.
@ -99,12 +99,12 @@ const struct conf runcon = {
.period = STEP_NS(100000000), .period = STEP_NS(100000000),
.slen = STEP_NS(25000), .slen = STEP_NS(25000),
.lmask = LIMIT1 | LIMIT2 | FAULT1 | FAULT2, .lmask = LIMIT1 | LIMIT2 | FAULT1 | FAULT2,
.lval = LIMIT1 | LIMIT2 | FAULT1 | FAULT2, .lval = FAULT1 | FAULT2,
.enable = SLEEP | RESET, .enable = SLEEP | RESET,
.reset = RESET, .reset = RESET,
.adc_ch = {3, 8, 9, 10, 11+0x80, 12+0x80, 17, 18,}, .adc_ch = {0, 3, 8, 9, 10, 11+0x80, 12+0x80, 17, 18,},
.adc_incr = 8, // two conversions per channel .adc_incr = 8, // two conversions per channel
.adc_period = TICK_NS(1000), .adc_period = TICK_NS(1000000),
.dac_step = 0x20, .dac_step = 0x20,
}; };
@ -149,7 +149,7 @@ char stepper_status()
return TIMSK1; return TIMSK1;
} }
#if 0 #if 1
ISR(TIMER1_COMPA_vect) ISR(TIMER1_COMPA_vect)
{ {
if (!conf.n_steps || (LIMIT_PORT & conf.lmask) != conf.lval) { if (!conf.n_steps || (LIMIT_PORT & conf.lmask) != conf.lval) {
@ -209,7 +209,7 @@ ISR(TIMER1_COMPA_vect, ISR_NAKED)
} }
#endif #endif
#if 0 #if 1
ISR(TIMER1_COMPB_vect) ISR(TIMER1_COMPB_vect)
{ {
STEP_PORT = 0; STEP_PORT = 0;
@ -229,7 +229,7 @@ ISR(TIMER1_COMPB_vect, ISR_NAKED)
"out %[IFR], r24" "\n\t" "out %[IFR], r24" "\n\t"
"sts %[MSK], r24" "\n\t" "sts %[MSK], r24" "\n\t"
"pop r24" "\n\t" "pop r24" "\n\t"
"reti" "\n\t" "reti" "\n\t"
: :
:[MSK] "n" (_SFR_MEM_ADDR(TIMSK1)), :[MSK] "n" (_SFR_MEM_ADDR(TIMSK1)),
[IFR] "n" (_SFR_IO_ADDR(TIFR1)), [IFR] "n" (_SFR_IO_ADDR(TIFR1)),
@ -241,7 +241,7 @@ ISR(TIMER1_COMPB_vect, ISR_NAKED)
} }
#endif #endif
#if 0 #if 1
ISR(TIMER0_COMPB_vect) ISR(TIMER0_COMPB_vect)
{ {
uint16_t d = conf.dac; uint16_t d = conf.dac;
@ -382,7 +382,7 @@ void adc_stop()
uint16_t adc[16]; uint16_t adc[16];
#if 0 #if 1
ISR(ADC_vect) ISR(ADC_vect)
{ {
uint16_t a = ADCL | ADMUX & 0x1f | (ADMUX>>(REFS1-5)) & 0x20; uint16_t a = ADCL | ADMUX & 0x1f | (ADMUX>>(REFS1-5)) & 0x20;
@ -490,7 +490,7 @@ static void conf_init()
uint8_t eewr_n; // number of bytes to write uint8_t eewr_n; // number of bytes to write
uint16_t eewr_a; // EEPROM conf base address uint16_t eewr_a; // EEPROM conf base address
#if 0 #if 1
ISR(EE_READY_vect) ISR(EE_READY_vect)
{ {
uint8_t n = eewr_n; uint8_t n = eewr_n;

View file

@ -3,6 +3,12 @@
#include <avr/interrupt.h> #include <avr/interrupt.h>
#define SPSR_IF (1<<SPIF) #define SPSR_IF (1<<SPIF)
#ifndef PIN_SSEL
// ATmega32M1
# define PIN_SSEL (PIND & 8)
# define PCIF_SSEL 4
#endif
static inline void spi_slave_init() static inline void spi_slave_init()
{ {
SPCR = (1<<SPE)|(0<<CPOL)|(0<<CPHA); SPCR = (1<<SPE)|(0<<CPOL)|(0<<CPHA);
@ -27,30 +33,14 @@ static inline char spi_slave_Rx_n(unsigned char d[], unsigned char n)
b = SPDR; b = SPDR;
} while (b&0x80); } while (b&0x80);
*d++ = b; *d++ = b;
unsigned char s = 0;
while (--n) { while (--n) {
while (!(SPSR & SPSR_IF));
SPDR = 0xff;
*d++ = SPDR;
}
return 0;
}
static inline char spi_slave_Rx_cli(unsigned char d[], unsigned char n)
{
SPSR;
SPDR;
register unsigned char b;
do {
while (!(SPSR & SPSR_IF)) while (!(SPSR & SPSR_IF))
if (!(PIND & 8)) if (PIN_SSEL) {
cli(); if (s)
SPDR = 0xff; return n;
b = SPDR; s = n;
} while (b&0x80); }
cli();
*d++ = b;
while (--n) {
while (!(SPSR & SPSR_IF));
SPDR = 0xff; SPDR = 0xff;
*d++ = SPDR; *d++ = SPDR;
} }
@ -70,8 +60,14 @@ static inline char spi_slave_Rx_wdt(unsigned char d[], unsigned char n)
b = SPDR; b = SPDR;
} while (b&0x80); } while (b&0x80);
*d++ = b; *d++ = b;
unsigned char s=0;
while (--n) { while (--n) {
while (!(SPSR & SPSR_IF)); while (!(SPSR & SPSR_IF))
if (PIN_SSEL) {
if (s)
return n;
s = n;
}
SPDR = 0xff; SPDR = 0xff;
*d++ = SPDR; *d++ = SPDR;
} }
@ -79,24 +75,30 @@ static inline char spi_slave_Rx_wdt(unsigned char d[], unsigned char n)
} }
#define spi_slave_Tx spi_slave_Tx_n #define spi_slave_Tx spi_slave_Tx_n
static inline void spi_slave_Tx_n(const unsigned char d[], unsigned char n) static inline
unsigned char spi_slave_Tx_n(const unsigned char d[], unsigned char n)
{ {
SPSR; SPSR;
SPDR; SPDR;
while (n) { while (n) {
register unsigned char b = *d++; register unsigned char b = *d++;
while (!(SPSR & SPSR_IF)); while (!(SPSR & SPSR_IF))
if (PIN_SSEL)
return n;
SPDR = b; SPDR = b;
n--; n--;
} }
return n;
} }
static inline void int2frame(unsigned int i, unsigned char *f) static inline
void int2frame(unsigned int i, unsigned char *f)
{ {
f[0] = i; f[0] = i;
f[1] = i>>8; f[1] = i>>8;
} }
static inline unsigned int frame2int(const unsigned char *f) static inline
unsigned int frame2int(const unsigned char *f)
{ {
return f[1]<<8 | f[0]; return f[1]<<8 | f[0];
} }
@ -108,8 +110,8 @@ static inline
void spi_busy_init() void spi_busy_init()
{ {
PCMSK2 |= 8; // PIND3 PCINT19 PCMSK2 |= 8; // PIND3 PCINT19
while (!(PIND & 8)); while (!PIN_SSEL);
PCIFR = 4; PCIFR |= PCIF_SSEL;
} }
static inline static inline
@ -132,12 +134,8 @@ void clear_spi_busy(const char *busy_msg)
#ifdef SPI_Rx_SEI #ifdef SPI_Rx_SEI
#ifndef PIN_SSEL
// ATmega32M1 // ATmega32M1
# define PIN_SSEL (PIND & 8)
# define PCIF_SSEL 4
// TODO: avoid output in a header file? // TODO: avoid output in a header file?
ISR(PCINT2_vect, ISR_NAKED) ISR(PCINT2_vect, ISR_NAKED)
@ -153,7 +151,6 @@ void spi_slave_init_sei()
PCMSK2 |= 8; PCMSK2 |= 8;
PCICR |= PCIF_SSEL; PCICR |= PCIF_SSEL;
} }
#endif
#undef spi_slave_Rx #undef spi_slave_Rx
#define spi_slave_Rx spi_slave_Rx_sei #define spi_slave_Rx spi_slave_Rx_sei
@ -162,13 +159,11 @@ char spi_slave_Rx_sei(unsigned char d[], unsigned char n)
{ {
if (!PIN_SSEL) if (!PIN_SSEL)
return 1; return 1;
if (PCIFR & PCIF_SSEL) PCIFR |= PCIF_SSEL;
return 1;
PCIFR = PCIF_SSEL;
sei(); sei();
spi_slave_Rx_n(d, n); n = spi_slave_Rx_n(d, n);
cli(); cli();
return 0; return n;
} }
#undef spi_slave_Tx #undef spi_slave_Tx
@ -176,20 +171,11 @@ char spi_slave_Rx_sei(unsigned char d[], unsigned char n)
static inline static inline
char spi_slave_Tx_sei(const unsigned char d[], unsigned char n) char spi_slave_Tx_sei(const unsigned char d[], unsigned char n)
{ {
SPSR; n = spi_slave_Tx_n(d, n);
SPDR;
while (n) {
register unsigned char b = *d++;
while (!(SPSR & SPSR_IF))
if (!PIN_SSEL)
return 1;
SPDR = b;
n--;
}
while (!PIN_SSEL); while (!PIN_SSEL);
PCIFR = PCIF_SSEL; PCIFR |= PCIF_SSEL;
sei(); sei();
return 0; return n;
} }
#endif #endif